taler-ios

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

commit 8783a264b3375915dac50986872e5c4dec27056b
parent 9483593e3b554bf9d39af1830f59fd247f029cdb
Author: Marc Stibane <marc@taler.net>
Date:   Fri, 13 Dec 2024 12:28:52 +0100

Deposit+bank accounts, w.i.p.

Diffstat:
MTalerWallet1/Controllers/PublicConstants.swift | 1+
MTalerWallet1/Model/Model+Deposit.swift | 37++++++++++++++++++++++---------------
MTalerWallet1/Views/Actions/Banking/DepositAmountV.swift | 19++++++++++++++-----
MTalerWallet1/Views/Actions/Banking/DepositAmountView.swift | 13+++++++------
MTalerWallet1/Views/Actions/Banking/DepositSelectV.swift | 49+++++++++++++++----------------------------------
MTalerWallet1/Views/Settings/Bank/BankEditView.swift | 184++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
MTalerWallet1/Views/Settings/Bank/BankListView.swift | 20+++++++++++++-------
MTalerWallet1/Views/Settings/Bank/BankSectionView.swift | 82+++++++++++++++++++++++++------------------------------------------------------
8 files changed, 206 insertions(+), 199 deletions(-)

diff --git a/TalerWallet1/Controllers/PublicConstants.swift b/TalerWallet1/Controllers/PublicConstants.swift @@ -134,6 +134,7 @@ public let NOTIFICATIONERROR = "error" extension Notification.Name { static let Idle = Notification.Name("idle") static let BalanceChange = Notification.Name("balance-change") + static let BankAccountChange = Notification.Name(AccountChange.TransitionType.change.rawValue) static let ExchangeAdded = Notification.Name("exchange-added") static let ExchangeDeleted = Notification.Name("exchange-deleted") static let ExchangeStateTransition = Notification.Name(ExchangeTransition.TransitionType.transition.rawValue) diff --git a/TalerWallet1/Model/Model+Deposit.swift b/TalerWallet1/Model/Model+Deposit.swift @@ -11,6 +11,14 @@ import AnyCodable //import SymLog fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for debugging +struct AccountChange: Codable { // Notification + enum TransitionType: String, Codable { + case change = "bank-account-change" + } + var type: TransitionType + var bankAccountId: String +} + // MARK: - IBAN struct ValidateIbanResult: Codable { let valid: Bool @@ -60,16 +68,17 @@ fileprivate struct DepositWireTypes: WalletBackendFormattedRequest { func operation() -> String { "getDepositWireTypes" } func args() -> Args { Args(currency: currency, scopeInfo: scopeInfo) } - var currency: String + var currency: String? var scopeInfo: ScopeInfo? struct Args: Encodable { - var currency: String + // one of these must be set - don't set both to nil + var currency: String? var scopeInfo: ScopeInfo? } } extension WalletModel { /// Get wire types that can be used for a deposit operation - nonisolated func depositWireTypes(_ currency: String, scopeInfo: ScopeInfo? = nil, viewHandles: Bool = false) + nonisolated func depositWireTypes(_ currency: String?, scopeInfo: ScopeInfo? = nil, viewHandles: Bool = false) async throws -> [WireTypeDetails] { let request = DepositWireTypes(currency: currency, scopeInfo: scopeInfo) let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) @@ -147,19 +156,22 @@ fileprivate struct CreateDepositGroup: WalletBackendFormattedRequest { typealias Response = DepositGroupResult func operation() -> String { "createDepositGroup" } func args() -> Args { Args(depositPaytoUri: depositPaytoUri, + restrictScope: scope, amount: amount) } var depositPaytoUri: String + var scope: ScopeInfo var amount: Amount struct Args: Encodable { var depositPaytoUri: String + var restrictScope: ScopeInfo var amount: Amount } } extension WalletModel { /// deposit coins. Networking involved - nonisolated func createDepositGroup(_ depositPaytoUri: String, amount: Amount, viewHandles: Bool = false) + nonisolated func createDepositGroup(_ depositPaytoUri: String, scope: ScopeInfo, amount: Amount, viewHandles: Bool = false) async throws -> DepositGroupResult { - let request = CreateDepositGroup(depositPaytoUri: depositPaytoUri, amount: amount) + let request = CreateDepositGroup(depositPaytoUri: depositPaytoUri, scope: scope, amount: amount) let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response } @@ -169,7 +181,6 @@ struct BankAccountsInfo: Decodable, Hashable { var bankAccountId: String var paytoUri: String var kycCompleted: Bool - var currencies: [String]? var label: String? } struct BankAccounts: Decodable, Hashable { @@ -224,28 +235,24 @@ fileprivate struct AddBankAccount: WalletBackendFormattedRequest { func operation() -> String { "addBankAccount" } func args() -> Args { Args(paytoUri: uri, label: label, - currencies: currencies, - replacePaytoUri: replaceUri) } + replaceBankAccountId: replace) } var uri: String var label: String - var currencies: [String]? - var replaceUri: String? + var replace: String? struct Args: Encodable { var paytoUri: String // bank account that should be added var label: String // Human-readable label - var currencies: [String]? // currencies supported by the bank (if known) - var replacePaytoUri: String? // account that this new account should replace + var replaceBankAccountId: String? // account that this new account should replace } } extension WalletModel { /// add (or update) a known account. No networking nonisolated func addBankAccount(_ uri: String, label: String, - currencies: [String]? = nil, - replaceUri: String? = nil, + replace: String? = nil, viewHandles: Bool = false) async throws -> String { - let request = AddBankAccount(uri: uri, label: label, currencies: currencies, replaceUri: replaceUri) + let request = AddBankAccount(uri: uri, label: label, replace: replace) let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles) return response.bankAccountId } diff --git a/TalerWallet1/Views/Actions/Banking/DepositAmountV.swift b/TalerWallet1/Views/Actions/Banking/DepositAmountV.swift @@ -16,6 +16,7 @@ struct DepositAmountV: View { @Binding var selectedBalance: Balance? @Binding var amountLastUsed: Amount let paytoUri: String? + let label: String? @EnvironmentObject private var controller: Controller @EnvironmentObject private var model: WalletModel @@ -68,10 +69,15 @@ struct DepositAmountV: View { #endif let count = controller.balances.count let _ = symLog.log("count = \(count)") - let navTitle = String(localized: "NavTitle_Deposit_Currency", - defaultValue: "Deposit", // \(currencySymbol)", - comment: "NavTitle: Deposit 'currencySymbol'") +// let navTitle = String(localized: "NavTitle_Deposit", // _Currency", +// defaultValue: "Deposit") // \(currencySymbol)" let scrollView = ScrollView { + if let label { + Text("to \(label)") + .talerFont(.picker) + .frame(maxWidth: .infinity, alignment: .leading) + .padding(.horizontal) + } if count > 0 { ScopePicker(value: $balanceIndex, onlyNonZero: true) // can only send what exists @@ -90,10 +96,13 @@ struct DepositAmountV: View { amountAvailable: amountAvailable, paytoUri: paytoUri) } // ScrollView - .navigationTitle(navTitle) +// .navigationTitle(navTitle) .frame(maxWidth: .infinity, alignment: .leading) .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) - .task { await viewDidLoad() } + .task { + setVoice(to: nil) + await viewDidLoad() + } .task(id: balanceIndex + (1000 * controller.currencyTicker)) { await newBalance() } if #available(iOS 16.0, *) { diff --git a/TalerWallet1/Views/Actions/Banking/DepositAmountView.swift b/TalerWallet1/Views/Actions/Banking/DepositAmountView.swift @@ -38,10 +38,9 @@ struct DepositAmountView: View { ) -> String { condition ? String(localized: "NavTitle_Deposit_Currency", defaultValue: "Deposit \(currency)", - comment: "NavTitle: Deposit 'currencySymbol'") + comment: "currencySymbol") : String(localized: "NavTitle_Deposit", - defaultValue: "Deposit", - comment: "NavTitle: Deposit") + defaultValue: "Deposit") } private func feeLabel(_ feeString: String) -> String { @@ -90,12 +89,14 @@ struct DepositAmountView: View { } @MainActor - private func startDeposit() { + private func startDeposit(_ scope: ScopeInfo) { if let paytoUri { depositStarted = true // don't run twice Task { symLog.log("Deposit") - if let result = try? await model.createDepositGroup(paytoUri, amount: amountToTransfer) { + if let result = try? await model.createDepositGroup(paytoUri, + scope: scope, + amount: amountToTransfer) { symLog.log(result.transactionId) // ViewState2.shared.popToRootView(stack.push()) NotificationCenter.default.post(name: .TransactionDone, object: nil, userInfo: nil) @@ -162,7 +163,7 @@ struct DepositAmountView: View { .padding(4) let hint = String(localized: "enabled when amount is non-zero, but not higher than your available amount", comment: "VoiceOver") - Button(buttonTitle(amountToTransfer)) { startDeposit() } + Button(buttonTitle(amountToTransfer)) { startDeposit(balance.scopeInfo) } // TODO: use exchange scope .buttonStyle(TalerButtonStyle(type: .prominent, disabled: disabled || depositStarted)) .padding(.horizontal) .disabled(disabled || depositStarted) diff --git a/TalerWallet1/Views/Actions/Banking/DepositSelectV.swift b/TalerWallet1/Views/Actions/Banking/DepositSelectV.swift @@ -62,8 +62,8 @@ struct DepositSelectV: View { Section { depositHint } - Section { - if bankAccounts.isEmpty { + if bankAccounts.isEmpty { + Section { let bankAccountsTitle = String(localized: "TitleBankAccounts", defaultValue: "Bank Accounts") let bankAccountsDest = BankListView(stack: stack.push(bankAccountsTitle), navTitle: bankAccountsTitle) @@ -73,37 +73,15 @@ struct DepositSelectV: View { SettingsItem(name: bankAccountsTitle, id1: "bankAccounts", description: minimalistic ? nil : String(localized: "Your accounts for deposit...")) {} } - } else { - ForEach(bankAccounts, id: \.self) { account in -// let disabled = (accountHolder.count < 1) || paytoUri == nil // TODO: check amountAvailable - let payURL = URL(string: account.paytoUri) - let iban = payURL?.iban - let xTaler = payURL?.xTaler - let alias = account.label - let kyc = account.kycCompleted ? String(localized: "verified", comment: "KYC state") - : String(localized: "not yet verified", comment: "KYC state") - - let destination = DepositAmountV(stack: stack.push(), - selectedBalance: $selectedBalance, - amountLastUsed: $amountLastUsed, - paytoUri: account.paytoUri) - NavigationLink(destination: destination) { - VStack { - if let iban { - Text("IBAN: \(iban)") - } else if let xTaler { - Text("xTaler: \(xTaler)") - } else { - Text("unknown payment method") - } - Text("Status: \(kyc)") - .padding(.leading) - if let alias { - Text(alias) - } - } - } - } + } + } else { + ForEach(bankAccounts, id: \.self) { account in +// let disabled = (accountHolder.count < 1) || paytoUri == nil // TODO: check amountAvailable + BankSectionView(stack: stack.push(), + account: account, + selectedBalance: $selectedBalance, + amountLastUsed: $amountLastUsed, + goToEdit: false) } } } @@ -113,7 +91,10 @@ struct DepositSelectV: View { symLog.log("refreshing") await viewDidLoad() } - .task { await viewDidLoad() } + .task { + setVoice(to: nil) + await viewDidLoad() + } .navigationTitle(subjectTitle) // .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) .onAppear { diff --git a/TalerWallet1/Views/Settings/Bank/BankEditView.swift b/TalerWallet1/Views/Settings/Bank/BankEditView.swift @@ -28,19 +28,20 @@ struct BankEditView: View { @State private var didDelete: Bool = false @State private var disabled: Bool = false @State private var showAlert: Bool = false - @State private var purge: Bool = false -// @State private var global: Bool = false + + @State private var myAccount: String? = nil @State private var accountHolder: String = EMPTYSTRING @State private var iban: String = EMPTYSTRING @State private var xTaler: String = EMPTYSTRING - @State private var label: String = EMPTYSTRING + @State private var accountLabel: String = EMPTYSTRING @State private var paytoType: PaytoType = .iban - @State private var currencies: [String] = [] @State private var selected = 0 + @State private var kycCompleted = false + @FocusState private var focus:FocusedField? enum FocusedField: Hashable { - case accountHolder, iban, xTaler, label + case accountLabel, accountHolder, iban, xTaler } // @MainActor @@ -60,12 +61,15 @@ struct BankEditView: View { let payURL = URL(string: account.paytoUri) iban = payURL?.iban ?? EMPTYSTRING xTaler = payURL?.xTaler ?? EMPTYSTRING - label = account.label ?? EMPTYSTRING + if iban.count < 1 && xTaler.count > 1 { + paytoType = .xTalerBank + } + accountLabel = account.label ?? EMPTYSTRING + kycCompleted = account.kycCompleted if let queryParameters = payURL?.queryParameters { let name = queryParameters["receiver-name"] ?? ownerName accountHolder = name.replacingOccurrences(of: "+", with: SPACE) } - currencies = account.currencies ?? [] } } else { @@ -73,21 +77,38 @@ struct BankEditView: View { } @MainActor + private func updateAccount() async { + let payto = "payto://iban/\(iban)?receiver-name=\(accountHolder)" + let paytoUri = payto.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)! + + symLog.log(paytoUri) + if let account = try? await model.addBankAccount(paytoUri, + label: accountLabel, + replace: myAccount ?? accountID + ) { + symLog.log(account) + myAccount = account + } else { + symLog.log("error addBankAccount") + } + } + + @MainActor private func deleteAccount() { disabled = true // don't try this more than once Task { // runs on MainActor -// if let _ = try? await model.deleteExchange(url: baseUrl, purge: purge, viewHandles: !purge) { -// purge = false -// symLog.log("deleted \(baseUrl.trimURL)") -// didDelete = true // change button text + if let id = myAccount ?? accountID { + if let _ = try? await model.forgetBankAccount(id) { + symLog.log("forgot \(id)") + didDelete = true // change button text // NotificationCenter.default.post(name: .ExchangeDeleted, object: nil, userInfo: nil) // NotificationCenter.default.post(name: .BalanceChange, object: nil, userInfo: nil) -// demoHints = true -// } else { -// purge = true -// showAlert = true -// disabled = false -// } + dismissTop(stack.push()) + } else { + showAlert = true + disabled = false + } + } } } @@ -97,39 +118,70 @@ struct BankEditView: View { // let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear #endif let methods = [PaytoType.iban, PaytoType.xTalerBank] - List { Group { - let accountTitle = String(localized: "Account holder") - let accountColon = String("\(accountTitle):") + List { + if kycCompleted // || true + { Section { + Text("If you change the account holder name or the IBAN, you may have to perform the KYC procedure again.") + .talerFont(.body) + } + } + Section { + let labelTitle = String(localized: "Label") + let labelColon = String("\(labelTitle):") + if !minimalistic { + Text(labelColon) + .talerFont(.picker) + .accessibilityHidden(true) + .padding(.bottom, -12) + } + TextField(minimalistic ? labelTitle : EMPTYSTRING, text: $accountLabel) + .accessibilityLabel(labelColon) + .focused($focus, equals: .accountLabel) + .talerFont(.title3) + .foregroundColor(WalletColors().fieldForeground) // text color + .background(WalletColors().fieldBackground) + .textFieldStyle(.roundedBorder) + .padding(.bottom) + + let holderTitle = String(localized: "Account holder") + let holderColon = String("\(holderTitle):") if !minimalistic { - Text(accountColon) - .talerFont(.body) + Text(holderColon) + .talerFont(.picker) .accessibilityHidden(true) + .padding(.bottom, -12) } - TextField(minimalistic ? accountTitle : EMPTYSTRING, text: $accountHolder) - .accessibilityLabel(accountColon) + TextField(minimalistic ? holderTitle : EMPTYSTRING, text: $accountHolder) + .accessibilityLabel(holderColon) .focused($focus, equals: .accountHolder) .talerFont(.title3) .foregroundColor(WalletColors().fieldForeground) // text color .background(WalletColors().fieldBackground) .textFieldStyle(.roundedBorder) - .padding(.top, -4) .padding(.bottom) - Picker(EMPTYSTRING, selection: $selected) { - ForEach(0..<methods.count, id: \.self) { index in - let method = methods[index] - Text(method.rawValue.uppercased()) - .tag(index) + let paytoStr = paytoType.rawValue.uppercased() + let paytoColon = String("\(paytoStr):") + if let accountID { + // we are editing an existing bank account + Text(paytoColon) + .talerFont(.picker) + .accessibilityHidden(true) + .padding(.bottom, -12) + } else { + // this is a NEW bank account - choose a payment method + Picker(EMPTYSTRING, selection: $selected) { + ForEach(0..<methods.count, id: \.self) { index in + let method = methods[index] + Text(method.rawValue.uppercased()) + .tag(index) + } } - } .pickerStyle(.segmented) .onChange(of: selected) { newValue in paytoType = methods[newValue] } - - Group { - let paytoStr = paytoType.rawValue.uppercased() - let paytoColon = String("\(paytoStr):") + } if paytoType == .iban { TextField(paytoStr, text: $iban) .accessibilityLabel(paytoColon) @@ -138,6 +190,7 @@ struct BankEditView: View { .foregroundColor(WalletColors().fieldForeground) // text color .background(WalletColors().fieldBackground) .textFieldStyle(.roundedBorder) + .padding(.bottom) } else if paytoType == .xTalerBank { TextField(paytoStr, text: $xTaler) .accessibilityLabel(paytoColon) @@ -146,57 +199,36 @@ struct BankEditView: View { .foregroundColor(WalletColors().fieldForeground) // text color .background(WalletColors().fieldBackground) .textFieldStyle(.roundedBorder) + .padding(.bottom) } else { Text("unknown payment method") + .talerFont(.title3) + .padding(.bottom) } - }.padding(.bottom) - - if currencies.count == 1 { - let currency = currencies[0] - Text(minimalistic ? currency - : "Currency: \(currency)") - } else if currencies.count > 1 { - if !minimalistic { - Text("Currencies:") - } - ForEach (currencies, id: \.self) { currency in - Text(currency) - .padding(.leading) + let buttonTitle = String(localized: "Account.Delete", defaultValue: "Forget bank account", comment: "Action button") + let warningText1 = String(localized: "Are you sure you want to forget this bank account?") + WarningButton(warningText: warningText1, + buttonTitle: buttonTitle, + buttonIcon: "trash", + role: .destructive, + disabled: $disabled, + action: deleteAccount) + .padding(.top) + }.listRowSeparator(.hidden) + } // List + .onChange(of: focus) { [focus] newState in + switch focus { + case .none: + break + case .some(_): Task { + await updateAccount() } } - - let note = String(localized: "Note") - let noteColon = String("\(note):") - if !minimalistic { - Text(noteColon) - .talerFont(.title3) - .accessibilityHidden(true) - } - TextField(minimalistic ? note : EMPTYSTRING, text: $label) - .accessibilityLabel(noteColon) - .focused($focus, equals: .label) - .talerFont(.title2) - .foregroundColor(WalletColors().fieldForeground) // text color - .background(WalletColors().fieldBackground) - .textFieldStyle(.roundedBorder) - Button { - deleteAccount() - } label: { - Label("Delete Account", systemImage: "trash") - } - .buttonStyle(TalerButtonStyle(type: .bordered, disabled: disabled)) - .disabled(disabled) - }.listRowSeparator(.hidden) - } // List - .onChange(of: focus) { - print($0) } .task { await viewDidLoad() } -// .task(id: controller.currencyTicker) { await currencyTickerChanged(scopeInfo) } .onDisappear() { disabled = false - purge = false } } } diff --git a/TalerWallet1/Views/Settings/Bank/BankListView.swift b/TalerWallet1/Views/Settings/Bank/BankListView.swift @@ -20,8 +20,9 @@ struct BankListView: View { @AppStorage("minimalistic") var minimalistic: Bool = false @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic - @State var showAddDialog: Bool = false - @State var newExchange: String = TESTEXCHANGE + @State private var selectedBalance: Balance? = nil + @State private var amountLastUsed = Amount.zero(currency: EMPTYSTRING) // needed for Deposit, ignore + @State private var showAddDialog: Bool = false @State private var bankAccounts: [BankAccountsInfo] = [] @MainActor @@ -76,8 +77,7 @@ struct BankListView: View { .talerFont(.body) } - let addBankDest = BankEditView(stack: stack.push(), - accountID: nil) + let addBankDest = BankEditView(stack: stack.push(), accountID: nil) let actions = Group { NavLink($showAddDialog) { addBankDest } } @@ -85,13 +85,15 @@ struct BankListView: View { List { if bankAccounts.isEmpty { emptyList - .opacity(0) +// .opacity(0) // TODO: wait 0.5 seconds, then fade in } else { depositHint ForEach(bankAccounts, id: \.self) { account in BankSectionView(stack: stack.push(), - account: account) -// Text(account.paytoUri) + account: account, + selectedBalance: $selectedBalance, // needed for Deposit, ignore + amountLastUsed: $amountLastUsed, // needed for Deposit, ignore + goToEdit: true) } } } @@ -102,6 +104,10 @@ struct BankListView: View { symLog.log("refreshing") await viewDidLoad() } + .onNotification(.BankAccountChange) { notification in +// logger.info(".onNotification(.BankAccountChange) ==> reload accounts") + Task { await viewDidLoad() } + } .task { await viewDidLoad() } .navigationTitle(navTitle) .navigationBarItems(trailing: plusButton) diff --git a/TalerWallet1/Views/Settings/Bank/BankSectionView.swift b/TalerWallet1/Views/Settings/Bank/BankSectionView.swift @@ -15,31 +15,23 @@ struct BankSectionView: View { private let symLog = SymLogV(0) let stack: CallStack let account: BankAccountsInfo + @Binding var selectedBalance: Balance? + @Binding var amountLastUsed: Amount + let goToEdit: Bool @EnvironmentObject private var model: WalletModel @EnvironmentObject private var controller: Controller @AppStorage("minimalistic") var minimalistic: Bool = false - @AppStorage("demoHints") var demoHints: Bool = true - @AppStorage("fakeNoFees") var fakeNoFees: Bool = true @AppStorage("ownerName") var ownerName: String = EMPTYSTRING - @State private var shouldReloadBalances: Int = 0 - @State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN) - @State private var didDelete: Bool = false - @State private var disabled: Bool = false // @State private var purge: Bool = false + @State private var label: String = EMPTYSTRING @State private var accountHolder: String = EMPTYSTRING @State private var iban: String = EMPTYSTRING @State private var xTaler: String = EMPTYSTRING - @State private var label: String = EMPTYSTRING @State private var paytoType: PaytoType = .iban @State private var selected = 0 - @FocusState private var focus:FocusedField? - - enum FocusedField: Hashable { - case accountHolder, iban, xTaler, label - } // @MainActor // private func validateIban() async { @@ -67,24 +59,6 @@ struct BankSectionView: View { } } - @MainActor - private func deleteAccount() { - disabled = true // don't try this more than once - Task { // runs on MainActor -// if let _ = try? await model.deleteExchange(url: baseUrl, purge: purge, viewHandles: !purge) { -// purge = false -// symLog.log("deleted \(baseUrl.trimURL)") -// didDelete = true // change button text -// NotificationCenter.default.post(name: .ExchangeDeleted, object: nil, userInfo: nil) -// NotificationCenter.default.post(name: .BalanceChange, object: nil, userInfo: nil) -// demoHints = true -// } else { -// purge = true -// disabled = false -// } - } - } - var body: some View { #if PRINT_CHANGES let _ = Self._printChanges() @@ -97,29 +71,25 @@ struct BankSectionView: View { let methodStr = (paytoType == .iban) ? iban : (paytoType == .xTalerBank) ? xTaler : "unknown payment method" + let editHint = String(localized: "Double tap to edit the account", comment: "VoiceOver") + let selectHint = String(localized: "Double tap to select", comment: "VoiceOver") Section { NavigationLink { - BankEditView(stack: stack.push(), - accountID: account.bankAccountId) + if goToEdit { + BankEditView(stack: stack.push(), + accountID: account.bankAccountId) + } else { + let navTitle = String(localized: "NavTitle_Deposit", // _Currency", + defaultValue: "Deposit") // \(currencySymbol)" + DepositAmountV(stack: stack.push(), + selectedBalance: $selectedBalance, + amountLastUsed: $amountLastUsed, + paytoUri: account.paytoUri, + label: account.label) + .navigationTitle(navTitle) + } } label: { VStack(alignment: .leading) { - if let currencies = account.currencies { - if currencies.count == 1 { - BankSectionRow(title: String(localized: "Currency:"), - value: currencies[0]) - } else { - if !minimalistic { Text("Currencies:") } - ForEach (currencies, id: \.self) { currency in - Text(currency) - .frame(maxWidth: .infinity, alignment: .trailing) - } - } - } else { - BankSectionRow(title: String(localized: "Currency:"), - value: "UNKNOWN") - } - BankSectionRow(title: String(localized: "Note:"), - value: label) BankSectionRow(title: String(localized: "Account holder:"), value: accountHolder) BankSectionRow(title: String(localized: "\(methodType):", comment: "methodType:"), @@ -127,18 +97,18 @@ struct BankSectionView: View { BankSectionRow(title: String(localized: "Status:"), value: kyc) } .talerFont(.body) - .accessibilityElement(children: .combine) - .accessibilityHint(String(localized: "Double tap to edit the account", comment: "VoiceOver")) + .listRowSeparator(.hidden) +// .accessibilityElement(children: .combine) } + .accessibilityHint(goToEdit ? editHint : selectHint) } header: { - } - .listRowSeparator(.hidden) - .onChange(of: focus) { - print($0) + Text(label) + .talerFont(.title3) +// .foregroundColor(WalletColors().secondary(colorScheme, colorSchemeContrast)) +// .accessibilityHint(EMPTYSTRING) } .task { await viewDidLoad() } .onDisappear() { - disabled = false // purge = false } }