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 }