BankListView.swift (4515B)
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 /// This view shows the list of exchanges 13 struct BankListView: View { 14 private let symLog = SymLogV(0) 15 let stack: CallStack 16 let navTitle: String 17 18 @EnvironmentObject private var model: WalletModel 19 @EnvironmentObject private var controller: Controller 20 @AppStorage("minimalistic") var minimalistic: Bool = false 21 @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic 22 23 @State private var amountLastUsed = Amount.zero(currency: EMPTYSTRING) // needed for Deposit, ignore 24 @State private var showAddDialog: Bool = false 25 @State private var bankAccounts: [BankAccountsInfo] = [] 26 27 @MainActor 28 func addExchange(_ exchange: String) -> Void { 29 Task { // runs on MainActor 30 symLog.log("adding: \(exchange)") 31 if let _ = try? await model.addExchange(uri: exchange) { 32 symLog.log("added: \(exchange)") 33 announce("added: \(exchange)") 34 NotificationCenter.default.post(name: .ExchangeAdded, object: nil, userInfo: nil) 35 } 36 } 37 } 38 39 @MainActor 40 private func viewDidLoad() async { 41 if let accounts = try? await model.listBankAccounts() { 42 withAnimation { bankAccounts = accounts } 43 } 44 } 45 46 var body: some View { 47 #if PRINT_CHANGES 48 let _ = Self._printChanges() 49 let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear 50 #endif 51 let a11yLabelStr = String(localized: "Add bank account", comment: "a11y for the + button") 52 let plusButton = PlusButton(accessibilityLabelStr: a11yLabelStr) { 53 showAddDialog = true 54 } 55 let addTitleStr = String(localized: "Add bank account", comment: "title of the addExchange alert") 56 let addButtonStr = String(localized: "Add", comment: "button in the addExchange alert") 57 58 let depositHint = Text("You can only deposit to a bank account that you control, otherwise you will not be able to fulfill the regulatory requirements.") 59 60 let emptyList = Group { 61 Section { 62 Text("There are no bank accounts yet.") 63 .talerFont(.title3) 64 } 65 Section { 66 depositHint 67 let plus = Image(systemName: "plus") 68 if !minimalistic { 69 Text("Tap the \(plus) button to add an account.") 70 .listRowSeparator(.hidden) 71 Text("You can also scan a withdrawal QR code from your bank in the Action menu to automatically add a bank account.") 72 } else { 73 Text("Tap \(plus) or scan a withdrawal QR code from your bank to add a bank account.") 74 } 75 } 76 .talerFont(.body) 77 } 78 79 let addBankDest = BankEditView(stack: stack.push(), accountID: nil) 80 let actions = Group { 81 NavLink($showAddDialog) { addBankDest } 82 } 83 84 List { 85 if bankAccounts.isEmpty { 86 emptyList 87 // .opacity(0) // TODO: wait 0.5 seconds, then fade in 88 } else { 89 depositHint 90 ForEach(bankAccounts, id: \.self) { account in 91 BankSectionView(stack: stack.push(), 92 account: account, 93 selectedBalance: nil, // needed for Deposit, ignore 94 amountLastUsed: $amountLastUsed, // needed for Deposit, ignore 95 goToEdit: true) 96 } 97 } 98 } 99 .background(actions) 100 .listStyle(myListStyle.style).anyView 101 .refreshable { 102 controller.hapticNotification(.success) 103 symLog.log("refreshing") 104 await viewDidLoad() 105 } 106 .onNotification(.BankAccountChange) { notification in 107 // logger.info(".onNotification(.BankAccountChange) ==> reload accounts") 108 Task { await viewDidLoad() } 109 } 110 .task { await viewDidLoad() } 111 .navigationTitle(navTitle) 112 .navigationBarItems(trailing: plusButton) 113 .onAppear() { 114 DebugViewC.shared.setViewID(VIEW_BANK_ACCOUNTS, stack: stack.push()) 115 } 116 } // body 117 }