BalancesListView.swift (5202B)
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 21 @EnvironmentObject private var model: WalletModel 22 @EnvironmentObject private var controller: Controller 23 @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic 24 @AppStorage("oimEuro") var oimEuro: Bool = false 25 26 @State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING) // Update currency when used 27 @State private var summary = EMPTYSTRING 28 29 @State private var historyTapped: Int? = nil 30 @Namespace var namespace 31 32 private static func className() -> String {"\(self)"} 33 34 func refresh() async { 35 controller.hapticNotification(.success) 36 symLog.log("refreshing balances") 37 await controller.loadBalances(stack.push("refreshing balances"), model) 38 } 39 40 @ViewBuilder 41 func balancesList() -> some View { 42 let count = controller.balances.count 43 let list = List { 44 if !controller.haveProdBalance && !controller.defaultExchanges.isEmpty { 45 ProdSectionView(stack: stack.push(), isEmpty: false, disabled: false) 46 } 47 ForEachWithIndex(data: controller.balances) { index, balance in 48 BalancesSectionView(stack: stack.push("\(balance.scopeInfo.currency)"), 49 balance: balance, // this is the currency to be used 50 selectedBalance: $selectedBalance, // set in TransactionsListView 51 balanceIndex: index, 52 sectionCount: count, 53 amountToTransfer: $amountToTransfer, // does still have the wrong currency 54 summary: $summary, 55 historyTapped: $historyTapped, 56 reloadTransactions: $reloadTransactions) 57 } 58 } 59 .listStyle(myListStyle.style).anyView 60 .background(FullBackground()) 61 .onAppear() { 62 DebugViewC.shared.setViewID(VIEW_BALANCES, stack: stack.push("onAppear")) 63 if !controller.oimModeActive { 64 print("🚩BalancesListView.onAppear() reset selectedBalance") 65 // if count > 1 { 66 selectedBalance = nil // reset 67 // } 68 } 69 } 70 .refreshable { 71 await refresh() 72 } 73 .navigationTitle(title) 74 if #available(iOS 26.0, *) { 75 list 76 .toolbar { 77 ToolbarItem(placement: .primaryAction) { 78 Button { 79 NotificationCenter.default.post(name: .SettingsAction, object: nil) // will trigger NavigationLink 80 } label: { 81 Label(TalerTab.settings.title, systemImage: TalerTab.settings.sysImg) 82 .labelStyle(.iconOnly) 83 } 84 // .padding() 85 .buttonStyle(.glass) 86 // .accessibilitySortPriority(0) 87 } 88 } 89 } else { 90 list 91 } 92 } 93 94 var body: some View { 95 #if PRINT_CHANGES 96 let _ = Self._printChanges() 97 let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear 98 #endif 99 /// In standard mode, selectedBalance just sets a "preference" which balance to pre-select for Actions. 100 /// However, the user can select another balance (with the picker) in each action 101 /// In OIM mode, the user selects a balance 'here' (in OIMView) when tapping on a savings box (representing the balance) 102 103 balancesList() 104 .onChange(of: controller.oimModeActive) { oimModeActive in 105 if !oimModeActive { 106 print("🚩BalancesListView.onChange(of: oimModeActive) reset selectedBalance") 107 // if count > 1 { 108 selectedBalance = nil // reset 109 // } 110 } 111 } 112 .overlay { if #available(iOS 16.4, *) { 113 if controller.oimModeActive { 114 #if OIM 115 OIMbalances(stack: stack.push(), 116 selectedBalance: $selectedBalance, // set to user choice 117 historyTapped: $historyTapped, 118 oimEuro: oimEuro) 119 .environmentObject(NamespaceWrapper(namespace)) // keep OIMviews apart 120 #endif // OIM 121 } 122 } } 123 } 124 }