damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

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 }