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