taler-ios

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

DepositAmountV.swift (4194B)


      1 /*
      2  * This file is part of GNU Taler, ©2022-25 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 // Called from DepositSelectV
     13 struct DepositAmountV: View {
     14     private let symLog = SymLogV(0)
     15     let stack: CallStack
     16     // when Action is tapped while in currency TransactionList…
     17     let selectedBalance: Balance?   // …then use THIS balance, otherwise show picker
     18     @Binding var amountLastUsed: Amount
     19     let paytoUri: String?
     20     let label: String?
     21 
     22     @EnvironmentObject private var controller: Controller
     23     @EnvironmentObject private var model: WalletModel
     24 
     25     @State private var balanceIndex = 0
     26     @State private var balance: Balance? = nil      // nil only when balances == []
     27     @State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING)    // Update currency when used
     28     @State private var amountAvailable = Amount.zero(currency: EMPTYSTRING)     // GetMaxPeerPushAmount
     29 
     30     @MainActor
     31     private func viewDidLoad() async {
     32         let balances = controller.balances
     33         if let selectedBalance {
     34             if selectedBalance.available.isZero {
     35                 // find another balance
     36                 balance = Balance.firstNonZero(balances)
     37             } else {
     38                 balance = selectedBalance
     39             }
     40         } else {
     41             balance = Balance.firstNonZero(balances)
     42         }
     43         if let balance {
     44             balanceIndex = balances.firstIndex(of: balance) ?? 0
     45         } else {
     46             balanceIndex = 0
     47             balance = (balances.count > 0) ? balances[0] : nil
     48         }
     49     }
     50 
     51     @MainActor
     52     private func newBalance() async {
     53         // runs whenever the user changes the exchange via ScopePicker, or on new currencyInfo
     54         symLog.log("❗️ task \(balanceIndex)")
     55         if let balance {
     56             let scope = balance.scopeInfo
     57             amountToTransfer.setCurrency(scope.currency)
     58             do {
     59                 amountAvailable = try await model.getMaxDepositAmount(scope)
     60             } catch {
     61                 // TODO: Error
     62                 amountAvailable = balance.available
     63             }
     64         }
     65     }
     66 
     67     var body: some View {
     68 #if PRINT_CHANGES
     69         let _ = Self._printChanges()
     70 #endif
     71         let count = controller.balances.count
     72         let _ = symLog.log("count = \(count)")
     73 //        let navTitle = String(localized: "NavTitle_Deposit",    // _Currency",
     74 //                           defaultValue: "Deposit")             // \(currencySymbol)"
     75         let scrollView = ScrollView {
     76             if let label {
     77                 Text("to \(label)")
     78                     .talerFont(.picker)
     79                     .frame(maxWidth: .infinity, alignment: .leading)
     80                     .padding(.horizontal)
     81             }
     82             if count > 0 {
     83                 ScopePicker(value: $balanceIndex,
     84                       onlyNonZero: true)                                        // can only send what exists
     85                 { index in
     86                     balanceIndex = index
     87                     balance = controller.balances[index]
     88                 }
     89                 .padding(.horizontal)
     90                 .padding(.bottom, 4)
     91             }
     92             DepositAmountView(stack: stack.push(),
     93                             balance: $balance,
     94                        balanceIndex: $balanceIndex,
     95                      amountLastUsed: $amountLastUsed,
     96                    amountToTransfer: $amountToTransfer,
     97                     amountAvailable: amountAvailable,
     98                            paytoUri: paytoUri)
     99         } // ScrollView
    100 //            .navigationTitle(navTitle)
    101             .frame(maxWidth: .infinity, alignment: .leading)
    102             .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all))
    103             .task {
    104                 setVoice(to: nil)
    105                 await viewDidLoad()
    106             }
    107             .task(id: balanceIndex + (1000 * controller.currencyTicker)) { await newBalance() }
    108 
    109         if #available(iOS 16.4, *) {
    110             scrollView.toolbar(.hidden, for: .tabBar)
    111                 .scrollBounceBehavior(.basedOnSize)
    112         } else {
    113             scrollView
    114         }
    115     }
    116 }