damus

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

ConnectWalletView.swift (7209B)


      1 //
      2 //  ConnectWalletView.swift
      3 //  damus
      4 //
      5 //  Created by William Casarin on 2023-05-05.
      6 //
      7 
      8 import SwiftUI
      9 
     10 struct ConnectWalletView: View {
     11     @Environment(\.openURL) private var openURL
     12     @ObservedObject var model: WalletModel
     13     
     14     @State var scanning: Bool = false
     15     @State private var showAlert = false
     16     @State var error: String? = nil
     17     @State var wallet_scan_result: WalletScanResult = .scanning
     18     var nav: NavigationCoordinator
     19     
     20     var body: some View {
     21         MainContent
     22             .navigationTitle(NSLocalizedString("Wallet", comment: "Navigation title for attaching Nostr Wallet Connect lightning wallet."))
     23             .navigationBarTitleDisplayMode(.inline)
     24             .padding()
     25             .onChange(of: wallet_scan_result) { res in
     26                 scanning = false
     27                 
     28                 switch res {
     29                 case .success(let url):
     30                     error = nil
     31                     self.model.new(url)
     32                     
     33                 case .failed:
     34                     showAlert.toggle()
     35                 
     36                 case .scanning:
     37                     error = nil
     38                 }
     39             }
     40             .alert(isPresented: $showAlert) {
     41                 Alert(
     42                     title: Text("Invalid Nostr wallet connection string", comment: "Error message when an invalid Nostr wallet connection string is provided."),
     43                     message: Text("Make sure the wallet you are connecting to supports NWC.", comment: "Hint message when an invalid Nostr wallet connection string is provided."),
     44                     dismissButton: .default(Text("OK", comment: "Button label indicating user wants to proceed.")) {
     45                         wallet_scan_result = .scanning
     46                     }
     47                 )
     48             }
     49     }
     50     
     51     func AreYouSure(nwc: WalletConnectURL) -> some View {
     52         VStack(spacing: 25) {
     53 
     54             Text("Are you sure you want to connect this wallet?", comment: "Prompt to ask user if they want to attach their Nostr Wallet Connect lightning wallet.")
     55                 .fontWeight(.bold)
     56                 .multilineTextAlignment(.center)
     57 
     58             Text(nwc.relay.absoluteString)
     59                 .font(.body)
     60                 .foregroundColor(.gray)
     61 
     62             if let lud16 = nwc.lud16 {
     63                 Text(lud16)
     64                     .font(.body)
     65                     .foregroundColor(.gray)
     66             }
     67             
     68             Button(action: {
     69                 model.connect(nwc)
     70             }) {
     71                 HStack {
     72                     Text("Connect", comment: "Text for button to conect to Nostr Wallet Connect lightning wallet.")
     73                         .fontWeight(.semibold)
     74                 }
     75                 .frame(minWidth: 300, maxWidth: .infinity, maxHeight: 18, alignment: .center)
     76             }
     77             .buttonStyle(GradientButtonStyle())
     78             
     79             Button(action: {
     80                 model.cancel()
     81             }) {
     82                 HStack {
     83                     Text("Cancel", comment: "Text for button to cancel out of connecting Nostr Wallet Connect lightning wallet.")
     84                         .padding()
     85                 }
     86                 .frame(minWidth: 300, maxWidth: .infinity, alignment: .center)
     87             }
     88             .buttonStyle(NeutralButtonStyle())
     89         }
     90     }
     91     
     92     var ConnectWallet: some View {
     93         VStack(spacing: 25) {
     94             
     95             AlbyButton() {
     96                 openURL(URL(string:"https://nwc.getalby.com/apps/new?c=Damus")!)
     97             }
     98             
     99             CoinosButton() {
    100                 openURL(URL(string:"https://coinos.io/settings/nostr")!)
    101             }
    102             
    103             Button(action: {
    104                 if let pasted_nwc = UIPasteboard.general.string {
    105                     guard let url = WalletConnectURL(str: pasted_nwc) else {
    106                         wallet_scan_result = .failed
    107                         return
    108                     }
    109                     
    110                     wallet_scan_result = .success(url)
    111                 }
    112             }) {
    113                 HStack {
    114                     Image("clipboard")
    115                     Text("Paste NWC Address", comment: "Text for button to connect a lightning wallet.")
    116                         .fontWeight(.semibold)
    117                 }
    118                 .frame(minWidth: 300, maxWidth: .infinity, maxHeight: 18, alignment: .center)
    119             }
    120             .buttonStyle(GradientButtonStyle())
    121             
    122             Button(action: {
    123                 nav.push(route: Route.WalletScanner(result: $wallet_scan_result))
    124             }) {
    125                 HStack {
    126                     Image("qr-code")
    127                     Text("Scan NWC Address", comment: "Text for button to connect a lightning wallet.")
    128                         .fontWeight(.semibold)
    129                 }
    130                 .frame(minWidth: 300, maxWidth: .infinity, maxHeight: 18, alignment: .center)
    131             }
    132             .buttonStyle(GradientButtonStyle())
    133 
    134             
    135             if let err = self.error {
    136                 Text(err)
    137                     .foregroundColor(.red)
    138             }
    139         }
    140     }
    141     
    142     var TopSection: some View {
    143         HStack(spacing: 0) {
    144             Button(action: {}, label: {
    145                 Image("damus-home")
    146                     .resizable()
    147                     .frame(width: 30, height: 30)
    148             })
    149             .buttonStyle(NeutralButtonStyle(padding: EdgeInsets(top: 15, leading: 15, bottom: 15, trailing: 15), cornerRadius: 9999))
    150             .disabled(true)
    151             .padding(.horizontal, 30)
    152             
    153             Image("chevron-double-right")
    154                 .resizable()
    155                 .frame(width: 25, height: 25)
    156             
    157             Button(action: {}, label: {
    158                 Image("wallet")
    159                     .resizable()
    160                     .frame(width: 30, height: 30)
    161                     .foregroundStyle(LINEAR_GRADIENT)
    162             })
    163             .buttonStyle(NeutralButtonStyle(padding: EdgeInsets(top: 15, leading: 15, bottom: 15, trailing: 15), cornerRadius: 9999))
    164             .disabled(true)
    165             .padding(.horizontal, 30)
    166         }
    167     }
    168     
    169     var TitleSection: some View {
    170         VStack(spacing: 25) {
    171             Text("Damus Wallet", comment: "Title text for Damus Wallet view.")
    172                 .fontWeight(.bold)
    173             
    174             Text("Securely connect your Damus app to your wallet using Nostr Wallet Connect", comment: "Text to prompt user to connect their wallet using 'Nostr Wallet Connect'.")
    175                 .font(.caption)
    176                 .multilineTextAlignment(.center)
    177         }
    178     }
    179     
    180     var MainContent: some View {
    181         Group {
    182             TopSection
    183             switch model.connect_state {
    184             case .new(let nwc):
    185                 AreYouSure(nwc: nwc)
    186             case .existing:
    187                 Text(verbatim: "Shouldn't happen")
    188             case .none:
    189                 TitleSection
    190                 ConnectWallet
    191             }
    192         }
    193     }
    194 }
    195 
    196 struct ConnectWalletView_Previews: PreviewProvider {
    197     static var previews: some View {
    198         ConnectWalletView(model: WalletModel(settings: UserSettingsStore()), nav: .init())
    199     }
    200 }