ConnectWalletView.swift (7312B)
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(NSLocalizedString("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."), 44 dismissButton: .default(Text(NSLocalizedString("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(NSLocalizedString("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 // 100 // Mutiny Wallet NWC is way too advanced to recommend for normal 101 // users until they have a way to do async receive. 102 // 103 104 /* 105 MutinyButton() { 106 openURL(URL(string:"https://app.mutinywallet.com/settings/connections?callbackUri=nostr%2bwalletconnect&name=Damus")!) 107 } 108 */ 109 110 Button(action: { 111 if let pasted_nwc = UIPasteboard.general.string { 112 guard let url = WalletConnectURL(str: pasted_nwc) else { 113 wallet_scan_result = .failed 114 return 115 } 116 117 wallet_scan_result = .success(url) 118 } 119 }) { 120 HStack { 121 Image("clipboard") 122 Text("Paste NWC Address", comment: "Text for button to connect a lightning wallet.") 123 .fontWeight(.semibold) 124 } 125 .frame(minWidth: 300, maxWidth: .infinity, maxHeight: 18, alignment: .center) 126 } 127 .buttonStyle(GradientButtonStyle()) 128 129 Button(action: { 130 nav.push(route: Route.WalletScanner(result: $wallet_scan_result)) 131 }) { 132 HStack { 133 Image("qr-code") 134 Text("Scan NWC Address", comment: "Text for button to connect a lightning wallet.") 135 .fontWeight(.semibold) 136 } 137 .frame(minWidth: 300, maxWidth: .infinity, maxHeight: 18, alignment: .center) 138 } 139 .buttonStyle(GradientButtonStyle()) 140 141 142 if let err = self.error { 143 Text(err) 144 .foregroundColor(.red) 145 } 146 } 147 } 148 149 var TopSection: some View { 150 HStack(spacing: 0) { 151 Button(action: {}, label: { 152 Image("damus-home") 153 .resizable() 154 .frame(width: 30, height: 30) 155 }) 156 .buttonStyle(NeutralButtonStyle(padding: EdgeInsets(top: 15, leading: 15, bottom: 15, trailing: 15), cornerRadius: 9999)) 157 .disabled(true) 158 .padding(.horizontal, 30) 159 160 Image("chevron-double-right") 161 .resizable() 162 .frame(width: 25, height: 25) 163 164 Button(action: {}, label: { 165 Image("wallet") 166 .resizable() 167 .frame(width: 30, height: 30) 168 .foregroundStyle(LINEAR_GRADIENT) 169 }) 170 .buttonStyle(NeutralButtonStyle(padding: EdgeInsets(top: 15, leading: 15, bottom: 15, trailing: 15), cornerRadius: 9999)) 171 .disabled(true) 172 .padding(.horizontal, 30) 173 } 174 } 175 176 var TitleSection: some View { 177 VStack(spacing: 25) { 178 Text("Damus Wallet") 179 .fontWeight(.bold) 180 181 Text("Securely connect your Damus app to your wallet\nusing Nostr Wallet Connect") 182 .font(.caption) 183 .multilineTextAlignment(.center) 184 } 185 } 186 187 var MainContent: some View { 188 Group { 189 TopSection 190 switch model.connect_state { 191 case .new(let nwc): 192 AreYouSure(nwc: nwc) 193 case .existing: 194 Text(verbatim: "Shouldn't happen") 195 case .none: 196 TitleSection 197 ConnectWallet 198 } 199 } 200 } 201 } 202 203 struct ConnectWalletView_Previews: PreviewProvider { 204 static var previews: some View { 205 ConnectWalletView(model: WalletModel(settings: UserSettingsStore()), nav: .init()) 206 } 207 }