URLSheet.swift (4394B)
1 /* 2 * This file is part of GNU Taler, ©2022-26 Taler Systems S.A. 3 * See LICENSE.md 4 */ 5 /** 6 * @author Marc Stibane 7 */ 8 import SwiftUI 9 import taler_swift 10 import SymLog 11 12 struct URLSheet: View { 13 private let symLog = SymLogV(0) 14 let stack: CallStack 15 let selectedBalance: Balance? 16 @Binding var urlToOpen: URL? 17 let sheetURL: URL? 18 19 @EnvironmentObject private var controller: Controller 20 @EnvironmentObject private var model: WalletModel 21 @AppStorage("shouldShowWarning") var shouldShowWarning: Bool = true 22 @AppStorage("oimEuro") var oimEuro: Bool = false 23 24 @State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING) 25 @State private var summary = EMPTYSTRING 26 @State private var urlCommand: UrlCommand? 27 @State private var passedURL: URL? 28 29 init(_ stack: CallStack, selectedBalance: Balance? = nil, 30 urlToOpen: Binding<URL?>? = nil, 31 sheetURL: URL? = nil) { 32 self.stack = stack 33 self.selectedBalance = selectedBalance 34 self._urlToOpen = urlToOpen ?? Binding.constant(nil) 35 self.sheetURL = sheetURL 36 } 37 38 // don't need @MainActor here 39 private func passUrlOnce() { 40 if let url = urlToOpen { 41 symLog.log("❗️ passed urlToOpen: \(url.absoluteString)") 42 (urlCommand, passedURL) = controller.urlCommand(url, stack: stack.push()) 43 urlToOpen = nil // make sure we don't get this a second time 44 } else if let sheetURL { 45 (urlCommand, passedURL) = controller.urlCommand(sheetURL, stack: stack.push()) 46 } 47 } 48 49 var body: some View { 50 #if PRINT_CHANGES 51 let _ = Self._printChanges() 52 let _ = symLog.vlog(urlToOpen?.absoluteString) // just to get the # to compare it with .onAppear & onDisappear 53 #endif 54 if let urlCommand, let passedURL { 55 switch urlCommand { 56 case .addExchange: // TODO: just check the ToS 57 ExchangeListView(stack: stack.push(), url: $passedURL) 58 case .withdraw: 59 WithdrawUriScan(stack: stack.push(), url: passedURL) 60 case .withdrawExchange: 61 WithdrawExchangeScan(stack: stack.push(), 62 selectedBalance: selectedBalance, 63 url: passedURL) 64 case .pay: 65 PaymentScan(stack: stack.push(), url: passedURL, 66 template: false, amountToTransfer: $amountToTransfer, summary: $summary, 67 amountIsEditable: false, summaryIsEditable: false) 68 case .payPull: 69 P2pPayURIView(stack: stack.push(), url: passedURL) 70 case .payPush: 71 P2pReceiveURIView(stack: stack.push(), url: passedURL, oimEuro: oimEuro) 72 case .payTemplate: 73 PayTemplateScan(stack: stack.push(), url: passedURL) 74 case .refund: 75 RefundURIView(stack: stack.push(), url: passedURL) 76 #if GNU_TALER || TALER_NIGHTLY 77 case .devExperiment: 78 DevExperimentView(stack: stack.push(), url: passedURL) 79 #endif 80 default: // TODO: Error view 81 let unknown = String(localized: "Unknown command: \(passedURL.trimmedString)") 82 VStack { 83 let _ = symLog.log("Unknown command❗️ \(passedURL.absoluteString)") 84 Text(controller.messageForSheet ?? unknown) 85 .talerFont(.title) 86 } 87 .navigationTitle(unknown) 88 } 89 } else { 90 let message = String(localized: "Scanning...", comment: "loading") 91 LoadingView(stack: stack.push(), scopeInfo: nil, message: message) 92 .task(id: urlToOpen) { 93 passUrlOnce() 94 } 95 } 96 } 97 } 98 // MARK: - 99 //struct PaySheet_Previews: PreviewProvider { 100 // static var previews: some View { 101 // needs BackendManager 102 // URLSheet(urlToOpen: URL(string: "ftp://this.URL.is.invalid")!) 103 // } 104 //}