taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

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 }