more mention progress

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2022-05-07 13:50:19 -07:00
parent 73652513d9
commit 0eb1372937
21 changed files with 611 additions and 144 deletions

View File

@@ -7,9 +7,19 @@
import Foundation
enum MentionType {
case pubkey
case event
var ref: String {
switch self {
case .pubkey:
return "p"
case .event:
return "e"
}
}
}
struct Mention {
@@ -42,38 +52,15 @@ enum Block {
}
}
struct ParsedMentions {
let blocks: [Block]
}
class Parser {
var pos: Int
var str: String
init(pos: Int, str: String) {
self.pos = pos
self.str = str
}
}
func consume_until(_ p: Parser, match: Character) -> Bool {
var i: Int = 0
let sub = substring(p.str, start: p.pos, end: p.str.count)
for c in sub {
if c == match {
p.pos += i
return true
func render_blocks(blocks: [Block]) -> String {
return blocks.reduce("") { str, block in
switch block {
case .mention(let m):
return str + "#[\(m.index)]"
case .text(let txt):
return str + txt
}
i += 1
}
return false
}
func substring(_ s: String, start: Int, end: Int) -> Substring {
let ind = s.index(s.startIndex, offsetBy: start)
let end = s.index(s.startIndex, offsetBy: end)
return s[ind..<end]
}
func parse_textblock(str: String, from: Int, to: Int) -> Block {
@@ -86,7 +73,7 @@ func parse_mentions(content: String, tags: [[String]]) -> [Block] {
var starting_from: Int = 0
while p.pos < content.count {
if (!consume_until(p, match: "#")) {
if (!consume_until(p, match: { $0 == "#" })) {
blocks.append(parse_textblock(str: p.str, from: starting_from, to: p.str.count))
return blocks
}
@@ -142,3 +129,17 @@ func parse_mention(_ p: Parser, tags: [[String]]) -> Mention? {
return Mention(index: digit, type: kind, ref: ref)
}
func post_to_event(post: NostrPost, privkey: String, pubkey: String) -> NostrEvent {
let new_ev = NostrEvent(content: post.content, pubkey: pubkey)
for id in post.references {
var tag = [id.key, id.ref_id]
if let relay_id = id.relay_id {
tag.append(relay_id)
}
new_ev.tags.append(tag)
}
new_ev.calculate_id()
new_ev.sign(privkey: privkey)
return new_ev
}

69
damus/Models/Post.swift Normal file
View File

@@ -0,0 +1,69 @@
//
// Post.swift
// damus
//
// Created by William Casarin on 2022-05-07.
//
import Foundation
struct NostrPost {
let content: String
let references: [ReferencedId]
}
// TODO: parse nostr:{e,p}:pubkey uris as well
func parse_post_mention_type(_ p: Parser) -> MentionType? {
if parse_char(p, "@") {
return .pubkey
}
if parse_char(p, "&") {
return .event
}
return nil
}
func parse_post_reference(_ p: Parser) -> ReferencedId? {
let start = p.pos
guard let typ = parse_post_mention_type(p) else {
return parse_nostr_ref_uri(p)
}
guard let id = parse_hexstr(p, len: 64) else {
p.pos = start
return nil
}
return ReferencedId(ref_id: id, relay_id: nil, key: typ.ref)
}
/// Return a list of tags
func parse_post_blocks(content: String) -> [PostBlock] {
let p = Parser(pos: 0, str: content)
var blocks: [PostBlock] = []
var starting_from: Int = 0
if content.count == 0 {
return []
}
while p.pos < content.count {
let pre_mention = p.pos
if let reference = parse_post_reference(p) {
blocks.append(parse_post_textblock(str: p.str, from: starting_from, to: pre_mention))
blocks.append(.ref(reference))
starting_from = p.pos
} else {
p.pos += 1
}
}
blocks.append(parse_post_textblock(str: content, from: starting_from, to: content.count))
return blocks
}

View File

@@ -0,0 +1,31 @@
//
// PostBlock.swift
// damus
//
// Created by William Casarin on 2022-05-07.
//
import Foundation
enum PostBlock {
case text(String)
case ref(ReferencedId)
var is_text: Bool {
if case .text = self {
return true
}
return false
}
var is_ref: Bool {
if case .ref = self {
return true
}
return false
}
}
func parse_post_textblock(str: String, from: Int, to: Int) -> PostBlock {
return .text(String(substring(str, start: from, end: to)))
}

View File

@@ -0,0 +1,14 @@
//
// ProfileUpdate.swift
// damus
//
// Created by William Casarin on 2022-05-06.
//
import Foundation
struct ProfileUpdate {
let pubkey: String
let profile: Profile
}