EventsModel.swift (3094B)
1 // 2 // EventsModel.swift 3 // damus 4 // 5 // Created by William Casarin on 2022-05-24. 6 // 7 8 import Foundation 9 10 class EventsModel: ObservableObject { 11 let state: DamusState 12 let target: NoteId 13 let kind: QueryKind 14 let sub_id = UUID().uuidString 15 let profiles_id = UUID().uuidString 16 var events: EventHolder 17 @Published var loading: Bool 18 19 enum QueryKind { 20 case kind(NostrKind) 21 case quotes 22 } 23 24 init(state: DamusState, target: NoteId, kind: NostrKind) { 25 self.state = state 26 self.target = target 27 self.kind = .kind(kind) 28 self.loading = true 29 self.events = EventHolder(on_queue: { ev in 30 preload_events(state: state, events: [ev]) 31 }) 32 } 33 34 init(state: DamusState, target: NoteId, query: EventsModel.QueryKind) { 35 self.state = state 36 self.target = target 37 self.kind = query 38 self.loading = true 39 self.events = EventHolder(on_queue: { ev in 40 preload_events(state: state, events: [ev]) 41 }) 42 } 43 44 public static func quotes(state: DamusState, target: NoteId) -> EventsModel { 45 EventsModel(state: state, target: target, query: .quotes) 46 } 47 48 public static func reposts(state: DamusState, target: NoteId) -> EventsModel { 49 EventsModel(state: state, target: target, kind: .boost) 50 } 51 52 public static func likes(state: DamusState, target: NoteId) -> EventsModel { 53 EventsModel(state: state, target: target, kind: .like) 54 } 55 56 private func get_filter() -> NostrFilter { 57 var filter: NostrFilter 58 switch kind { 59 case .kind(let k): 60 filter = NostrFilter(kinds: [k]) 61 filter.referenced_ids = [target] 62 case .quotes: 63 filter = NostrFilter(kinds: [.text]) 64 filter.quotes = [target] 65 } 66 filter.limit = 500 67 return filter 68 } 69 70 func subscribe() { 71 state.pool.subscribe(sub_id: sub_id, 72 filters: [get_filter()], 73 handler: handle_nostr_event) 74 } 75 76 func unsubscribe() { 77 state.pool.unsubscribe(sub_id: sub_id) 78 } 79 80 private func handle_event(relay_id: RelayURL, ev: NostrEvent) { 81 if events.insert(ev) { 82 objectWillChange.send() 83 } 84 } 85 86 func handle_nostr_event(relay_id: RelayURL, ev: NostrConnectionEvent) { 87 guard case .nostr_event(let nev) = ev, nev.subid == self.sub_id 88 else { 89 return 90 } 91 92 switch nev { 93 case .event(_, let ev): 94 handle_event(relay_id: relay_id, ev: ev) 95 case .notice: 96 break 97 case .ok: 98 break 99 case .auth: 100 break 101 case .eose: 102 self.loading = false 103 guard let txn = NdbTxn(ndb: self.state.ndb) else { 104 return 105 } 106 load_profiles(context: "events_model", profiles_subid: profiles_id, relay_id: relay_id, load: .from_events(events.all_events), damus_state: state, txn: txn) 107 } 108 } 109 }