taler-ios

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

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 }