damus

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

WalletView.swift (10579B)


      1 //
      2 //  WalletView.swift
      3 //  damus
      4 //
      5 //  Created by William Casarin on 2023-05-05.
      6 //
      7 
      8 import SwiftUI
      9 
     10 struct WalletView: View {
     11     let damus_state: DamusState
     12     @ObservedObject var model: WalletModel
     13     @ObservedObject var settings: UserSettingsStore
     14     
     15     init(damus_state: DamusState, model: WalletModel? = nil) {
     16         self.damus_state = damus_state
     17         self._model = ObservedObject(wrappedValue: model ?? damus_state.wallet)
     18         self._settings = ObservedObject(wrappedValue: damus_state.settings)
     19     }
     20     
     21     func MainWalletView(nwc: WalletConnectURL) -> some View {
     22         ScrollView {
     23             VStack(spacing: 35) {
     24                 if !damus_state.settings.nozaps {
     25                     SupportDamus
     26                         .padding(.vertical, 20)
     27                 }
     28                 
     29                 VStack(spacing: 5) {
     30                     VStack(spacing: 10) {
     31                         Text("Wallet Relay", comment: "Label text indicating that below it is the information about the wallet relay.")
     32                             .fontWeight(.semibold)
     33                             .padding(.top)
     34                         
     35                         Divider()
     36                         
     37                         RelayView(state: damus_state, relay: nwc.relay, showActionButtons: .constant(false), recommended: false)
     38                     }
     39                     .frame(maxWidth: .infinity, minHeight: 125, alignment: .top)
     40                     .padding(.horizontal, 10)
     41                     .background(DamusColors.neutral1)
     42                     .cornerRadius(10)
     43                     .overlay(
     44                         RoundedRectangle(cornerRadius: 10)
     45                             .stroke(DamusColors.neutral3, lineWidth: 1)
     46                     )
     47                     
     48                     if let lud16 = nwc.lud16 {
     49                         VStack(spacing: 10) {
     50                             Text("Wallet Address", comment: "Label text indicating that below it is the wallet address.")
     51                                 .fontWeight(.semibold)
     52                             
     53                             Divider()
     54                             
     55                             Text(lud16)
     56                         }
     57                         .frame(maxWidth: .infinity, minHeight: 75, alignment: .center)
     58                         .padding(.horizontal, 10)
     59                         .background(DamusColors.neutral1)
     60                         .cornerRadius(10)
     61                         .overlay(
     62                             RoundedRectangle(cornerRadius: 10)
     63                                 .stroke(DamusColors.neutral3, lineWidth: 1)
     64                         )
     65                     }
     66                 }
     67                 
     68                 Button(action: {
     69                     self.model.disconnect()
     70                 }) {
     71                     HStack {
     72                         Text("Disconnect Wallet", comment: "Text for button to disconnect from Nostr Wallet Connect lightning wallet.")
     73                     }
     74                     .frame(minWidth: 300, maxWidth: .infinity, maxHeight: 18, alignment: .center)
     75                 }
     76                 .buttonStyle(GradientButtonStyle())
     77                 .padding(.bottom, 50) // Bottom padding while Scrolling
     78                 
     79             }
     80             .navigationTitle(NSLocalizedString("Wallet", comment: "Navigation title for Wallet view"))
     81             .navigationBarTitleDisplayMode(.inline)
     82             .padding()
     83         }
     84     }
     85     
     86     func donation_binding() -> Binding<Double> {
     87         return Binding(get: {
     88             return Double(model.settings.donation_percent)
     89         }, set: { v in
     90             model.settings.donation_percent = Int(v)
     91         })
     92     }
     93     
     94     static let min_donation: Double = 0.0
     95     static let max_donation: Double = 100.0
     96     
     97     var percent: Double {
     98         Double(model.settings.donation_percent) / 100.0
     99     }
    100     
    101     var tip_msats: String {
    102         let msats = Int64(percent * Double(model.settings.default_zap_amount * 1000))
    103         let s = format_msats_abbrev(msats)
    104         // TODO: fix formatting and remove this hack
    105         let parts = s.split(separator: ".")
    106         if parts.count == 1 {
    107             return s
    108         }
    109         if let end = parts[safe: 1] {
    110             if end.allSatisfy({ c in c.isNumber }) {
    111                 return String(parts[0])
    112             } else {
    113                 return s
    114             }
    115         }
    116         return s
    117     }
    118     
    119     var SupportDamus: some View {
    120         ZStack(alignment: .topLeading) {
    121             RoundedRectangle(cornerRadius: 20)
    122                 .fill(DamusGradient.gradient.opacity(0.5))
    123             
    124             VStack(alignment: .leading, spacing: 20) {
    125                 HStack {
    126                     Image("logo-nobg")
    127                         .resizable()
    128                         .frame(width: 50, height: 50)
    129                     Text("Support Damus", comment: "Text calling for the user to support Damus through zaps")
    130                         .font(.title.bold())
    131                         .foregroundColor(.white)
    132                 }
    133                 
    134                 Text("Help build the future of decentralized communication on the web.", comment: "Text indicating the goal of developing Damus which the user can help with.")
    135                     .fixedSize(horizontal: false, vertical: true)
    136                     .foregroundColor(.white)
    137                 
    138                 Text("An additional percentage of each zap will be sent to support Damus development", comment: "Text indicating that they can contribute zaps to support Damus development.")
    139                     .fixedSize(horizontal: false, vertical: true)
    140                     .foregroundColor(.white)
    141                 
    142                 let binding = donation_binding()
    143                 
    144                 HStack {
    145                     Slider(value: binding,
    146                            in: WalletView.min_donation...WalletView.max_donation,
    147                            label: {  })
    148                     Text("\(Int(binding.wrappedValue))%", comment: "Percentage of additional zap that should be sent to support Damus development.")
    149                         .font(.title.bold())
    150                         .foregroundColor(.white)
    151                         .frame(width: 80)
    152                 }
    153                 
    154                 HStack{
    155                     Spacer()
    156                     
    157                     VStack {
    158                         HStack {
    159                             Text("\(Image("zap.fill")) \(format_msats_abbrev(Int64(model.settings.default_zap_amount) * 1000))")
    160                                 .font(.title)
    161                                 .foregroundColor(percent == 0 ? .gray : .yellow)
    162                                 .frame(width: 120)
    163                         }
    164                         
    165                         Text("Zap", comment: "Text underneath the number of sats indicating that it's the amount used for zaps.")
    166                             .foregroundColor(.white)
    167                     }
    168                     Spacer()
    169                     
    170                     Text(verbatim: "+")
    171                         .font(.title)
    172                         .foregroundColor(.white)
    173                     Spacer()
    174                     
    175                     VStack {
    176                         HStack {
    177                             Text("\(Image("zap.fill")) \(tip_msats)")
    178                                 .font(.title)
    179                                 .foregroundColor(percent == 0 ? .gray : Color.yellow)
    180                                 .frame(width: 120)
    181                         }
    182                         
    183                         Text(verbatim: percent == 0 ? "🩶" : "💜")
    184                             .foregroundColor(.white)
    185                     }
    186                     Spacer()
    187                 }
    188                 
    189                 EventProfile(damus_state: damus_state, pubkey: damus_state.pubkey, size: .small)
    190             }
    191             .padding(25)
    192         }
    193         .frame(height: 370)
    194     }
    195     
    196     var body: some View {
    197         switch model.connect_state {
    198         case .new:
    199             ConnectWalletView(model: model, nav: damus_state.nav)
    200         case .none:
    201             ConnectWalletView(model: model, nav: damus_state.nav)
    202         case .existing(let nwc):
    203             MainWalletView(nwc: nwc)
    204                 .onAppear() {
    205                     model.initial_percent = settings.donation_percent
    206                 }
    207                 .onChange(of: settings.donation_percent) { p in
    208                     let profile_txn = damus_state.profiles.lookup(id: damus_state.pubkey)
    209                     guard let profile = profile_txn?.unsafeUnownedValue else {
    210                         return
    211                     }
    212                     
    213                     let prof = Profile(name: profile.name, display_name: profile.display_name, about: profile.about, picture: profile.picture, banner: profile.banner, website: profile.website, lud06: profile.lud06, lud16: profile.lud16, nip05: profile.nip05, damus_donation: p, reactions: profile.reactions)
    214 
    215                     notify(.profile_updated(.manual(pubkey: self.damus_state.pubkey, profile: prof)))
    216                 }
    217                 .onDisappear {
    218                     let profile_txn = damus_state.profiles.lookup(id: damus_state.pubkey)
    219                     
    220                     guard let keypair = damus_state.keypair.to_full(),
    221                           let profile = profile_txn?.unsafeUnownedValue,
    222                           model.initial_percent != profile.damus_donation
    223                     else {
    224                         return
    225                     }
    226                     
    227                     let prof = Profile(name: profile.name, display_name: profile.display_name, about: profile.about, picture: profile.picture, banner: profile.banner, website: profile.website, lud06: profile.lud06, lud16: profile.lud16, nip05: profile.nip05, damus_donation: settings.donation_percent, reactions: profile.reactions)
    228 
    229                     guard let meta = make_metadata_event(keypair: keypair, metadata: prof) else {
    230                         return
    231                     }
    232                     damus_state.postbox.send(meta)
    233                 }
    234         }
    235     }
    236 }
    237 
    238 let test_wallet_connect_url = WalletConnectURL(pubkey: test_pubkey, relay: .init("wss://relay.damus.io")!, keypair: test_damus_state.keypair.to_full()!, lud16: "jb55@sendsats.com")
    239 
    240 struct WalletView_Previews: PreviewProvider {
    241     static let tds = test_damus_state
    242     static var previews: some View {
    243         WalletView(damus_state: tds, model: WalletModel(state: .existing(test_wallet_connect_url), settings: tds.settings))
    244     }
    245 }