taler-ios

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

commit d2e7c9b5017e9a200b125eb631aa15faa6859122
parent f9d124168e833866d3a094b298ff1b095893fdb2
Author: Marc Stibane <marc@taler.net>
Date:   Sun, 14 Jul 2024 18:45:41 +0200

Done-button in safeAreaInset

Diffstat:
MTalerWallet1/Views/Banking/ManualWithdrawDone.swift | 15++++++++++-----
MTalerWallet1/Views/Peer2peer/P2PReadyV.swift | 12++++++++++--
MTalerWallet1/Views/Sheets/Payment/PaymentDone.swift | 15++++++++++-----
MTalerWallet1/Views/Sheets/Refund/RefundURIView.swift | 12++++++++++--
MTalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift | 27++++++++++++++++++++-------
MTalerWallet1/Views/Transactions/TransactionSummaryV.swift | 33++++++++++++++-------------------
MTalerWallet1/Views/Transactions/TransactionsListView.swift | 7+++++--
7 files changed, 79 insertions(+), 42 deletions(-)

diff --git a/TalerWallet1/Views/Banking/ManualWithdrawDone.swift b/TalerWallet1/Views/Banking/ManualWithdrawDone.swift @@ -1,7 +1,10 @@ /* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * 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 @@ -23,9 +26,6 @@ struct ManualWithdrawDone: View { func reloadOneAction(_ transactionId: String, viewHandles: Bool) async throws -> Transaction { return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) } - func dismissTopAnimated(_ stack: CallStack) { - dismissTop(stack.push()) - } var body: some View { #if PRINT_CHANGES @@ -38,7 +38,7 @@ struct ManualWithdrawDone: View { transactionId: transactionId, reloadAction: reloadOneAction, navTitle: navTitle, - doneAction: dismissTopAnimated, // ViewState.shared.popToRootView, + hasDone: true, abortAction: nil, deleteAction: nil, failAction: nil, @@ -47,6 +47,11 @@ struct ManualWithdrawDone: View { .navigationBarBackButtonHidden(true) .interactiveDismissDisabled() // can only use "Done" button to dismiss // .navigationTitle(navTitle) + .safeAreaInset(edge: .bottom) { + Button("Done", action: { dismissTop(stack.push()) } ) // ViewState.shared.popToRootView ? + .buttonStyle(TalerButtonStyle(type: .prominent)) + .padding(.horizontal) + } } else { LoadingView(scopeInfo: nil, message: exchange.exchangeBaseUrl.trimURL()) } diff --git a/TalerWallet1/Views/Peer2peer/P2PReadyV.swift b/TalerWallet1/Views/Peer2peer/P2PReadyV.swift @@ -1,7 +1,10 @@ /* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * 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 @@ -42,7 +45,7 @@ struct P2PReadyV: View { transactionId: transactionId, reloadAction: reloadOneAction, navTitle: navTitle, - doneAction: ViewState.shared.popToRootView, + hasDone: true, abortAction: nil, deleteAction: nil, failAction: nil, @@ -50,6 +53,11 @@ struct P2PReadyV: View { resumeAction: nil) .navigationBarBackButtonHidden(true) .interactiveDismissDisabled() // can only use "Done" button to dismiss + .safeAreaInset(edge: .bottom) { + Button("Done", action: { dismissTop(stack.push()) } ) // ViewState.shared.popToRootView ? + .buttonStyle(TalerButtonStyle(type: .prominent)) + .padding(.horizontal) + } } else { #if DEBUG let message = amountToTransfer.currencyStr diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentDone.swift b/TalerWallet1/Views/Sheets/Payment/PaymentDone.swift @@ -1,7 +1,10 @@ /* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * This file is part of GNU Taler, ©2022-24 Taler Systems S.A. * See LICENSE.md */ +/** + * @author Marc Stibane + */ import SwiftUI import SymLog @@ -18,9 +21,6 @@ struct PaymentDone: View { func reloadOneAction(_ transactionId: String, viewHandles: Bool) async throws -> Transaction { return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) } - func dismissTopAnimated(_ stack: CallStack) { - dismissTop(stack.push()) - } var body: some View { #if PRINT_CHANGES @@ -34,7 +34,7 @@ struct PaymentDone: View { transactionId: transactionId, reloadAction: reloadOneAction, navTitle: navTitle, - doneAction: dismissTopAnimated, + hasDone: true, abortAction: nil, deleteAction: nil, failAction: nil, @@ -43,6 +43,11 @@ struct PaymentDone: View { .navigationBarBackButtonHidden(true) .interactiveDismissDisabled() // can only use "Done" button to dismiss .navigationTitle(navTitle) + .safeAreaInset(edge: .bottom) { + Button("Done", action: { dismissTop(stack.push()) } ) + .buttonStyle(TalerButtonStyle(type: .prominent)) + .padding(.horizontal) + } } else { LoadingView(scopeInfo: nil, message: "Paying...") .task { diff --git a/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift b/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift @@ -1,7 +1,10 @@ /* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * This file is part of GNU Taler, ©2022-24 Taler Systems S.A. * See LICENSE.md */ +/** + * @author Marc Stibane + */ import SwiftUI import SymLog import taler_swift @@ -27,12 +30,17 @@ struct RefundURIView: View { transactionId: refundTransactionId, reloadAction: reloadOneAction, navTitle: nil, // navTitle, - doneAction: ViewState.shared.popToRootView, + hasDone: true, abortAction: model.abortTransaction, deleteAction: model.deleteTransaction, failAction: model.failTransaction, suspendAction: model.suspendTransaction, resumeAction: model.resumeTransaction) + .safeAreaInset(edge: .bottom) { + Button("Done", action: { dismissTop(stack.push()) } ) // ViewState.shared.popToRootView ? + .buttonStyle(TalerButtonStyle(type: .prominent)) + .padding(.horizontal) + } } else { LoadingView(scopeInfo: nil, message: url.host) .task { diff --git a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift @@ -1,7 +1,10 @@ /* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * 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 @@ -19,13 +22,12 @@ struct WithdrawAcceptDone: View { @EnvironmentObject private var model: WalletModel @State private var transactionId: String? = nil + @State private var transaction: Transaction? = nil func reloadOneAction(_ transactionId: String, viewHandles: Bool) async throws -> Transaction { - return try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) - } - func dismissTopAnimated(_ stack: CallStack) { - symLog.log("ErrorSheet dismissTop") - dismissTop(stack.push()) + let response = try await model.getTransactionByIdT(transactionId, viewHandles: viewHandles) + transaction = response + return response } var body: some View { @@ -39,7 +41,7 @@ struct WithdrawAcceptDone: View { transactionId: transactionId, reloadAction: reloadOneAction, navTitle: navTitle, - doneAction: dismissTopAnimated, + hasDone: true, abortAction: nil, deleteAction: nil, failAction: nil, @@ -48,6 +50,17 @@ struct WithdrawAcceptDone: View { .navigationBarBackButtonHidden(true) .interactiveDismissDisabled() // can only use "Done" button to dismiss .navigationTitle(navTitle) + .safeAreaInset(edge: .bottom) { + if let transaction { + Button(transaction.shouldConfirm ? "Authorize later" : "Done", action: { dismissTop(stack.push()) } ) + .buttonStyle(TalerButtonStyle(type: transaction.shouldConfirm ? .bordered : .prominent)) + .padding(.horizontal) + } else { + Button("Cancel", action: { dismissTop(stack.push()) } ) + .buttonStyle(TalerButtonStyle(type: .bordered)) + .padding(.horizontal) + } + } } else { LoadingView(scopeInfo: nil, message: exchangeBaseUrl?.trimURL() ?? "Bank Authorization") diff --git a/TalerWallet1/Views/Transactions/TransactionSummaryV.swift b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift @@ -30,7 +30,7 @@ struct TransactionSummaryV: View { let transactionId: String let reloadAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Transaction) let navTitle: String? - let doneAction: ((_ stack: CallStack) -> Void)? + let hasDone: Bool let abortAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Void)? let deleteAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Void)? let failAction: ((_ transactionId: String, _ viewHandles: Bool) async throws -> Void)? @@ -58,13 +58,14 @@ struct TransactionSummaryV: View { } } + @MainActor @discardableResult func checkDismiss(_ notification: Notification, _ logStr: String = "") -> Bool { - if let doneAction { + if hasDone { if let transition = notification.userInfo?[TRANSACTIONTRANSITION] as? TransactionTransition { if transition.transactionId == transaction.common.transactionId { // is the transition for THIS transaction? symLog.log(logStr) - doneAction(stack.push()) // if this view is in a sheet then dissmiss the sheet + dismissTop(stack.push()) // if this view is in a sheet then dissmiss the sheet return true } } @@ -115,12 +116,11 @@ struct TransactionSummaryV: View { command: .resume, warning: nil, action: resumeAction) } } } // Suspend + Resume buttons - Text(dateString) - .talerFont(.body) - .accessibilityLabel(a11yDate) - .foregroundColor(WalletColors().secondary(colorScheme, colorSchemeContrast)) - .listRowSeparator(.hidden) - VStack(alignment: .trailing) { + Group { + Text(dateString) + .talerFont(.body) + .accessibilityLabel(a11yDate) + .foregroundColor(WalletColors().secondary(colorScheme, colorSchemeContrast)) let majorState = common.txState.major.localizedState let minorState = common.txState.minor?.localizedState ?? nil let state = developerMode ? transaction.isPending ? minorState ?? majorState @@ -128,18 +128,17 @@ struct TransactionSummaryV: View { : majorState HStack { Text(Image(common.type.iconName())) -// Text(verbatim: "|") // only reason for this leading-aligned text is to get a nice full length listRowSeparator .accessibilityHidden(true) -// .foregroundColor(Color.clear) -// Spacer() + Spacer() Text("Status: \(state)") .frame(maxWidth: .infinity, alignment: .trailing) .multilineTextAlignment(.trailing) - } - } .listRowSeparator(.automatic) + } // Icon + State + } .listRowSeparator(.hidden) .talerFont(.title) TypeDetail(stack: stack.push(), - transaction: $transaction, hasDone: doneAction != nil) + transaction: $transaction, + hasDone: hasDone) // TODO: Retry Countdown, Retry Now button // if transaction.isRetryable { if let retryAction { @@ -161,10 +160,6 @@ struct TransactionSummaryV: View { warning: String(localized: "Are you sure you want to delete this transaction?"), action: deleteAction) } } // Delete button - if let doneAction { - Button(transaction.shouldConfirm ? "Authorize later" : "Done", action: { doneAction(stack.push()) } ) - .buttonStyle(TalerButtonStyle(type: transaction.shouldConfirm ? .bordered : .prominent)) - } // Done button }.id(viewId) // change viewId to enforce a draw update .listStyle(myListStyle.style).anyView } // Group diff --git a/TalerWallet1/Views/Transactions/TransactionsListView.swift b/TalerWallet1/Views/Transactions/TransactionsListView.swift @@ -1,7 +1,10 @@ /* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * This file is part of GNU Taler, ©2022-24 Taler Systems S.A. * See LICENSE.md */ +/** + * @author Marc Stibane + */ import SwiftUI import SymLog @@ -102,7 +105,7 @@ struct TransactionsArraySliceV: View { transactionId: transaction.id, reloadAction: reloadOneAction, navTitle: nil, - doneAction: nil, + hasDone: false, abortAction: abortAction, deleteAction: deleteAction, failAction: failAction,