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 }