SuggestedUsersViewModel.swift (2680B)
1 // 2 // SuggestedUsersViewModel.swift 3 // damus 4 // 5 // Created by klabo on 7/17/23. 6 // 7 8 import Foundation 9 import Combine 10 11 struct SuggestedUserGroup: Identifiable, Codable { 12 let id = UUID() 13 let title: String 14 let users: [Pubkey] 15 16 enum CodingKeys: String, CodingKey { 17 case title, users 18 } 19 } 20 21 22 class SuggestedUsersViewModel: ObservableObject { 23 24 public let damus_state: DamusState 25 26 @Published var groups: [SuggestedUserGroup] = [] 27 28 private let sub_id = UUID().uuidString 29 30 init(damus_state: DamusState) { 31 self.damus_state = damus_state 32 loadSuggestedUserGroups() 33 let pubkeys = getPubkeys(groups: groups) 34 subscribeToSuggestedProfiles(pubkeys: pubkeys) 35 } 36 37 func suggestedUser(pubkey: Pubkey) -> SuggestedUser? { 38 let profile_txn = damus_state.profiles.lookup(id: pubkey) 39 if let profile = profile_txn?.unsafeUnownedValue, 40 let user = SuggestedUser(name: profile.name, about: profile.about, picture: profile.picture, pubkey: pubkey) { 41 return user 42 } 43 return nil 44 } 45 46 func follow(pubkeys: [Pubkey]) { 47 for pubkey in pubkeys { 48 notify(.follow(.pubkey(pubkey))) 49 } 50 } 51 52 private func loadSuggestedUserGroups() { 53 guard let url = Bundle.main.url(forResource: "suggested_users", withExtension: "json") else { 54 return 55 } 56 57 guard let data = try? Data(contentsOf: url) else { 58 return 59 } 60 61 let decoder = JSONDecoder() 62 do { 63 let groups = try decoder.decode([SuggestedUserGroup].self, from: data) 64 self.groups = groups 65 } catch { 66 print(error.localizedDescription.localizedLowercase) 67 } 68 } 69 70 private func getPubkeys(groups: [SuggestedUserGroup]) -> [Pubkey] { 71 var pubkeys: [Pubkey] = [] 72 for group in groups { 73 pubkeys.append(contentsOf: group.users) 74 } 75 return pubkeys 76 } 77 78 private func subscribeToSuggestedProfiles(pubkeys: [Pubkey]) { 79 let filter = NostrFilter(kinds: [.metadata], authors: pubkeys) 80 damus_state.pool.subscribe(sub_id: sub_id, filters: [filter], handler: handle_event) 81 } 82 83 func handle_event(relay_id: RelayURL, ev: NostrConnectionEvent) { 84 guard case .nostr_event(let nev) = ev else { 85 return 86 } 87 88 switch nev { 89 case .event: 90 break 91 92 case .notice(let msg): 93 print("suggested user profiles notice: \(msg)") 94 95 case .eose: 96 self.objectWillChange.send() 97 98 case .ok: 99 break 100 101 case .auth: 102 break 103 } 104 } 105 }