From 8cdbc8409363194f197415a5ed65a6e840bcd8ba Mon Sep 17 00:00:00 2001 From: William Casarin Date: Sat, 16 Mar 2024 12:05:49 +0000 Subject: [PATCH] home: add quote repost counter and handler This adds the initial support code for counting and handling quote reposts. Eventually we are going to replace all of the event counts by stats within nostrdb, but we do this in the meantime now. Signed-off-by: William Casarin --- damus/ContentView.swift | 3 ++- damus/Models/ActionBarModel.swift | 12 +++++++++++- damus/Models/DamusState.swift | 7 +++++-- damus/Models/HomeModel.swift | 15 +++++++++++++-- damus/TestData.swift | 4 +++- damusTests/Mocking/MockDamusState.swift | 3 ++- 6 files changed, 36 insertions(+), 8 deletions(-) diff --git a/damus/ContentView.swift b/damus/ContentView.swift index 930f163b..6fe9a1ee 100644 --- a/damus/ContentView.swift +++ b/damus/ContentView.swift @@ -723,7 +723,8 @@ struct ContentView: View { nav: self.navigationCoordinator, music: MusicController(onChange: music_changed), video: VideoController(), - ndb: ndb + ndb: ndb, + quote_reposts: .init(our_pubkey: pubkey) ) home.damus_state = self.damus_state! diff --git a/damus/Models/ActionBarModel.swift b/damus/Models/ActionBarModel.swift index d0109757..90f2c228 100644 --- a/damus/Models/ActionBarModel.swift +++ b/damus/Models/ActionBarModel.swift @@ -16,10 +16,12 @@ enum Zapped { class ActionBarModel: ObservableObject { @Published var our_like: NostrEvent? @Published var our_boost: NostrEvent? + @Published var our_quote_repost: NostrEvent? @Published var our_reply: NostrEvent? @Published var our_zap: Zapping? @Published var likes: Int @Published var boosts: Int + @Published var quote_reposts: Int @Published private(set) var zaps: Int @Published var zap_total: Int64 @Published var replies: Int @@ -28,7 +30,7 @@ class ActionBarModel: ObservableObject { return ActionBarModel(likes: 0, boosts: 0, zaps: 0, zap_total: 0, replies: 0, our_like: nil, our_boost: nil, our_zap: nil, our_reply: nil) } - init(likes: Int = 0, boosts: Int = 0, zaps: Int = 0, zap_total: Int64 = 0, replies: Int = 0, our_like: NostrEvent? = nil, our_boost: NostrEvent? = nil, our_zap: Zapping? = nil, our_reply: NostrEvent? = nil) { + init(likes: Int = 0, boosts: Int = 0, zaps: Int = 0, zap_total: Int64 = 0, replies: Int = 0, our_like: NostrEvent? = nil, our_boost: NostrEvent? = nil, our_zap: Zapping? = nil, our_reply: NostrEvent? = nil, our_quote_repost: NostrEvent? = nil, quote_reposts: Int = 0) { self.likes = likes self.boosts = boosts self.zaps = zaps @@ -38,6 +40,8 @@ class ActionBarModel: ObservableObject { self.our_boost = our_boost self.our_zap = our_zap self.our_reply = our_reply + self.our_quote_repost = our_quote_repost + self.quote_reposts = quote_reposts } func update(damus: DamusState, evid: NoteId) { @@ -45,11 +49,13 @@ class ActionBarModel: ObservableObject { self.boosts = damus.boosts.counts[evid] ?? 0 self.zaps = damus.zaps.event_counts[evid] ?? 0 self.replies = damus.replies.get_replies(evid) + self.quote_reposts = damus.quote_reposts.counts[evid] ?? 0 self.zap_total = damus.zaps.event_totals[evid] ?? 0 self.our_like = damus.likes.our_events[evid] self.our_boost = damus.boosts.our_events[evid] self.our_zap = damus.zaps.our_zaps[evid]?.first self.our_reply = damus.replies.our_reply(evid) + self.our_quote_repost = damus.quote_reposts.our_events[evid] self.objectWillChange.send() } @@ -68,4 +74,8 @@ class ActionBarModel: ObservableObject { var boosted: Bool { return our_boost != nil } + + var quoted: Bool { + return our_quote_repost != nil + } } diff --git a/damus/Models/DamusState.swift b/damus/Models/DamusState.swift index d3cafdde..97a5d843 100644 --- a/damus/Models/DamusState.swift +++ b/damus/Models/DamusState.swift @@ -13,6 +13,7 @@ class DamusState: HeadlessDamusState { let keypair: Keypair let likes: EventCounter let boosts: EventCounter + let quote_reposts: EventCounter let contacts: Contacts let mutelist_manager: MutelistManager let profiles: Profiles @@ -36,7 +37,7 @@ class DamusState: HeadlessDamusState { let ndb: Ndb var purple: DamusPurple - init(pool: RelayPool, keypair: Keypair, likes: EventCounter, boosts: EventCounter, contacts: Contacts, mutelist_manager: MutelistManager, profiles: Profiles, dms: DirectMessagesModel, previews: PreviewCache, zaps: Zaps, lnurls: LNUrls, settings: UserSettingsStore, relay_filters: RelayFilters, relay_model_cache: RelayModelCache, drafts: Drafts, events: EventCache, bookmarks: BookmarksManager, postbox: PostBox, bootstrap_relays: [String], replies: ReplyCounter, wallet: WalletModel, nav: NavigationCoordinator, music: MusicController?, video: VideoController, ndb: Ndb, purple: DamusPurple? = nil) { + init(pool: RelayPool, keypair: Keypair, likes: EventCounter, boosts: EventCounter, contacts: Contacts, mutelist_manager: MutelistManager, profiles: Profiles, dms: DirectMessagesModel, previews: PreviewCache, zaps: Zaps, lnurls: LNUrls, settings: UserSettingsStore, relay_filters: RelayFilters, relay_model_cache: RelayModelCache, drafts: Drafts, events: EventCache, bookmarks: BookmarksManager, postbox: PostBox, bootstrap_relays: [String], replies: ReplyCounter, wallet: WalletModel, nav: NavigationCoordinator, music: MusicController?, video: VideoController, ndb: Ndb, purple: DamusPurple? = nil, quote_reposts: EventCounter) { self.pool = pool self.keypair = keypair self.likes = likes @@ -66,6 +67,7 @@ class DamusState: HeadlessDamusState { settings: settings, keypair: keypair ) + self.quote_reposts = quote_reposts } @discardableResult @@ -129,7 +131,8 @@ class DamusState: HeadlessDamusState { nav: NavigationCoordinator(), music: nil, video: VideoController(), - ndb: .empty + ndb: .empty, + quote_reposts: .init(our_pubkey: empty_pub) ) } } diff --git a/damus/Models/HomeModel.swift b/damus/Models/HomeModel.swift index 4f76c899..ac6909b2 100644 --- a/damus/Models/HomeModel.swift +++ b/damus/Models/HomeModel.swift @@ -347,12 +347,19 @@ class HomeModel { case .already_counted: break case .success(let n): - let boosted = Counted(event: ev, id: e, total: n) - notify(.reposted(boosted)) notify(.update_stats(note_id: e)) } } + func handle_quote_repost_event(_ ev: NostrEvent, target: NoteId) { + switch damus_state.quote_reposts.add_event(ev, target: target) { + case .already_counted: + break + case .success(let n): + notify(.update_stats(note_id: target)) + } + } + func handle_like_event(_ ev: NostrEvent) { guard let e = ev.last_refid() else { // no id ref? invalid like event @@ -672,6 +679,10 @@ class HomeModel { damus_state.replies.count_replies(ev, keypair: self.damus_state.keypair) damus_state.events.insert(ev) + if let quoted_event = ev.referenced_quote_ids.first { + handle_quote_repost_event(ev, target: quoted_event.note_id) + } + if sub_id == home_subid { insert_home_event(ev) } else if sub_id == notifications_subid { diff --git a/damus/TestData.swift b/damus/TestData.swift index 127468a7..1de6ac02 100644 --- a/damus/TestData.swift +++ b/damus/TestData.swift @@ -92,7 +92,9 @@ var test_damus_state: DamusState = ({ nav: .init(), music: .init(onChange: {_ in }), video: .init(), - ndb: ndb) + ndb: ndb, + quote_reposts: .init(our_pubkey: our_pubkey) + ) /* let prof = Profile(name: "damus", display_name: "damus", about: "iOS app!", picture: "https://damus.io/img/logo.png", banner: "", website: "https://damus.io", lud06: nil, lud16: "jb55@sendsats.lol", nip05: "damus.io", damus_donation: nil) diff --git a/damusTests/Mocking/MockDamusState.swift b/damusTests/Mocking/MockDamusState.swift index 4c4faf53..fb02cd62 100644 --- a/damusTests/Mocking/MockDamusState.swift +++ b/damusTests/Mocking/MockDamusState.swift @@ -49,7 +49,8 @@ func generate_test_damus_state( nav: .init(), music: .init(onChange: {_ in }), video: .init(), - ndb: ndb) + ndb: ndb, + quote_reposts: .init(our_pubkey: our_pubkey) ) return damus }