From 3f1f257df2dbdfada879c1d6e7b4ef7f57da8ca6 Mon Sep 17 00:00:00 2001 From: William Casarin Date: Sat, 16 Mar 2024 12:19:29 +0000 Subject: [PATCH] model: upgrade EventsModel to support quote reposts queries We also switch to using an eventholder because that is a bit nicer when it comes to rendering quotes in timelines. Signed-off-by: William Casarin --- damus/Models/EventsModel.swift | 59 ++++++++++++++++++++++++--------- damus/Views/ReactionsView.swift | 2 +- damus/Views/RepostsView.swift | 2 +- 3 files changed, 45 insertions(+), 18 deletions(-) diff --git a/damus/Models/EventsModel.swift b/damus/Models/EventsModel.swift index ae51fcac..74ee5b12 100644 --- a/damus/Models/EventsModel.swift +++ b/damus/Models/EventsModel.swift @@ -11,16 +11,39 @@ import Foundation class EventsModel: ObservableObject { let state: DamusState let target: NoteId - let kind: NostrKind + let kind: QueryKind let sub_id = UUID().uuidString let profiles_id = UUID().uuidString - - @Published var events: [NostrEvent] = [] - + var events: EventHolder + @Published var loading: Bool + + enum QueryKind { + case kind(NostrKind) + case quotes + } + init(state: DamusState, target: NoteId, kind: NostrKind) { self.state = state self.target = target - self.kind = kind + self.kind = .kind(kind) + self.loading = true + self.events = EventHolder(on_queue: { ev in + preload_events(state: state, events: [ev]) + }) + } + + init(state: DamusState, target: NoteId, query: EventsModel.QueryKind) { + self.state = state + self.target = target + self.kind = query + self.loading = true + self.events = EventHolder(on_queue: { ev in + preload_events(state: state, events: [ev]) + }) + } + + public static func quotes(state: DamusState, target: NoteId) -> EventsModel { + EventsModel(state: state, target: target, query: .quotes) } public static func reposts(state: DamusState, target: NoteId) -> EventsModel { @@ -32,8 +55,15 @@ class EventsModel: ObservableObject { } private func get_filter() -> NostrFilter { - var filter = NostrFilter(kinds: [kind]) - filter.referenced_ids = [target] + var filter: NostrFilter + switch kind { + case .kind(let k): + filter = NostrFilter(kinds: [k]) + filter.referenced_ids = [target] + case .quotes: + filter = NostrFilter(kinds: [.text]) + filter.quotes = [target] + } filter.limit = 500 return filter } @@ -49,21 +79,17 @@ class EventsModel: ObservableObject { } private func handle_event(relay_id: String, ev: NostrEvent) { - guard ev.kind == kind.rawValue, - ev.referenced_ids.last == target else { - return - } - - if insert_uniq_sorted_event(events: &self.events, new_ev: ev, cmp: { a, b in a.created_at < b.created_at } ) { + if events.insert(ev) { objectWillChange.send() } } func handle_nostr_event(relay_id: String, ev: NostrConnectionEvent) { - guard case .nostr_event(let nev) = ev else { + guard case .nostr_event(let nev) = ev, nev.subid == self.sub_id + else { return } - + switch nev { case .event(_, let ev): handle_event(relay_id: relay_id, ev: ev) @@ -74,10 +100,11 @@ class EventsModel: ObservableObject { case .auth: break case .eose: + self.loading = false guard let txn = NdbTxn(ndb: self.state.ndb) else { return } - load_profiles(context: "events_model", profiles_subid: profiles_id, relay_id: relay_id, load: .from_events(events), damus_state: state, txn: txn) + load_profiles(context: "events_model", profiles_subid: profiles_id, relay_id: relay_id, load: .from_events(events.all_events), damus_state: state, txn: txn) } } } diff --git a/damus/Views/ReactionsView.swift b/damus/Views/ReactionsView.swift index 5be84455..2c6e6503 100644 --- a/damus/Views/ReactionsView.swift +++ b/damus/Views/ReactionsView.swift @@ -16,7 +16,7 @@ struct ReactionsView: View { var body: some View { ScrollView { LazyVStack { - ForEach(model.events, id: \.id) { ev in + ForEach(model.events.events, id: \.id) { ev in ReactionView(damus_state: damus_state, reaction: ev) } } diff --git a/damus/Views/RepostsView.swift b/damus/Views/RepostsView.swift index 2aadecb2..368f11ce 100644 --- a/damus/Views/RepostsView.swift +++ b/damus/Views/RepostsView.swift @@ -14,7 +14,7 @@ struct RepostsView: View { var body: some View { ScrollView { LazyVStack { - ForEach(model.events, id: \.id) { ev in + ForEach(model.events.events, id: \.id) { ev in RepostView(damus_state: damus_state, repost: ev) } }