WalletEmptyView.swift (6545B)
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 SymLog 10 import taler_swift 11 12 /// This view shows hints if a wallet is empty 13 /// It is the very first thing the user sees after installing the app 14 15 struct WalletEmptyView: View { 16 private let symLog = SymLogV(0) 17 let stack: CallStack 18 19 @Environment(\.colorScheme) private var colorScheme 20 @Environment(\.colorSchemeContrast) private var colorSchemeContrast 21 @EnvironmentObject private var controller: Controller 22 @EnvironmentObject private var model: WalletModel 23 @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic 24 #if DEBUG 25 @AppStorage("developerMode") var developerMode: Bool = true 26 #else 27 @AppStorage("developerMode") var developerMode: Bool = false 28 #endif 29 @State private var withDrawStarted = false 30 @State private var defaultExchanges: [DefaultExchange] = [] 31 @State private var urlToOpen: URL? = nil 32 @State private var selectedCurrency: Int = 0 33 34 @MainActor 35 private func viewDidLoad() async { 36 if let exchanges = try? await model.getDefaultExchanges() { 37 withAnimation { defaultExchanges = exchanges } 38 } 39 } 40 41 var body: some View { 42 let list = List { 43 Section { 44 Text("Welcome to Taler Wallet!") 45 .talerFont(.headline) 46 Text("To make your first payment, withdraw digital cash.") 47 .talerFont(.body) 48 #if false 49 let qrButton = Image(systemName: QRBUTTON) // "qrcode.viewfinder" 50 let settings = Image(systemName: SETTINGS) // "gear" 51 Text("Use «\(qrButton) Scan QR code» in the Actions menu to start a withdrawal if your bank already supports Taler payments.", comment: "« » 'qrcode.viewfinder'") 52 .talerFont(.body) 53 Text("You can also add a payment service manually in the \(settings) Settings tab.", comment: "« » 'gear'") 54 .talerFont(.body) 55 #endif 56 57 if !defaultExchanges.isEmpty { 58 #if !TALER_WALLET 59 if developerMode { 60 if defaultExchanges.count > 1 { 61 CurrencyPicker(stack: stack.push(), value: $selectedCurrency, 62 exchanges: defaultExchanges) { index in 63 selectedCurrency = index 64 } 65 } 66 } 67 #endif 68 let defaultExchange = defaultExchanges[selectedCurrency] 69 let currency = defaultExchange.currency 70 let currencySpec = defaultExchange.currencySpec 71 let name = currencySpec.name 72 let title = String(localized: "LinkTitle_Withdraw", defaultValue: "Withdraw \(currency)") 73 Button(title) { 74 if let talerUri = URL(string: defaultExchange.talerUri) { 75 controller.talerURI = talerUri 76 } 77 } 78 .buttonStyle(TalerButtonStyle(type: .prominent, narrow: false, disabled: withDrawStarted, aligned: .center)) 79 .padding(.bottom) 80 } 81 #if !TALER_WALLET 82 Text("If you don't have a Swiss bank account, you can simply try out the demo…") 83 .talerFont(.body) 84 #endif 85 86 #if DEBUG 87 // if developerMode { 88 // Text("Either deposit or send your money to a friend before you delete the app, or it will be lost.") 89 // .talerFont(.body) 90 // } 91 #endif 92 } header: { 93 let firstHeader = EMPTYSTRING 94 Text(firstHeader) 95 .talerFont(.badge) 96 // .foregroundColor(.primary) 97 /// YIKES! when not specifying this color, the Text in the BarGraphHeader vanishes!!! 98 .foregroundColor(WalletColors().secondary(colorScheme, colorSchemeContrast)) 99 // .listRowInsets(EdgeInsets()) // << here !! 100 } 101 .listRowSeparator(.hidden) 102 // .listSectionSpacing(.compact) iOS 17 103 Section { 104 // Text("Demo") 105 // .talerFont(.headline) 106 // Text("Get digital cash to experience how easy you can pay online, and send money to friends & family.") 107 Text("Get demo cash to experience how to pay with digital cash.") 108 // Text("Get digital cash to experience how to pay with the money of the future.") 109 .talerFont(.body) 110 .listRowSeparator(.hidden) 111 let title = String(localized: "LinkTitle_Test_Money", defaultValue: "Get demo cash") 112 Button(title) { 113 withDrawStarted = true // don't run twice 114 Task { // runs on MainActor 115 let amount = Amount(currency: DEMOCURRENCY, cent: 2500) 116 symLog.log("Withdraw KUDOS") 117 try? await model.loadTestKudos(0, amount: amount) 118 } 119 } 120 .buttonStyle(TalerButtonStyle(type: .prominent, narrow: false, disabled: withDrawStarted, aligned: .center)) 121 .disabled(withDrawStarted) 122 // } header: { 123 // let secondHeader = String(localized: "Demo", comment: "section header") 124 // Text(secondHeader) 125 // .talerFont(.title3) 126 // .foregroundColor(WalletColors().secondary(colorScheme, colorSchemeContrast)) 127 } 128 } 129 .listStyle(myListStyle.style).anyView 130 .talerFont(.title2) 131 .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) 132 ZStack { 133 list 134 if withDrawStarted { 135 RotatingTaler(size: 150, progress: true, rotationEnabled: $withDrawStarted) 136 } 137 } 138 .task { 139 setVoice(to: nil) 140 await viewDidLoad() 141 } 142 .onAppear() { 143 DebugViewC.shared.setViewID(VIEW_EMPTY_WALLET, stack: stack.push("onAppear")) // 10 144 } 145 } 146 } 147 148 struct WalletEmptyView_Previews: PreviewProvider { 149 static var previews: some View { 150 WalletEmptyView(stack: CallStack("Preview")) 151 } 152 }