URLSheet.swift (4730B)
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 urlToOpen != nil { 41 passedURL = urlToOpen 42 symLog.log("❗️ passed urlToOpen: \(String(describing: urlToOpen?.absoluteString))") 43 urlCommand = controller.urlCommand(urlToOpen!, stack: stack.push()) 44 urlToOpen = nil // make sure we don't get this a second time 45 } else if let sheetURL { 46 passedURL = sheetURL 47 urlCommand = controller.urlCommand(sheetURL, stack: stack.push()) 48 } 49 } 50 51 var body: some View { 52 #if PRINT_CHANGES 53 let _ = Self._printChanges() 54 let _ = symLog.vlog(urlToOpen?.absoluteString) // just to get the # to compare it with .onAppear & onDisappear 55 #endif 56 VStack { 57 if controller.networkUnavailable { 58 ErrorBanner(.networkUnavailable) // red bar on top 59 } else if controller.slowConnection { 60 ErrorBanner(.warning5sec) // yellow bar on top 61 } 62 if let urlCommand, let passedURL { 63 switch urlCommand { 64 case .addExchange: // TODO: just check the ToS 65 ExchangeListView(stack: stack.push(), url: $passedURL) 66 case .withdraw: 67 WithdrawURIView(stack: stack.push(), url: passedURL) 68 case .withdrawExchange: 69 WithdrawExchangeV(stack: stack.push(), 70 selectedBalance: selectedBalance, 71 url: passedURL) 72 case .pay: 73 PaymentView(stack: stack.push(), url: passedURL, 74 template: false, amountToTransfer: $amountToTransfer, summary: $summary, 75 amountIsEditable: false, summaryIsEditable: false) 76 case .payPull: 77 P2pPayURIView(stack: stack.push(), url: passedURL) 78 case .payPush: 79 P2pReceiveURIView(stack: stack.push(), url: passedURL, oimEuro: oimEuro) 80 case .payTemplate: 81 PayTemplateV(stack: stack.push(), url: passedURL) 82 case .refund: 83 RefundURIView(stack: stack.push(), url: passedURL) 84 #if GNU_TALER || TALER_NIGHTLY 85 case .devExperiment: 86 DevExperimentView(stack: stack.push(), url: passedURL) 87 #endif 88 default: // TODO: Error view 89 let unknown = String(localized: "Unknown command: \(passedURL.absoluteString)") 90 VStack { 91 let _ = symLog.log("Unknown command❗️ \(passedURL.absoluteString)") 92 Text(controller.messageForSheet ?? unknown) 93 .talerFont(.title) 94 } 95 .navigationTitle(unknown) 96 } 97 } else { 98 let message = String(localized: "Scanning...", comment: "loading") 99 LoadingView(stack: stack.push(), scopeInfo: nil, message: message) 100 .task(id: urlToOpen) { 101 passUrlOnce() 102 } 103 } 104 } 105 } 106 } 107 // MARK: - 108 //struct PaySheet_Previews: PreviewProvider { 109 // static var previews: some View { 110 // needs BackendManager 111 // URLSheet(urlToOpen: URL(string: "ftp://this.URL.is.invalid")!) 112 // } 113 //}