DamusState.swift (8259B)
1 // 2 // DamusState.swift 3 // damus 4 // 5 // Created by William Casarin on 2022-04-30. 6 // 7 8 import Foundation 9 import LinkPresentation 10 import EmojiPicker 11 12 class DamusState: HeadlessDamusState { 13 let pool: RelayPool 14 let keypair: Keypair 15 let likes: EventCounter 16 let boosts: EventCounter 17 let quote_reposts: EventCounter 18 let contacts: Contacts 19 let mutelist_manager: MutelistManager 20 let profiles: Profiles 21 let dms: DirectMessagesModel 22 let previews: PreviewCache 23 let zaps: Zaps 24 let lnurls: LNUrls 25 let settings: UserSettingsStore 26 let relay_filters: RelayFilters 27 let relay_model_cache: RelayModelCache 28 let drafts: Drafts 29 let events: EventCache 30 let bookmarks: BookmarksManager 31 let postbox: PostBox 32 let bootstrap_relays: [RelayURL] 33 let replies: ReplyCounter 34 let wallet: WalletModel 35 let nav: NavigationCoordinator 36 let music: MusicController? 37 let video: DamusVideoCoordinator 38 let ndb: Ndb 39 var purple: DamusPurple 40 var push_notification_client: PushNotificationClient 41 let emoji_provider: EmojiProvider 42 43 init(pool: RelayPool, keypair: Keypair, likes: EventCounter, boosts: EventCounter, contacts: Contacts, mutelist_manager: MutelistManager, profiles: Profiles, dms: DirectMessagesModel, previews: PreviewCache, zaps: Zaps, lnurls: LNUrls, settings: UserSettingsStore, relay_filters: RelayFilters, relay_model_cache: RelayModelCache, drafts: Drafts, events: EventCache, bookmarks: BookmarksManager, postbox: PostBox, bootstrap_relays: [RelayURL], replies: ReplyCounter, wallet: WalletModel, nav: NavigationCoordinator, music: MusicController?, video: DamusVideoCoordinator, ndb: Ndb, purple: DamusPurple? = nil, quote_reposts: EventCounter, emoji_provider: EmojiProvider) { 44 self.pool = pool 45 self.keypair = keypair 46 self.likes = likes 47 self.boosts = boosts 48 self.contacts = contacts 49 self.mutelist_manager = mutelist_manager 50 self.profiles = profiles 51 self.dms = dms 52 self.previews = previews 53 self.zaps = zaps 54 self.lnurls = lnurls 55 self.settings = settings 56 self.relay_filters = relay_filters 57 self.relay_model_cache = relay_model_cache 58 self.drafts = drafts 59 self.events = events 60 self.bookmarks = bookmarks 61 self.postbox = postbox 62 self.bootstrap_relays = bootstrap_relays 63 self.replies = replies 64 self.wallet = wallet 65 self.nav = nav 66 self.music = music 67 self.video = video 68 self.ndb = ndb 69 self.purple = purple ?? DamusPurple( 70 settings: settings, 71 keypair: keypair 72 ) 73 self.quote_reposts = quote_reposts 74 self.push_notification_client = PushNotificationClient(keypair: keypair, settings: settings) 75 self.emoji_provider = emoji_provider 76 } 77 78 @MainActor 79 convenience init?(keypair: Keypair) { 80 // nostrdb 81 var mndb = Ndb() 82 if mndb == nil { 83 // try recovery 84 print("DB ISSUE! RECOVERING") 85 mndb = Ndb.safemode() 86 87 // out of space or something?? maybe we need a in-memory fallback 88 if mndb == nil { 89 logout(nil) 90 return nil 91 } 92 } 93 94 let navigationCoordinator: NavigationCoordinator = NavigationCoordinator() 95 let home: HomeModel = HomeModel() 96 let sub_id = UUID().uuidString 97 98 guard let ndb = mndb else { return nil } 99 let pubkey = keypair.pubkey 100 101 let pool = RelayPool(ndb: ndb, keypair: keypair) 102 let model_cache = RelayModelCache() 103 let relay_filters = RelayFilters(our_pubkey: pubkey) 104 let bootstrap_relays = load_bootstrap_relays(pubkey: pubkey) 105 106 let settings = UserSettingsStore.globally_load_for(pubkey: pubkey) 107 108 let new_relay_filters = load_relay_filters(pubkey) == nil 109 for relay in bootstrap_relays { 110 let descriptor = RelayDescriptor(url: relay, info: .rw) 111 add_new_relay(model_cache: model_cache, relay_filters: relay_filters, pool: pool, descriptor: descriptor, new_relay_filters: new_relay_filters, logging_enabled: settings.developer_mode) 112 } 113 114 pool.register_handler(sub_id: sub_id, handler: home.handle_event) 115 116 if let nwc_str = settings.nostr_wallet_connect, 117 let nwc = WalletConnectURL(str: nwc_str) { 118 try? pool.add_relay(.nwc(url: nwc.relay)) 119 } 120 self.init( 121 pool: pool, 122 keypair: keypair, 123 likes: EventCounter(our_pubkey: pubkey), 124 boosts: EventCounter(our_pubkey: pubkey), 125 contacts: Contacts(our_pubkey: pubkey), 126 mutelist_manager: MutelistManager(user_keypair: keypair), 127 profiles: Profiles(ndb: ndb), 128 dms: home.dms, 129 previews: PreviewCache(), 130 zaps: Zaps(our_pubkey: pubkey), 131 lnurls: LNUrls(), 132 settings: settings, 133 relay_filters: relay_filters, 134 relay_model_cache: model_cache, 135 drafts: Drafts(), 136 events: EventCache(ndb: ndb), 137 bookmarks: BookmarksManager(pubkey: pubkey), 138 postbox: PostBox(pool: pool), 139 bootstrap_relays: bootstrap_relays, 140 replies: ReplyCounter(our_pubkey: pubkey), 141 wallet: WalletModel(settings: settings), 142 nav: navigationCoordinator, 143 music: MusicController(onChange: { _ in }), 144 video: DamusVideoCoordinator(), 145 ndb: ndb, 146 quote_reposts: .init(our_pubkey: pubkey), 147 emoji_provider: DefaultEmojiProvider(showAllVariations: true) 148 ) 149 } 150 151 @discardableResult 152 func add_zap(zap: Zapping) -> Bool { 153 // store generic zap mapping 154 self.zaps.add_zap(zap: zap) 155 let stored = self.events.store_zap(zap: zap) 156 157 // thread zaps 158 if let ev = zap.event, !settings.nozaps, zap.is_in_thread { 159 // [nozaps]: thread zaps are only available outside of the app store 160 replies.count_replies(ev, keypair: self.keypair) 161 events.add_replies(ev: ev, keypair: self.keypair) 162 } 163 164 // associate with events as well 165 return stored 166 } 167 168 var pubkey: Pubkey { 169 return keypair.pubkey 170 } 171 172 var is_privkey_user: Bool { 173 keypair.privkey != nil 174 } 175 176 func close() { 177 print("txn: damus close") 178 Task { 179 try await self.push_notification_client.revoke_token() 180 } 181 wallet.disconnect() 182 pool.close() 183 ndb.close() 184 } 185 186 static var empty: DamusState { 187 let empty_pub: Pubkey = .empty 188 let empty_sec: Privkey = .empty 189 let kp = Keypair(pubkey: empty_pub, privkey: nil) 190 191 return DamusState.init( 192 pool: RelayPool(ndb: .empty), 193 keypair: Keypair(pubkey: empty_pub, privkey: empty_sec), 194 likes: EventCounter(our_pubkey: empty_pub), 195 boosts: EventCounter(our_pubkey: empty_pub), 196 contacts: Contacts(our_pubkey: empty_pub), 197 mutelist_manager: MutelistManager(user_keypair: kp), 198 profiles: Profiles(ndb: .empty), 199 dms: DirectMessagesModel(our_pubkey: empty_pub), 200 previews: PreviewCache(), 201 zaps: Zaps(our_pubkey: empty_pub), 202 lnurls: LNUrls(), 203 settings: UserSettingsStore(), 204 relay_filters: RelayFilters(our_pubkey: empty_pub), 205 relay_model_cache: RelayModelCache(), 206 drafts: Drafts(), 207 events: EventCache(ndb: .empty), 208 bookmarks: BookmarksManager(pubkey: empty_pub), 209 postbox: PostBox(pool: RelayPool(ndb: .empty)), 210 bootstrap_relays: [], 211 replies: ReplyCounter(our_pubkey: empty_pub), 212 wallet: WalletModel(settings: UserSettingsStore()), 213 nav: NavigationCoordinator(), 214 music: nil, 215 video: DamusVideoCoordinator(), 216 ndb: .empty, 217 quote_reposts: .init(our_pubkey: empty_pub), 218 emoji_provider: DefaultEmojiProvider(showAllVariations: true) 219 ) 220 } 221 }