taler-ios

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

commit 57ea6031c7f7ed34b1bba83e87f7104d5d2f2ce4
parent 58531d5060d38a02d080fd45ecc33e7fa982994f
Author: Marc Stibane <marc@taler.net>
Date:   Sat,  8 Aug 2026 20:37:43 +0200

improve manual withdraw details

Diffstat:
MTalerWallet1/Views/Transactions/ManualDetailsV.swift | 135+++++++++++++++++++++++++++++++++----------------------------------------------
1 file changed, 56 insertions(+), 79 deletions(-)

diff --git a/TalerWallet1/Views/Transactions/ManualDetailsV.swift b/TalerWallet1/Views/Transactions/ManualDetailsV.swift @@ -30,16 +30,8 @@ struct ManualDetailsV: View { withAnimation { listID = UUID() } } } - func validDetails(_ details: [ExchangeAccountDetails]) -> [ExchangeAccountDetails] { - details.filter { detail in - detail.status.lowercased() == "ok" - } - } - @ViewBuilder func qrCodesRow(_ transferOptions: [TransferOption], - receiverStr: String, - amountStr: String, - messageStr: String?) -> some View { + @ViewBuilder func qrCodesRow(_ transferOptions: [TransferOption]) -> some View { let qrCodesForPayto = QRcodesForPayto(stack: stack.push(), transferOptions: transferOptions) NavigationLink(destination: qrCodesForPayto) { @@ -48,13 +40,14 @@ struct ManualDetailsV: View { .talerFont(.title3) } } + var body: some View { - if let accountDetails = details.exchangeCreditAccountDetails { - let validDetails = validDetails(accountDetails) - let validCount = validDetails.count - if validCount > 0 { - let account = validDetails[validIndex] - if let amount = account.transferAmount { + if let validDetails = details.validDetails { + let validCount = validDetails.count // guaranteed to be > 0 + let account = validDetails[validIndex] + let json = account.toJSON() + if account.transferAmount != nil { + if let transferOptions = account.transferOptions, let firstOption = transferOptions.first { let specs = account.currencySpecification let amountStr = common.amountRaw.formatted(specs: specs, isNegative: false) let amountValue = common.amountRaw.valueStr @@ -81,84 +74,68 @@ struct ManualDetailsV: View { } else if let bankName = account.bankLabel { Text(bankName + ": " + amountStr.0) .accessibilityLabel(bankName + ": " + amountStr.1) -// } else { -// Text(amountStr) + } else { + Text(amountStr.0) + .accessibilityLabel(amountStr.1) } - let payto = PayTo(account.paytoUri) - if let receiverStr = payto.receiver { - let wireDetails = ManualDetailsWireV(stack: stack.push(), - reservePub: details.reservePub, - payto: payto, - restrictions: account.creditRestrictions, - amountValue: amountValue, - amountStr: amountStr, - obtainStr: obtainStr, - debitIBAN: nil, // only for deposit auth + + let countA = transferOptions.count + let countB = firstOption.qrCodes?.count ?? 0 + + if let paytoUri = firstOption.paytoUri { + let payto = PayTo(paytoUri) + if let receiverStr = payto.receiver { + let wireDetails = ManualDetailsWireV(stack: stack.push(), + reservePub: details.reservePub, + payto: payto, + restrictions: account.creditRestrictions, + amountValue: amountValue, + amountStr: amountStr, + obtainStr: obtainStr, + debitIBAN: nil // only for deposit auth ) - Group { NavigationLink(destination: wireDetails) { Text(minimalistic ? "Instructions" : "Wire transfer instructions") .talerFont(.title3) } - if let transferOptions = account.transferOptions { - if let firstOption = transferOptions.first { - let countA = transferOptions.count - let countB = firstOption.qrCodes?.count ?? 0 + Group { if countA > 1 || countB > 1 { - qrCodesRow(transferOptions, - receiverStr: receiverStr, - amountStr: amountStr.0, - messageStr: payto.messageStr) + qrCodesRow(transferOptions) } else if countA > 0 { // show the single QR directly -// Text("If your banking software runs on another device, you can scan this QR code:") -// .listRowSeparator(.hidden) - if let qrCodeSpecs = firstOption.qrCodes { - if let qrCode = qrCodeSpecs.first { - let message = payto.messageStr ?? EMPTYSTRING - let textToShare = String(receiverStr + "\n" + amountStr.0 + "\n" + message) - QRcodeCopyShare(option: firstOption) - .listRowSeparator(.automatic) - } - } + Text("If your banking software runs on another device, you can scan this QR code:") + .listRowSeparator(.hidden) + QRcodeCopyShare(option: firstOption) + .listRowSeparator(.automatic) } - } - } + }.id(listID) + .talerFont(.body) #if DEBUG - if developerMode { - if let iban = payto.iban { - Text(minimalistic ? "**Alternative:** Use this PayTo-Link:" - : "**Alternative:** If your bank already supports PayTo, you can use this PayTo-Link instead:") - .multilineTextAlignment(.leading) - .padding(.top) - .listRowSeparator(.hidden) - let title = String(localized: "Share the PayTo URL", comment: "a11y") - let minTitle = String(localized: "Share PayTo", comment: "mini") - let textToShare = String("\(payto)\n\nIBAN: \(iban)\nReceiver: \(receiverStr)\nAmount: \(amountStr.1)\nSubject: \(details.reservePub)") + if developerMode { + if let iban = payto.iban { + Text(minimalistic ? "**Alternative:** Use this PayTo-Link:" + : "**Alternative:** If your bank already supports PayTo, you can use this PayTo-Link instead:") + .multilineTextAlignment(.leading) + .padding(.top) + .listRowSeparator(.hidden) + let title = String(localized: "Share the PayTo URL", comment: "a11y") + let minTitle = String(localized: "Share PayTo", comment: "mini") + let textToShare = String("\(payto)\n\nIBAN: \(iban)\nReceiver: \(receiverStr)\nAmount: \(amountStr.1)\nSubject: \(details.reservePub)") let _ = print(textToShare) - ShareButton(textToShare, title: minimalistic ? minTitle : title) - .frame(maxWidth: .infinity, alignment: .center) - .accessibilityLabel(Text(title)) - .disabled(false) - .listRowSeparator(.hidden) + ShareButton(textToShare, title: minimalistic ? minTitle : title) + .frame(maxWidth: .infinity, alignment: .center) + .accessibilityLabel(Text(title)) + .disabled(false) + .listRowSeparator(.hidden) + } } - } #endif - }.id(listID) - .talerFont(.body) - } else { - // TODO: Error No payto URL - } - } else { - // TODO: Error No amount - } - } else { - // TODO: Error none of the details is valid - } - } else { - // TODO: Error No exchangeCreditAccountDetails - } + } else { ErrorView(stack.push(), title: "No receiver", message: json, copyable: true) } + } else { ErrorView(stack.push(), title: "No payto URL", message: json, copyable: true) } + } else { ErrorView(stack.push(), title: "No transfer options", message: json, copyable: true) } + } else { ErrorView(stack.push(), title: "No amount", message: json, copyable: true) } + } else { ErrorView(stack.push(), title: "Payment Error", message: "No valid details") } } } // MARK: - @@ -173,7 +150,7 @@ struct ManualDetails_Previews: PreviewProvider { txActions: [], amountRaw: Amount(currency: LONGCURRENCY, cent: 220), amountEffective: Amount(currency: LONGCURRENCY, cent: 110)) - let payto = "payto://iban/SANDBOXX/DE159593?receiver-name=Exchange+Company" +// let payto = "payto://iban/SANDBOXX/DE159593?receiver-name=Exchange+Company" let details = WithdrawalDetails(type: .manual, reservePub: "ReSeRvEpUbLiC_KeY_FoR_WiThDrAwAl", reserveIsReady: false,