taler-ios

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

commit 0566952e5201aa0020cb8850ca58783ef03c3940
parent e76444e9537639e864284a300d15d55cf22b312a
Author: Marc Stibane <marc@taler.net>
Date:   Sat, 28 Sep 2024 22:07:56 +0200

Actions

Diffstat:
MTalerWallet.xcodeproj/project.pbxproj | 4++--
ATalerWallet1/Views/Actions/DepositWithdrawV.swift | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ATalerWallet1/Views/Actions/SendRequestV.swift | 120+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MTalerWallet1/Views/Balances/BalancesSectionView.swift | 22+++++++++++-----------
DTalerWallet1/Views/Balances/SendRequestV.swift | 138-------------------------------------------------------------------------------
DTalerWallet1/Views/Banking/DepositWithdrawV.swift | 106-------------------------------------------------------------------------------
MTalerWallet1/Views/Banking/ExchangeRowView.swift | 8++++----
7 files changed, 226 insertions(+), 261 deletions(-)

diff --git a/TalerWallet.xcodeproj/project.pbxproj b/TalerWallet.xcodeproj/project.pbxproj @@ -765,7 +765,6 @@ 4EB095292989CBFE0043A8A1 /* ExchangeListView.swift */, 4EC90C772A1B528B0071DC58 /* ExchangeSectionView.swift */, 4EC4008E2AE8019700DF72C7 /* ExchangeRowView.swift */, - 4EA076B22BC0607400685A10 /* DepositWithdrawV.swift */, 4EBC0F002B7B3CD600C0CB19 /* DepositIbanV.swift */, 4E96583B2B79656E00404A68 /* DepositAmountV.swift */, 4E50B34F2A1BEE8000F9F01C /* ManualWithdraw.swift */, @@ -808,7 +807,6 @@ 4EB0953A2989CBFE0043A8A1 /* BalancesSectionView.swift */, 4E77976E2C4BEA4E005D6ECB /* BalanceCellV.swift */, 4E448AB62C4A4109007D5C92 /* BalancesPendingRowV.swift */, - 4EB095362989CBFE0043A8A1 /* SendRequestV.swift */, 4EB065432A4CD1A80039B91D /* TwoRowButtons.swift */, 4EB095382989CBFE0043A8A1 /* PendingRowView.swift */, ); @@ -882,6 +880,8 @@ isa = PBXGroup; children = ( 4E2B337C2C8B1D5500186A3E /* ActionsSheet.swift */, + 4EB095362989CBFE0043A8A1 /* SendRequestV.swift */, + 4EA076B22BC0607400685A10 /* DepositWithdrawV.swift */, ); path = Actions; sourceTree = "<group>"; diff --git a/TalerWallet1/Views/Actions/DepositWithdrawV.swift b/TalerWallet1/Views/Actions/DepositWithdrawV.swift @@ -0,0 +1,89 @@ +/* + * This file is part of GNU Taler, ©2022-24 Taler Systems S.A. + * See LICENSE.md + */ +/** + * @author Marc Stibane + */ +import SwiftUI +import taler_swift +import SymLog + +struct DepositWithdrawV: View { + private let symLog = SymLogV(0) + let stack: CallStack + @Binding var balances: [Balance] +// @Binding var currencyInfo: CurrencyInfo +// let amountAvailable: Amount? +// let currency: String // this is the currency to be used + @Binding var amountToTransfer: Amount // does still have the wrong currency + + @EnvironmentObject private var model: WalletModel + @AppStorage("minimalistic") var minimalistic: Bool = false + @State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN) + @State private var currencyName: String = UNKNOWN + @State private var currencySymbol: String = UNKNOWN + @State private var amountAvailable = Amount.zero(currency: EMPTYSTRING) // Update currency when used + + func selectAndUpdate(_ button: Int) { + let scope = currencyInfo.scope + let currency = scope.currency + amountToTransfer.setCurrency(currency) + dismissTop(stack.push()) + NotificationCenter.default.post(name: button == 3 ? .DepositAction : .WithdrawAction, + object: nil) // will trigger NavigationLink + // after user tapped a button, while navigation animation runs, contact Exchange to update Fees + if let url = scope.url { + Task { // runs on MainActor + do { + // TODO: try await model.updateExchange(scopeInfo: scope) + try await model.updateExchange(exchangeBaseUrl: url) + } catch { // TODO: error handling - couldn't updateExchange + symLog.log("error: \(error)") + } + } + } + } + + private var canDeposit: Bool { + for balance in balances { + if !balance.available.isZero { + return true + } + } + return false + } + + var body: some View { + let scope = currencyInfo.scope + let currencyName = currencyInfo.specs.name + let depositTitle = String(localized: "DepositButton_Short", defaultValue: "Deposit", + comment: "Abbreviation of button `Deposit (currency)´") + let withdrawTitle = String(localized: "WithdrawButton_Short", defaultValue: "Withdraw", + comment: "Abbreviation of button `Withdraw (currency)´") + let twoRowButtons = TwoRowButtons(stack: stack.push(), + sendTitle: depositTitle, + sendType: .deposit, + sendA11y: depositTitle,//1.tabbed(oneLine: true), + recvTitle: withdrawTitle, + recvType: .withdrawal, + recvA11y: withdrawTitle,//1.tabbed(oneLine: true), + fitsSideBySide: false, + lineLimit: 5, + sendDisabled: !canDeposit, + sendAction: { selectAndUpdate(3) }, + recvAction: { selectAndUpdate(4) }) + Group { + if #available(iOS 16.0, *) { + ViewThatFits(in: .horizontal) { + HStack(spacing: HSPACING) { + twoRowButtons.makeCopy(fitsSideBySide: true) + } + VStack { twoRowButtons } + } + } else { // view for iOS 15 + VStack { twoRowButtons } + } + } + } +} diff --git a/TalerWallet1/Views/Actions/SendRequestV.swift b/TalerWallet1/Views/Actions/SendRequestV.swift @@ -0,0 +1,120 @@ +/* + * This file is part of GNU Taler, ©2022-24 Taler Systems S.A. + * See LICENSE.md + */ +/** + * @author Marc Stibane + */ +import SwiftUI +import taler_swift +import SymLog + +struct SendRequestV: View { + private let symLog = SymLogV(0) + let stack: CallStack + @Binding var balances: [Balance] +// @Binding var currencyInfo: CurrencyInfo +// let amountAvailable: Amount + // let currency: String // this is the currency to be used + @Binding var amountToTransfer: Amount // does still have the wrong currency + @Binding var summary: String + let cameraAction: () -> Void + + @EnvironmentObject private var model: WalletModel + @EnvironmentObject private var controller: Controller + @AppStorage("minimalistic") var minimalistic: Bool = false + @State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN) + @State private var currencyName: String = UNKNOWN + @State private var currencySymbol: String = UNKNOWN + @State private var amountAvailable = Amount.zero(currency: EMPTYSTRING) // Update currency when used + + func selectAndUpdate(_ button: Int) { + let scope = currencyInfo.scope + let currency = scope.currency + amountToTransfer.setCurrency(currency) + dismissTop(stack.push()) + NotificationCenter.default.post(name: button == 1 ? .SendAction : .RequestAction, + object: nil) // will trigger NavigationLink + // after user tapped a button, while navigation animation runs, contact Exchange to update Fees + if let url = scope.url { + Task { // runs on MainActor + do { + // TODO: try await model.updateExchange(scopeInfo: scope) + try await model.updateExchange(exchangeBaseUrl: url) + } catch { // TODO: error handling - couldn't updateExchange + symLog.log("error: \(error)") + } + } + } + } + + private var canSend: Bool { + for balance in balances { + if !balance.available.isZero { + return true + } + } + return false + } + + var body: some View { + let scope = currencyInfo.scope + let currencyName = currencyInfo.specs.name + let sendTitle = String(localized: "SendButton_Short", defaultValue: "Send", + comment: "Abbreviation of button `Send (currency)´") + let requTitle = String(localized: "RequestButton_Short", defaultValue: "Request", + comment: "Abbreviation of button `Request (currency)´") + let twoRowButtons = TwoRowButtons(stack: stack.push(), + sendTitle: sendTitle, + sendType: .peerPushDebit, + sendA11y: sendTitle,//1.tabbed(oneLine: true), + recvTitle: requTitle, + recvType: .peerPullCredit, + recvA11y: requTitle,//1.tabbed(oneLine: true), + fitsSideBySide: false, + lineLimit: 5, + sendDisabled: !canSend, + sendAction: { controller.frontendState = -1; selectAndUpdate(1) }, + recvAction: { controller.frontendState = 1; selectAndUpdate(2) }) + Group { + if #available(iOS 16.0, *) { + ViewThatFits(in: .horizontal) { + HStack(spacing: HSPACING) { + twoRowButtons.makeCopy(fitsSideBySide: true) + } +// .border(.red) + VStack { twoRowButtons } +// .border(.red) + } + } else { // view for iOS 15 + VStack { twoRowButtons } + } + } + } +} +// MARK: - +#if false +struct SendRequestV_Previews: PreviewProvider { + @MainActor + struct StateContainer: View { + var body: some View { + let test = Amount(currency: TESTCURRENCY, cent: 123) + let demo = Amount(currency: DEMOCURRENCY, cent: 123456) + + List { + Section { + SendRequestV(stack: CallStack("Preview"), currencyName: DEMOCURRENCY, amount: demo, + sendAction: {}, recvAction: {}, rowAction: {}, balanceDest: nil) + } + SendRequestV(stack: CallStack("Preview"), currencyName: TESTCURRENCY, amount: test, + sendAction: {}, recvAction: {}, rowAction: {}, balanceDest: nil) + } + } + } + + static var previews: some View { + StateContainer() +// .environment(\.sizeCategory, .extraExtraLarge) Canvas Device Settings + } +} +#endif diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift b/TalerWallet1/Views/Balances/BalancesSectionView.swift @@ -129,12 +129,12 @@ extension BalancesSectionView: View { // .listRowSeparator(.hidden) // .border(.red) - SendRequestV(stack: stack.push(), - currencyInfo: $currencyInfo, - amountAvailable: balance.available, - amountToTransfer: $amountToTransfer, - summary: $summary, - cameraAction: cameraAction) +// SendRequestV(stack: stack.push(), +// currencyInfo: $currencyInfo, +// amountAvailable: balance.available, +// amountToTransfer: $amountToTransfer, +// summary: $summary, +// cameraAction: cameraAction) // .listRowSeparator(.hidden) // BalancesNavigationLinksV(symLog: symLog, @@ -183,11 +183,11 @@ extension BalancesSectionView: View { .accessibilityHint(String(localized: "Will go to the demo shop website.")) .listRowSeparator(.hidden) } - DepositWithdrawV(stack: stack.push(), - currencyInfo: $currencyInfo, -// scopeInfo: balance.scopeInfo, - amountAvailable: balance.available, - amountToTransfer: $amountToTransfer) // does still have the wrong currency +// DepositWithdrawV(stack: stack.push(), +// currencyInfo: $currencyInfo, +//// scopeInfo: balance.scopeInfo, +// amountAvailable: balance.available, +// amountToTransfer: $amountToTransfer) // does still have the wrong currency } header: { BarGraphHeader(stack: stack.push(), diff --git a/TalerWallet1/Views/Balances/SendRequestV.swift b/TalerWallet1/Views/Balances/SendRequestV.swift @@ -1,138 +0,0 @@ -/* - * This file is part of GNU Taler, ©2022-24 Taler Systems S.A. - * See LICENSE.md - */ -/** - * @author Marc Stibane - */ -import SwiftUI -import taler_swift -import SymLog - -struct SendRequestV: View { - private let symLog = SymLogV(0) - let stack: CallStack - @Binding var currencyInfo: CurrencyInfo - let amountAvailable: Amount - // let currency: String // this is the currency to be used - @Binding var amountToTransfer: Amount // does still have the wrong currency - @Binding var summary: String - let cameraAction: () -> Void - - @EnvironmentObject private var model: WalletModel - @EnvironmentObject private var controller: Controller - @AppStorage("minimalistic") var minimalistic: Bool = false - @State private var buttonSelected: Int? = nil - - func selectAndUpdate(_ button: Int) { - let scope = currencyInfo.scope - let currency = scope.currency - amountToTransfer.setCurrency(currency) - buttonSelected = button // will trigger NavigationLink - // after user tapped a button, while navigation animation runs, contact Exchange to update Fees - if let url = scope.url { - Task { // runs on MainActor - do { - // TODO: try await model.updateExchange(scopeInfo: scope) - try await model.updateExchange(exchangeBaseUrl: url) - } catch { // TODO: error handling - couldn't updateExchange - symLog.log("error: \(error)") - } - } - } - } - - private static func className() -> String {"\(self)"} - - var body: some View { - let scope = currencyInfo.scope - let currencyName = currencyInfo.specs.name - let sendTitle0 = String(localized: "SendButton_Short", defaultValue: "Send", - comment: "Abbreviation of button `Send (currency)´") - let sendTitle1 = String(localized: "SendButton_Full", defaultValue: "Send\t\(currencyName)", - comment: "`Send (currency)´ in Balances - must have ONE \\t and ONE %@") - let sendTitle = minimalistic ? sendTitle0 : sendTitle1 - - let requTitle0 = String(localized: "RequestButton_Short", defaultValue: "Request", - comment: "Abbreviation of button `Request (currency)´") - let requTitle1 = String(localized: "RequestButton_Full", defaultValue: "Request\t\(currencyName)", - comment: "`Request (currency)´ in Balances - must have ONE \\t and ONE %@") - let requTitle = minimalistic ? requTitle0 : requTitle1 - let sendDest = LazyView { - SendAmount(stack: stack.push("\(Self.className())()"), - currencyInfo: $currencyInfo, - available: amountAvailable, - amountToTransfer: $amountToTransfer, // with correct currency - summary: $summary, - scopeInfo: scope, - cameraAction: cameraAction) - } - let requestDest = LazyView { - RequestPayment(stack: stack.push("\(Self.className())()"), - currencyInfo: $currencyInfo, - amountToTransfer: $amountToTransfer, // with correct currency - summary: $summary, - scopeInfo: scope, - cameraAction: cameraAction) - } - let disableSend = amountAvailable.isZero //?? false - let twoRowButtons = TwoRowButtons(stack: stack.push(), - sendTitle: sendTitle, - sendType: .peerPushDebit, - sendA11y: sendTitle1.tabbed(oneLine: true), - recvTitle: requTitle, - recvType: .peerPullCredit, - recvA11y: requTitle1.tabbed(oneLine: true), - fitsSideBySide: false, - lineLimit: 5, - sendDisabled: disableSend, - sendAction: { controller.frontendState = -1; selectAndUpdate(1) }, - recvAction: { controller.frontendState = 1; selectAndUpdate(2) }) - Group { - if #available(iOS 16.0, *) { - ViewThatFits(in: .horizontal) { - HStack(spacing: HSPACING) { - twoRowButtons.makeCopy(fitsSideBySide: true) - } -// .border(.red) - VStack { twoRowButtons } -// .border(.red) - } - } else { // view for iOS 15 - VStack { twoRowButtons } - } - } - .background( Group { - NavigationLink(destination: sendDest, tag: 1, selection: $buttonSelected) - { EmptyView() }.frame(width: 0).opacity(0).hidden() - NavigationLink(destination: requestDest, tag: 2, selection: $buttonSelected) - { EmptyView() }.frame(width: 0).opacity(0).hidden() - }) - } -} -// MARK: - -#if false -struct SendRequestV_Previews: PreviewProvider { - @MainActor - struct StateContainer: View { - var body: some View { - let test = Amount(currency: TESTCURRENCY, cent: 123) - let demo = Amount(currency: DEMOCURRENCY, cent: 123456) - - List { - Section { - SendRequestV(stack: CallStack("Preview"), currencyName: DEMOCURRENCY, amount: demo, - sendAction: {}, recvAction: {}, rowAction: {}, balanceDest: nil) - } - SendRequestV(stack: CallStack("Preview"), currencyName: TESTCURRENCY, amount: test, - sendAction: {}, recvAction: {}, rowAction: {}, balanceDest: nil) - } - } - } - - static var previews: some View { - StateContainer() -// .environment(\.sizeCategory, .extraExtraLarge) Canvas Device Settings - } -} -#endif diff --git a/TalerWallet1/Views/Banking/DepositWithdrawV.swift b/TalerWallet1/Views/Banking/DepositWithdrawV.swift @@ -1,106 +0,0 @@ -/* - * This file is part of GNU Taler, ©2022-24 Taler Systems S.A. - * See LICENSE.md - */ -/** - * @author Marc Stibane - */ -import SwiftUI -import taler_swift -import SymLog - -struct DepositWithdrawV: View { - private let symLog = SymLogV(0) - let stack: CallStack - @Binding var currencyInfo: CurrencyInfo - let amountAvailable: Amount? -// let currency: String // this is the currency to be used - @Binding var amountToTransfer: Amount // does still have the wrong currency - - @EnvironmentObject private var model: WalletModel - @AppStorage("minimalistic") var minimalistic: Bool = false - @State private var buttonSelected: Int? = nil - @State private var myExchange: Exchange? = nil - - func selectAndUpdate(_ button: Int) { - let scope = currencyInfo.scope - let currency = scope.currency - amountToTransfer.setCurrency(currency) - buttonSelected = button // will trigger NavigationLink - // after user tapped a button, while navigation animation runs, contact Exchange to update Fees - if let url = scope.url { - Task { // runs on MainActor - do { - // TODO: try await model.updateExchange(scopeInfo: scope) - try await model.updateExchange(exchangeBaseUrl: url) - } catch { // TODO: error handling - couldn't updateExchange - symLog.log("error: \(error)") - } - } - } - } - - var body: some View { - let scope = currencyInfo.scope - let currencyName = currencyInfo.specs.name - let depositTitle0 = String(localized: "DepositButton_Short", defaultValue: "Deposit", - comment: "Abbreviation of button `Deposit (currency)´") - let depositTitle1 = String(localized: "Deposit\t\(currencyName)", - comment: "Button `Deposit (currency)´, must have ONE \\t and ONE %@") - let depositTitle = minimalistic ? depositTitle0 : depositTitle1 - let withdrawTitle0 = String(localized: "WithdrawButton_Short", defaultValue: "Withdraw", - comment: "Abbreviation of button `Withdraw (currency)´") - let withdrawTitle1 = String(localized: "Withdraw\t\(currencyName)", - comment: "Button `Withdraw (currency)´, must have ONE \\t and ONE %@") - let withdrawTitle = minimalistic ? withdrawTitle0 : withdrawTitle1 - let depositDest = LazyView { - DepositIbanV(stack: stack.push(), - currencyInfo: $currencyInfo, - feeLabel: nil, - feeIsNotZero: nil, - amountAvailable: amountAvailable, -// depositIBAN: $depositIBAN, -// accountHolder: $accountHolder, - amountToTransfer: $amountToTransfer) - } - let manualWithdrawDest = LazyView { - ManualWithdraw(stack: stack.push(), - currencyInfo: $currencyInfo, - isSheet: false, - scopeInfo: scope, - exchange: $myExchange, - amountToTransfer: $amountToTransfer) - } - let disableDeposit = amountAvailable?.isZero ?? false - let twoRowButtons = TwoRowButtons(stack: stack.push(), - sendTitle: depositTitle, - sendType: .deposit, - sendA11y: depositTitle1.tabbed(oneLine: true), - recvTitle: withdrawTitle, - recvType: .withdrawal, - recvA11y: withdrawTitle1.tabbed(oneLine: true), - fitsSideBySide: false, - lineLimit: 5, - sendDisabled: disableDeposit, - sendAction: { selectAndUpdate(1) }, - recvAction: { selectAndUpdate(2) }) - Group { - if #available(iOS 16.0, *) { - ViewThatFits(in: .horizontal) { - HStack(spacing: HSPACING) { - twoRowButtons.makeCopy(fitsSideBySide: true) - } - VStack { twoRowButtons } - } - } else { // view for iOS 15 - VStack { twoRowButtons } - } - } - .background( Group { - NavigationLink(destination: depositDest, tag: 1, selection: $buttonSelected) - { EmptyView() }.frame(width: 0).opacity(0).hidden() - NavigationLink(destination: manualWithdrawDest, tag: 2, selection: $buttonSelected) - { EmptyView() }.frame(width: 0).opacity(0).hidden() - }) - } -} diff --git a/TalerWallet1/Views/Banking/ExchangeRowView.swift b/TalerWallet1/Views/Banking/ExchangeRowView.swift @@ -53,11 +53,11 @@ struct ExchangeRowView: View { } .listRowSeparator(.hidden) - DepositWithdrawV(stack: stack.push(), - currencyInfo: $currencyInfo, +// DepositWithdrawV(stack: stack.push(), +// currencyInfo: $currencyInfo, // scopeInfo: exchange.scopeInfo, - amountAvailable: amountAvailable, - amountToTransfer: $amountToTransfer) +// amountAvailable: amountAvailable, +// amountToTransfer: $amountToTransfer) } .task { if controller.info(for: currency) == nil {