taler-ios

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

BalancesListView.swift (6026B)


      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 import AVFoundation
     12 
     13 /// This view shows the list of balances / currencies, each in its own section
     14 struct BalancesListView: View {
     15     private let symLog = SymLogV(0)
     16     let stack: CallStack
     17     let title: String
     18     @Binding var selectedBalance: Balance?                      // set in TransactionsListView
     19     @Binding var reloadTransactions: Int
     20     @Binding var qrButtonTapped: Bool
     21 
     22     @EnvironmentObject private var model: WalletModel
     23     @EnvironmentObject private var controller: Controller
     24     @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
     25     @AppStorage("oimEuro") var oimEuro: Bool = false
     26 
     27     @State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING)    // Update currency when used
     28     @State private var summary = EMPTYSTRING
     29 
     30     @State private var historyTapped: Int? = nil
     31     @Namespace var namespace
     32 
     33     private static func className() -> String {"\(self)"}
     34 
     35     func refresh() async {
     36         controller.hapticNotification(.success)
     37         symLog.log("refreshing balances")
     38         await controller.loadBalances(stack.push("refreshing balances"), model)
     39     }
     40 
     41     var body: some View {
     42 #if PRINT_CHANGES
     43         let _ = Self._printChanges()
     44         let _ = symLog.vlog()       // just to get the # to compare it with .onAppear & onDisappear
     45 #endif
     46 //        Group {
     47             if controller.balances.isEmpty {
     48                 let talerLogo = HStack(spacing: 2) {
     49                     Image(TALER_LOGO_FULL)
     50 //                        .border(Color.gray, width: 1)
     51 //                    Text("TALER Wallet")
     52                     Text("Wallet")
     53 //                        .font(.logo(27, weight: .medium))
     54                         .font(.logo("Atkinson Hyperlegible Next", size: 27, weight: .medium))
     55                         .kerning(1.0)
     56                 }
     57                     .accessibilityElement(children: .combine)
     58                     .accessibilityAddTraits(.isHeader)
     59                     .accessibilityLabel(Text("Taler Wallet", comment: "a11y"))
     60 
     61                 WalletEmptyView(stack: stack.push("isEmpty"))
     62 //                    .navigationTitle("Taler Wallet")
     63                     .toolbar {
     64                         ToolbarItem(placement: .principal) {
     65                             talerLogo
     66                                 .padding(.top, 10)
     67                         }
     68                     }
     69                     .refreshable {
     70                         await refresh()
     71                     }
     72             } else {
     73                 /// In standard mode, selectedBalance just sets a "preference" which balance to pre-select for Actions.
     74                 ///   However, the user can select another balance (with the picker) in each action
     75                 /// In OIM mode, the user selects a balance 'here' (in OIMView) when tapping on a savings box (representing the balance)
     76                 let count = controller.balances.count
     77                 Group {
     78                     List {
     79                         if !controller.haveProdBalance && !controller.defaultExchanges.isEmpty {
     80                             ProdSectionView(stack: stack.push(), isEmpty: false, disabled: false)
     81                         }
     82                         ForEach(Array(controller.balances.enumerated()), id: \.element) { index, balance in
     83                             BalancesSectionView(stack: stack.push("\(balance.scopeInfo.currency)"),
     84                                               balance: balance,                     // this is the currency to be used
     85                                       selectedBalance: $selectedBalance,            // set in TransactionsListView
     86                                          balanceIndex: index,
     87                                          sectionCount: count,
     88                                      amountToTransfer: $amountToTransfer,           // does still have the wrong currency
     89                                               summary: $summary,
     90                                         historyTapped: $historyTapped,
     91                                    reloadTransactions: $reloadTransactions)
     92                         }
     93                     }
     94                     .onAppear() {
     95                         DebugViewC.shared.setViewID(VIEW_BALANCES, stack: stack.push("onAppear"))
     96                         if !controller.oimModeActive {
     97                             print("🚩BalancesListView.onAppear() reset selectedBalance")
     98 //                            if count > 1 {
     99                                 selectedBalance = nil                           // reset
    100 //                            }
    101                         }
    102                     }
    103                     .listStyle(myListStyle.style).anyView
    104                     .refreshable {
    105                         await refresh()
    106                     }
    107                 }.navigationTitle(title)
    108                 .onChange(of: controller.oimModeActive) { oimModeActive in
    109                     if !oimModeActive {
    110                         print("🚩BalancesListView.onChange(of: oimModeActive) reset selectedBalance")
    111 //                        if count > 1 {
    112                             selectedBalance = nil                               // reset
    113 //                        }
    114                     }
    115                 }
    116 #if OIM
    117                 .overlay { if #available(iOS 16.4, *) {
    118                     if controller.oimModeActive {
    119                         OIMbalances(stack: stack.push(),
    120                           selectedBalance: $selectedBalance,                    // set to user choice
    121                            qrButtonTapped: $qrButtonTapped,
    122                             historyTapped: $historyTapped,
    123                                   oimEuro: oimEuro)
    124                         .environmentObject(NamespaceWrapper(namespace))         // keep OIMviews apart
    125                     }
    126                 } }
    127 #endif
    128             } // not empty
    129 //        }
    130     }
    131 }