damus

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

FollowersModel.swift (2884B)


      1 //
      2 //  FollowersModel.swift
      3 //  damus
      4 //
      5 //  Created by William Casarin on 2022-05-26.
      6 //
      7 
      8 import Foundation
      9 
     10 class FollowersModel: ObservableObject {
     11     let damus_state: DamusState
     12     let target: Pubkey
     13 
     14     @Published var contacts: [Pubkey]? = nil
     15     var has_contact: Set<Pubkey> = Set()
     16 
     17     let sub_id: String = UUID().description
     18     let profiles_id: String = UUID().description
     19     
     20     var count: Int? {
     21         guard let contacts = self.contacts else {
     22             return nil
     23         }
     24         return contacts.count
     25     }
     26     
     27     init(damus_state: DamusState, target: Pubkey) {
     28         self.damus_state = damus_state
     29         self.target = target
     30     }
     31     
     32     func get_filter() -> NostrFilter {
     33         NostrFilter(kinds: [.contacts], pubkeys: [target])
     34     }
     35     
     36     func subscribe() {
     37         let filter = get_filter()
     38         let filters = [filter]
     39         //print_filters(relay_id: "following", filters: [filters])
     40         self.damus_state.pool.subscribe(sub_id: sub_id, filters: filters, handler: handle_event)
     41     }
     42     
     43     func unsubscribe() {
     44         self.damus_state.pool.unsubscribe(sub_id: sub_id)
     45     }
     46     
     47     func handle_contact_event(_ ev: NostrEvent) {
     48         if has_contact.contains(ev.pubkey) {
     49             return
     50         }
     51         process_contact_event(state: damus_state, ev: ev)
     52         contacts?.append(ev.pubkey)
     53         has_contact.insert(ev.pubkey)
     54     }
     55 
     56     func load_profiles<Y>(relay_id: RelayURL, txn: NdbTxn<Y>) {
     57         let authors = find_profiles_to_fetch_from_keys(profiles: damus_state.profiles, pks: contacts ?? [], txn: txn)
     58         if authors.isEmpty {
     59             return
     60         }
     61         
     62         let filter = NostrFilter(kinds: [.metadata],
     63                                  authors: authors)
     64         damus_state.pool.subscribe_to(sub_id: profiles_id, filters: [filter], to: [relay_id], handler: handle_event)
     65     }
     66 
     67     func handle_event(relay_id: RelayURL, ev: NostrConnectionEvent) {
     68         guard case .nostr_event(let nev) = ev else {
     69             return
     70         }
     71         
     72         switch nev {
     73         case .event(let sub_id, let ev):
     74             guard sub_id == self.sub_id || sub_id == self.profiles_id else {
     75                 return
     76             }
     77             
     78             if ev.known_kind == .contacts {
     79                 handle_contact_event(ev)
     80             }
     81         case .notice(let msg):
     82             print("followingmodel notice: \(msg)")
     83             
     84         case .eose(let sub_id):
     85             if sub_id == self.sub_id {
     86                 guard let txn = NdbTxn(ndb: self.damus_state.ndb) else { return }
     87                 load_profiles(relay_id: relay_id, txn: txn)
     88             } else if sub_id == self.profiles_id {
     89                 damus_state.pool.unsubscribe(sub_id: profiles_id, to: [relay_id])
     90             }
     91             
     92         case .ok:
     93             break
     94         case .auth:
     95             break
     96         }
     97     }
     98 }