commit 416553aa0079b6d40bc2b67bb41e6dc410218f70
parent 4b12e4a8b1cc48f99362aab1b87fc7b5c8219341
Author: Marc Stibane <marc@taler.net>
Date: Wed, 28 Aug 2024 00:06:24 +0200
deleteExchange
Diffstat:
4 files changed, 133 insertions(+), 36 deletions(-)
diff --git a/TalerWallet1/Localizable.xcstrings b/TalerWallet1/Localizable.xcstrings
@@ -1348,6 +1348,16 @@
}
}
},
+ "Are you sure you want to delete this payment provider?" : {
+ "localizations" : {
+ "de" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Sind Sie sicher, dass Sie diesen Zahlungsdienst löschen wollen?"
+ }
+ }
+ }
+ },
"Are you sure you want to delete this transaction?" : {
"localizations" : {
"de" : {
@@ -2832,6 +2842,24 @@
}
}
},
+ "Exchange.Delete" : {
+ "comment" : "Action button",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "de" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Zahlungsdienst löschen"
+ }
+ },
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "Delete Payment Provider"
+ }
+ }
+ }
+ },
"Expires in:" : {
"localizations" : {
"de" : {
diff --git a/TalerWallet1/Model/Model+Exchange.swift b/TalerWallet1/Model/Model+Exchange.swift
@@ -161,6 +161,21 @@ fileprivate struct AddExchange: WalletBackendFormattedRequest {
}
}
+/// A request to delete an exchange.
+fileprivate struct DeleteExchange: WalletBackendFormattedRequest {
+ struct Response: Decodable {} // no result - getting no error back means success
+ func operation() -> String { "deleteExchange" }
+ func args() -> Args { Args(exchangeBaseUrl: exchangeBaseUrl, purge: purge) }
+
+ var exchangeBaseUrl: String
+ var purge: Bool
+
+ struct Args: Encodable {
+ var exchangeBaseUrl: String
+ var purge: Bool
+ }
+}
+
/// A request to get info about a currency
fileprivate struct GetCurrencySpecification: WalletBackendFormattedRequest {
struct Response: Codable, Sendable {
@@ -214,6 +229,14 @@ extension WalletModel {
_ = try await sendRequest(request, viewHandles: viewHandles)
}
+ /// add a new exchange with URL to the wallet's list of known exchanges
+ func deleteExchange(url: String, purge: Bool = false, viewHandles: Bool = false)
+ async throws {
+ let request = DeleteExchange(exchangeBaseUrl: url, purge: purge)
+ logger.info("deleting exchange: \(url, privacy: .public)")
+ _ = try await sendRequest(request, viewHandles: viewHandles)
+ }
+
/// ask wallet-core to update an existing exchange by querying it for denominations, fees, and scoped currency info
// func updateExchange(scopeInfo: ScopeInfo)
// func updateExchange(scopeInfo: ScopeInfo, viewHandles: Bool = false)
diff --git a/TalerWallet1/Views/Banking/ExchangeSectionView.swift b/TalerWallet1/Views/Banking/ExchangeSectionView.swift
@@ -16,6 +16,7 @@ struct ExchangeSectionView: View {
// @Binding var depositIBAN: String
// @Binding var accountHolder: String
@Binding var amountToTransfer: Amount // does still have the wrong currency
+ @EnvironmentObject private var model: WalletModel
@EnvironmentObject private var controller: Controller
@AppStorage("minimalistic") var minimalistic: Bool = false
@@ -23,6 +24,9 @@ struct ExchangeSectionView: View {
@State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN)
@State private var currencyName: String = UNKNOWN
@State private var currencySymbol: String = UNKNOWN
+ @State private var didDelete: Bool = false
+ @State private var disabled: Bool = false
+ @State private var purge: Bool = false
func amountAvailable(_ exchange: Exchange?, currency: String?) -> Amount? {
if let exchange {
@@ -41,6 +45,19 @@ struct ExchangeSectionView: View {
return nil
}
+ private func deleteExchange() {
+ disabled = true // don't try this more than once
+ Task { // runs on MainActor
+ if let _ = try? await model.deleteExchange(url: exchange.exchangeBaseUrl, purge: purge) {
+// symLog.log("\(executed) \(transactionId)")
+ didDelete = true // change button text
+ } else {
+ purge = true
+ disabled = false
+ }
+ }
+ }
+
var body: some View {
#if PRINT_CHANGES
let _ = Self._printChanges()
@@ -76,6 +93,14 @@ struct ExchangeSectionView: View {
.accessibilityLabel(bankingHint + " " + linkTitle)
.padding(.top)
}
+
+ let buttonTitle = String(localized: "Exchange.Delete", defaultValue: "Delete Payment Provider", comment: "Action button")
+ WarningButton(warningText: String(localized: "Are you sure you want to delete this payment provider?"),
+ buttonTitle: buttonTitle,
+ buttonIcon: "trash",
+ role: .destructive,
+ disabled: $disabled,
+ action: deleteExchange)
} header: {
BarGraphHeader(stack: stack.push(),
scopeInfo: scopeInfo,
diff --git a/TalerWallet1/Views/HelperViews/TransactionButton.swift b/TalerWallet1/Views/HelperViews/TransactionButton.swift
@@ -6,24 +6,69 @@ import SwiftUI
import taler_swift
import AVFoundation
+struct WarningButton: View {
+ let warningText: String?
+ let buttonTitle: String
+ let buttonIcon: String?
+ let role: ButtonRole?
+ @Binding var disabled: Bool
+ let action: () -> Void
+
+ @AppStorage("shouldShowWarning") var shouldShowWarning: Bool = true
+ @State private var showAlert: Bool = false
+
+ var body: some View {
+ Button(role: role,
+ action: {
+ if !disabled {
+ if shouldShowWarning && (role == .destructive || role == .cancel) {
+ showAlert = true
+ } else {
+ action()
+ }
+ }
+ }) {
+ HStack(spacing: 50) {
+ Text(buttonTitle)
+ if let buttonIcon {
+ Image(systemName: buttonIcon)
+ }
+ }
+ }
+ .talerFont(.title2)
+ .frame(maxWidth: .infinity)
+ .buttonStyle(.bordered)
+ .controlSize(.large)
+ .disabled(disabled)
+ .alert(warningText ?? EMPTYSTRING, isPresented: $showAlert, actions: {
+ Button("Cancel", role: .cancel) {
+ showAlert = false
+ }
+ Button(buttonTitle) {
+ showAlert = false
+ action()
+ }
+ }, message: { Text("This operation cannot be undone") }
+ )
+ }
+}
+// MARK: -
struct TransactionButton: View {
let transactionId: String
let command: TxAction
let warning: String?
let action: (_ transactionId: String, _ viewHandles: Bool) async throws -> Void
- @AppStorage("shouldShowWarning") var shouldShowWarning: Bool = true
-
@State private var disabled: Bool = false
@State private var executed: Bool = false
- @State private var showAlert: Bool = false
+ @State private var buttonTitle: String = EMPTYSTRING
private func doAction() {
disabled = true // don't try this more than once
Task { // runs on MainActor
if let _ = try? await action(transactionId, false) {
// symLog.log("\(executed) \(transactionId)")
- executed = true
+ executed = true // change button text
}
}
}
@@ -34,38 +79,14 @@ struct TransactionButton: View {
let role: ButtonRole? = isDestructive ? .destructive
: isCancel ? .cancel
: nil
- Button(role: role, action: {
- if !disabled {
- if shouldShowWarning && (isDestructive || isCancel) {
- showAlert = true
- } else {
- doAction()
- }
- }
- }, label: {
- HStack(spacing: 50) {
- Text(executed ? command.localizedActionExecuted
- : command.localizedActionTitle)
- if let imageName = command.localizedActionImage {
- Image(systemName: imageName)
- }
- }
- .talerFont(.title2)
- .frame(maxWidth: .infinity)
- })
- .buttonStyle(.bordered)
- .controlSize(.large)
- .disabled(disabled)
- .alert(warning ?? EMPTYSTRING, isPresented: $showAlert, actions: {
- Button("Cancel", role: .cancel) {
- showAlert = false
- }
- Button(command.localizedActionTitle) {
- showAlert = false
- doAction()
- }
- }, message: { Text("This operation cannot be undone") }
- )
+ let buttonTitle = executed ? command.localizedActionExecuted
+ : command.localizedActionTitle
+ WarningButton(warningText: warning,
+ buttonTitle: command.localizedActionTitle,
+ buttonIcon: command.localizedActionImage,
+ role: role,
+ disabled: $disabled,
+ action: doAction)
}
}
// MARK: -