taler-ios

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

BankListView.swift (4310B)


      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 
     56         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.")
     57 
     58         let emptyList = Group {
     59             Section {
     60                 Text("There are no bank accounts yet.")
     61                     .talerFont(.title3)
     62             }
     63             Section {
     64                 depositHint
     65                 let plus = Image(systemName: PLUS)
     66                 if !minimalistic {
     67                     Text("Tap the \(plus) button to add an account.")
     68                         .listRowSeparator(.hidden)
     69                     Text("You can also scan a withdrawal QR code from your bank in the Action menu to automatically add a bank account.")
     70                 } else {
     71                     Text("Tap \(plus) or scan a withdrawal QR code from your bank to add a bank account.")
     72                 }
     73             }
     74                 .talerFont(.body)
     75         }
     76 
     77         let addBankDest = BankEditView(stack: stack.push(), accountID: nil)
     78         let actions = Group {
     79             NavLink($showAddDialog) { addBankDest }
     80         }
     81 
     82         List {
     83             if bankAccounts.isEmpty {
     84                 emptyList
     85 //                    .opacity(0)           // TODO: wait 0.5 seconds, then fade in
     86             } else {
     87                 depositHint
     88                 ForEach(bankAccounts, id: \.self) { account in
     89                     BankSectionView(stack: stack.push(),
     90                                   account: account,
     91                           selectedBalance: nil,                                 // needed for Deposit, ignore
     92                            amountLastUsed: $amountLastUsed,                     // needed for Deposit, ignore
     93                                  goToEdit: true)
     94                 }
     95             }
     96         }
     97         .background(actions)
     98         .listStyle(myListStyle.style).anyView
     99         .refreshable {
    100             controller.hapticNotification(.success)
    101             symLog.log("refreshing")
    102             await viewDidLoad()
    103         }
    104         .onNotification(.BankAccountChange) { notification in
    105 //            logger.info(".onNotification(.BankAccountChange) ==> reload accounts")
    106             Task { await viewDidLoad() }
    107         }
    108         .task { await viewDidLoad() }
    109         .navigationTitle(navTitle)
    110         .navigationBarItems(trailing: plusButton)
    111         .onAppear() {
    112             DebugViewC.shared.setViewID(VIEW_BANK_ACCOUNTS, stack: stack.push())
    113         }
    114     } // body
    115 }