likes, mention parsing, lots of stuff

Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
William Casarin
2022-05-04 16:26:10 -07:00
parent 403fa74f8d
commit f42bc2e91e
25 changed files with 608 additions and 118 deletions

View File

@@ -9,14 +9,21 @@ import Foundation
class ActionBarModel: ObservableObject {
@Published var our_like_event: NostrEvent? = nil
@Published var our_boost_event: NostrEvent? = nil
@Published var our_like: NostrEvent?
@Published var our_boost: NostrEvent?
@Published var likes: Int
init(likes: Int, our_like: NostrEvent?, our_boost: NostrEvent?) {
self.likes = likes
self.our_like = our_like
self.our_boost = our_boost
}
var liked: Bool {
return our_like_event != nil
return our_like != nil
}
var boosted: Bool {
return our_boost_event != nil
return our_boost != nil
}
}

View File

@@ -0,0 +1,16 @@
//
// DamusState.swift
// damus
//
// Created by William Casarin on 2022-04-30.
//
import Foundation
struct DamusState {
let pool: RelayPool
let pubkey: String
let likes: EventCounter
let boosts: EventCounter
}

View File

@@ -0,0 +1,53 @@
//
// LikeCounter.swift
// damus
//
// Created by William Casarin on 2022-04-30.
//
import Foundation
class EventCounter {
var counts: [String: Int] = [:]
var user_events: [String: Set<String>] = [:]
var our_events: [String: NostrEvent] = [:]
var our_pubkey: String
enum LikeResult {
case user_already_liked
case success(Int)
}
init (our_pubkey: String) {
self.our_pubkey = our_pubkey
}
func add_event(_ ev: NostrEvent) -> LikeResult {
let pubkey = ev.pubkey
if self.user_events[pubkey] == nil {
self.user_events[pubkey] = Set()
}
if user_events[pubkey]!.contains(ev.id) {
// don't double count
return .user_already_liked
}
user_events[pubkey]!.insert(ev.id)
if ev.pubkey == self.our_pubkey {
our_events[ev.id] = ev
}
if counts[ev.id] == nil {
counts[ev.id] = 1
return .success(1)
}
counts[ev.id]! += 1
return .success(counts[ev.id]!)
}
}

19
damus/Models/Liked.swift Normal file
View File

@@ -0,0 +1,19 @@
//
// Liked.swift
// damus
//
// Created by William Casarin on 2022-04-30.
//
import Foundation
struct Liked {
let like: NostrEvent
let id: String
let total: Int
}
struct LikeRefs {
let thread_id: String?
let like_id: String
}

132
damus/Models/Mentions.swift Normal file
View File

@@ -0,0 +1,132 @@
//
// Mentions.swift
// damus
//
// Created by William Casarin on 2022-05-04.
//
import Foundation
enum MentionType {
case pubkey
case event
}
struct Mention {
let index: Int
let kind: MentionType
}
enum Block {
case text(String)
case mention(Mention)
var is_text: Bool {
if case .text = self {
return true
}
return false
}
var is_mention: Bool {
if case .mention = self {
return true
}
return false
}
}
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
}
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 {
return .text(String(substring(str, start: from, end: to)))
}
func parse_mentions(content: String, tags: [[String]]) -> [Block] {
let p = Parser(pos: 0, str: content)
var blocks: [Block] = []
var starting_from: Int = 0
while p.pos < content.count {
if (!consume_until(p, match: "#")) {
blocks.append(parse_textblock(str: p.str, from: starting_from, to: p.str.count))
return blocks
}
let pre_mention = p.pos
if let mention = parse_mention(p, tags: tags) {
blocks.append(parse_textblock(str: p.str, from: starting_from, to: pre_mention))
blocks.append(.mention(mention))
starting_from = p.pos
}
}
return blocks
}
func parse_mention(_ p: Parser, tags: [[String]]) -> Mention? {
let start = p.pos
if !parse_str(p, "#[") {
return nil
}
guard let digit = parse_digit(p) else {
p.pos = start
return nil
}
if !parse_char(p, "]") {
return nil
}
var kind: MentionType = .pubkey
if digit > tags.count - 1 {
return nil
}
if tags[digit].count == 0 {
return nil
}
switch tags[digit][0] {
case "e": kind = .event
case "p": kind = .pubkey
default: return nil
}
return Mention(index: digit, kind: kind)
}

View File

@@ -0,0 +1,15 @@
//
// ParsedRefs.swift
// damus
//
// Created by William Casarin on 2022-04-30.
//
import Foundation
struct ReplyRefs {
let thread_id: String
let direct_reply: String
}

View File

@@ -10,34 +10,35 @@ import Foundation
class ProfileModel: ObservableObject {
@Published var events: [NostrEvent] = []
let pubkey: String
let pool: RelayPool
let damus: DamusState
var seen_event: Set<String> = Set()
var sub_id = UUID().description
init(pubkey: String, pool: RelayPool) {
init(pubkey: String, damus: DamusState) {
self.pubkey = pubkey
self.pool = pool
self.damus = damus
}
func unsubscribe() {
print("unsubscribing from profile \(pubkey) with sub_id \(sub_id)")
pool.unsubscribe(sub_id: sub_id)
damus.pool.unsubscribe(sub_id: sub_id)
}
func subscribe() {
let kinds: [Int] = [
NostrKind.text.rawValue,
NostrKind.delete.rawValue,
NostrKind.contacts.rawValue,
NostrKind.metadata.rawValue,
NostrKind.boost.rawValue
]
var filter = NostrFilter.filter_kinds(kinds)
filter.authors = [pubkey]
var filter = NostrFilter.filter_authors([pubkey])
filter.kinds = kinds
print("subscribing to profile \(pubkey) with sub_id \(sub_id)")
pool.subscribe(sub_id: sub_id, filters: [filter], handler: handle_event)
damus.pool.subscribe(sub_id: sub_id, filters: [filter], handler: handle_event)
}
func add_event(_ ev: NostrEvent) {

View File

@@ -62,14 +62,16 @@ class ThreadModel: ObservableObject {
}
func subscribe() {
let kinds: [Int] = [1, 5, 6]
let kinds: [Int] = [1, 5, 6, 7]
var ref_events = NostrFilter.filter_kinds(kinds)
var events_filter = NostrFilter.filter_kinds(kinds)
//var likes_filter = NostrFilter.filter_kinds(7])
// TODO: add referenced relays
ref_events.referenced_ids = event.referenced_ids.map { $0.ref_id }
ref_events.referenced_ids!.append(event.id)
//likes_filter.ids = ref_events.referenced_ids!
events_filter.ids = ref_events.referenced_ids!
print("subscribing to thread \(event.id) with sub_id \(sub_id)")
@@ -110,7 +112,9 @@ class ThreadModel: ObservableObject {
switch res {
case .event(let sub_id, let ev):
if sub_id == self.sub_id {
add_event(ev)
if ev.known_kind == .text {
add_event(ev)
}
}
case .notice(let note):