damus

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

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 }