[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-ios] 15/54: Suspend-Resume
From: |
gnunet |
Subject: |
[taler-taler-ios] 15/54: Suspend-Resume |
Date: |
Fri, 30 Jun 2023 22:33:47 +0200 |
This is an automated email from the git hooks/post-receive script.
marc-stibane pushed a commit to branch master
in repository taler-ios.
commit 185b6c0ad904af203233f8960b1116ebdeb332b1
Author: Marc Stibane <marc@taler.net>
AuthorDate: Wed Jun 21 15:07:17 2023 +0200
Suspend-Resume
---
TalerWallet1/Backend/Transaction.swift | 12 ++--
TalerWallet1/Model/Model+Exchange.swift | 2 +-
TalerWallet1/Model/Model+Transactions.swift | 69 ++++++++++++++++++----
TalerWallet1/Model/WalletModel.swift | 2 +-
.../Views/Balances/BalancesSectionView.swift | 16 +++--
.../Views/Balances/UncompletedRowView.swift | 18 +++---
.../Views/Transactions/TransactionDetailView.swift | 25 ++++----
.../Views/Transactions/TransactionsListView.swift | 23 ++++++--
8 files changed, 118 insertions(+), 49 deletions(-)
diff --git a/TalerWallet1/Backend/Transaction.swift
b/TalerWallet1/Backend/Transaction.swift
index 0ca3188..3a16618 100644
--- a/TalerWallet1/Backend/Transaction.swift
+++ b/TalerWallet1/Backend/Transaction.swift
@@ -102,12 +102,12 @@ struct TransactionCommon: Decodable {
case payment
case refund
case refresh
- case reward // get paid for e.g. survey participation
-// case tip // tip personnel at restaurants
- case peerPushDebit = "peer-push-debit" // send coins to
peer, show QR
- case scanPushCredit = "peer-push-credit" // scan QR,
receive coins from peer
- case peerPullCredit = "peer-pull-credit" // request payment
from peer, show QR
- case scanPullDebit = "peer-pull-debit" // scan QR, pay
requested
+ case reward = "tip" // get paid for e.g.
survey participation
+// case tip // tip personnel at
restaurants
+ case peerPushDebit = "peer-push-debit" // send coins to peer,
show QR
+ case scanPushCredit = "peer-push-credit" // scan QR, receive coins
from peer
+ case peerPullCredit = "peer-pull-credit" // request payment from
peer, show QR
+ case scanPullDebit = "peer-pull-debit" // scan QR, pay requested
}
var type: TransactionType
var txState: TransactionState
diff --git a/TalerWallet1/Model/Model+Exchange.swift
b/TalerWallet1/Model/Model+Exchange.swift
index fac7dae..e298420 100644
--- a/TalerWallet1/Model/Model+Exchange.swift
+++ b/TalerWallet1/Model/Model+Exchange.swift
@@ -98,7 +98,7 @@ extension WalletModel {
async throws {
symLog?.log("adding exchange: \(url)") // TODO: .notice
let request = AddExchange(exchangeBaseUrl: url)
- logger.info("adding exchange: \(url)")
+ logger.info("adding exchange: \(url, privacy: .public)")
_ = try await sendRequest(request)
}
}
diff --git a/TalerWallet1/Model/Model+Transactions.swift
b/TalerWallet1/Model/Model+Transactions.swift
index 4c4fd92..f6bb23c 100644
--- a/TalerWallet1/Model/Model+Transactions.swift
+++ b/TalerWallet1/Model/Model+Transactions.swift
@@ -41,7 +41,6 @@ fileprivate struct GetTransactions:
WalletBackendFormattedRequest {
var currency: String?
var search: String?
-
struct Args: Encodable {
var currency: String?
var search: String?
@@ -53,16 +52,14 @@ fileprivate struct GetTransactions:
WalletBackendFormattedRequest {
}
/// A request to abort a wallet transaction by ID.
struct AbortTransaction: WalletBackendFormattedRequest {
+ struct Response: Decodable {}
func operation() -> String { return "abortTransaction" }
func args() -> Args { return Args(transactionId: transactionId) }
var transactionId: String
-
struct Args: Encodable {
var transactionId: String
}
-
- struct Response: Decodable {}
}
/// A request to delete a wallet transaction by ID.
struct DeleteTransaction: WalletBackendFormattedRequest {
@@ -71,50 +68,98 @@ struct DeleteTransaction: WalletBackendFormattedRequest {
func args() -> Args { return Args(transactionId: transactionId) }
var transactionId: String
+ struct Args: Encodable {
+ var transactionId: String
+ }
+}
+/// A request to suspend a wallet transaction by ID.
+struct SuspendTransaction: WalletBackendFormattedRequest {
+ struct Response: Decodable {}
+ func operation() -> String { return "suspendTransaction" }
+ func args() -> Args { return Args(transactionId: transactionId) }
+ var transactionId: String
struct Args: Encodable {
var transactionId: String
}
}
+/// A request to suspend a wallet transaction by ID.
+struct ResumeTransaction: WalletBackendFormattedRequest {
+ struct Response: Decodable {}
+ func operation() -> String { return "resumeTransaction" }
+ func args() -> Args { return Args(transactionId: transactionId) }
+ var transactionId: String
+ struct Args: Encodable {
+ var transactionId: String
+ }
+}
// MARK: -
extension WalletModel {
/// ask wallet-core for its list of transactions filtered by searchString
func fetchTransactionsT(currency: String? = nil, searchString: String? =
nil)
- async -> [Transaction] { //
might be called from a background thread itself
+ async -> [Transaction] { // might
be called from a background thread itself
do {
let request = GetTransactions(currency: currency, search:
searchString)
+ logger.info("getTransactions")
let response = try await sendRequest(request, ASYNCDELAY)
return response.transactions
} catch {
+ logger.error("getTransactions failed: \(error)")
return []
}
}
/// fetch transactions from Wallet-Core. No networking involved
@MainActor func fetchTransactionsM(currency: String? = nil, searchString:
String? = nil)
- async -> [Transaction] { // M for MainActor
- await fetchTransactionsT(currency: currency, searchString:
searchString)
+ async -> [Transaction] { // M for MainActor
+ return await fetchTransactionsT(currency: currency, searchString:
searchString)
}
func abortTransactionT(transactionId: String)
- async throws { //
might be called from a background thread itself
+ async throws { // might be called from a background thread
itself
let request = AbortTransaction(transactionId: transactionId)
+ logger.info("abortTransaction: \(transactionId, privacy:
.private(mask: .hash))")
let _ = try await sendRequest(request, ASYNCDELAY)
}
/// delete the specified transaction from Wallet-Core. No networking
involved
@MainActor func abortTransactionM(transactionId: String)
- async throws { // M for MainActor
- try await abortTransactionT(transactionId: transactionId) //
call abortTransaction on main thread
+ async throws { // M for MainActor
+ try await abortTransactionT(transactionId: transactionId)
}
func deleteTransactionT(transactionId: String)
- async throws { //
might be called from a background thread itself
+ async throws { // might be called from a background thread
itself
let request = DeleteTransaction(transactionId: transactionId)
+ logger.info("deleteTransaction: \(transactionId, privacy:
.private(mask: .hash))")
let _ = try await sendRequest(request, ASYNCDELAY)
}
/// delete the specified transaction from Wallet-Core. No networking
involved
@MainActor func deleteTransactionM(transactionId: String)
async throws { // M for MainActor
- try await deleteTransactionT(transactionId: transactionId) //
call deleteTransaction on main thread
+ try await deleteTransactionT(transactionId: transactionId)
+ }
+
+ func suspendTransactionT(transactionId: String)
+ async throws { // might be called from a background thread
itself
+ let request = SuspendTransaction(transactionId: transactionId)
+ logger.info("suspendTransaction: \(transactionId, privacy:
.private(mask: .hash))")
+ let _ = try await sendRequest(request, ASYNCDELAY)
+ }
+ /// delete the specified transaction from Wallet-Core. No networking
involved
+ @MainActor func suspendTransactionM(transactionId: String)
+ async throws { // M for MainActor
+ try await suspendTransactionT(transactionId: transactionId)
+ }
+
+ func resumeTransactionT(transactionId: String)
+ async throws { // might be called from a background thread
itself
+ let request = ResumeTransaction(transactionId: transactionId)
+ logger.info("resumeTransaction: \(transactionId, privacy:
.private(mask: .hash))")
+ let _ = try await sendRequest(request, ASYNCDELAY)
+ }
+ /// delete the specified transaction from Wallet-Core. No networking
involved
+ @MainActor func resumeTransactionM(transactionId: String)
+ async throws { // M for MainActor
+ try await resumeTransactionT(transactionId: transactionId)
}
}
diff --git a/TalerWallet1/Model/WalletModel.swift
b/TalerWallet1/Model/WalletModel.swift
index 6a912d6..580f601 100644
--- a/TalerWallet1/Model/WalletModel.swift
+++ b/TalerWallet1/Model/WalletModel.swift
@@ -13,7 +13,7 @@ fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9
seconds for debugging
// MARK: -
/// The "virtual" base class for all models
class WalletModel: ObservableObject {
- public static let shared = WalletModel(-1)
+ public static let shared = WalletModel(0)
static func className() -> String {"\(self)"}
var symLog: SymLogC?
let logger = Logger (subsystem: "net.taler.gnu", category: "wallet-core")
diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift
b/TalerWallet1/Views/Balances/BalancesSectionView.swift
index fef89da..f46735e 100644
--- a/TalerWallet1/Views/Balances/BalancesSectionView.swift
+++ b/TalerWallet1/Views/Balances/BalancesSectionView.swift
@@ -77,6 +77,8 @@ struct BalancesSectionView: View {
}
let deleteAction = model.deleteTransactionT // dummyTransaction
let abortAction = model.abortTransactionT
+ let suspendAction = model.suspendTransactionT // dummyTransaction
+ let resumeAction = model.resumeTransactionT
Section {
// if "KUDOS" == currency && !balance.available.isZero {
@@ -104,7 +106,9 @@ struct BalancesSectionView: View {
reloadAllAction: reloadCompleted,
reloadOneAction: reloadOneAction,
deleteAction: deleteAction,
- abortAction: abortAction)
+ abortAction: abortAction,
+ suspendAction: suspendAction,
+ resumeAction: resumeAction)
}, tag: 3, selection: $buttonSelected
) { EmptyView() }.frame(width: 0).opacity(0).hidden()
@@ -131,7 +135,9 @@ struct BalancesSectionView: View {
reloadAllAction: reloadPending,
reloadOneAction: reloadOneAction,
deleteAction: deleteAction,
- abortAction: abortAction)
+ abortAction: abortAction,
+ suspendAction: suspendAction,
+ resumeAction: resumeAction)
}
} label: {
VStack(spacing: 6) {
@@ -160,10 +166,12 @@ struct BalancesSectionView: View {
reloadAllAction: reloadUncompleted,
reloadOneAction: reloadOneAction,
deleteAction: deleteAction,
- abortAction: abortAction)
+ abortAction: abortAction,
+ suspendAction: suspendAction,
+ resumeAction: resumeAction)
}
} label: {
- UncompletedRowView(uncompletedTransactions:
uncompletedTransactions)
+ UncompletedRowView(uncompletedTransactions:
$uncompletedTransactions)
}
}
diff --git a/TalerWallet1/Views/Balances/UncompletedRowView.swift
b/TalerWallet1/Views/Balances/UncompletedRowView.swift
index b7642dc..b4637a2 100644
--- a/TalerWallet1/Views/Balances/UncompletedRowView.swift
+++ b/TalerWallet1/Views/Balances/UncompletedRowView.swift
@@ -7,7 +7,7 @@ import taler_swift
/// This view shows an uncompleted transaction row in a currency section
struct UncompletedRowView: View {
- var uncompletedTransactions: [Transaction]
+ @Binding var uncompletedTransactions: [Transaction]
var body: some View {
let count = uncompletedTransactions.count
@@ -23,12 +23,12 @@ struct UncompletedRowView: View {
}
// MARK: -
#if DEBUG
-struct UncompletedRowView_Previews: PreviewProvider {
- static var previews: some View {
- let uncompletedTransactions: [Transaction] = []
- List {
- UncompletedRowView(uncompletedTransactions:
uncompletedTransactions)
- }
- }
-}
+//struct UncompletedRowView_Previews: PreviewProvider {
+// static var previews: some View {
+// let uncompletedTransactions: [Transaction] = []
+// List {
+// UncompletedRowView(uncompletedTransactions:
uncompletedTransactions)
+// }
+// }
+//}
#endif
diff --git a/TalerWallet1/Views/Transactions/TransactionDetailView.swift
b/TalerWallet1/Views/Transactions/TransactionDetailView.swift
index f1ea9d8..1310696 100644
--- a/TalerWallet1/Views/Transactions/TransactionDetailView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionDetailView.swift
@@ -32,6 +32,16 @@ struct TransactionDetailView: View {
: localizedType
Group {
List {
+ if developerMode {
+ if transaction.isSuspendable { if let suspendAction {
+ TransactionButton(transactionId: common.transactionId,
+ command: .suspend, action:
suspendAction)
+ } }
+ if transaction.isResumable { if let resumeAction {
+ TransactionButton(transactionId: common.transactionId,
+ command: .resume, action:
resumeAction)
+ } }
+ }
Text("\(dateString)")
.font(.title2)
// .listRowSeparator(.hidden)
@@ -49,16 +59,6 @@ struct TransactionDetailView: View {
if let doneAction {
DoneButton(doneAction: doneAction)
}
- if developerMode {
- if transaction.isSuspendable { if let suspendAction {
- TransactionButton(transactionId: common.transactionId,
- command: .suspend, action:
suspendAction)
- } }
- if transaction.isResumable { if let resumeAction {
- TransactionButton(transactionId: common.transactionId,
- command: .resume, action:
resumeAction)
- } }
- }
}.listStyle(myListStyle.style).anyView
}.onNotification(.TransactionStateTransition) { notification in
if let transition = notification.userInfo?[TRANSACTIONTRANSITION]
as? TransactionTransition {
@@ -71,6 +71,7 @@ struct TransactionDetailView: View {
symLog.log("newState: \(newState), reloading
transaction")
let reloadedTransaction = try await
reloadAction(common.transactionId)
transaction = reloadedTransaction // redraw
+ symLog.log("reloaded transaction:
\(reloadedTransaction.common.txState.major)")
} catch {
symLog.log(error.localizedDescription)
}}}
@@ -150,7 +151,9 @@ struct TransactionDetailView: View {
baseURL: nil, large: true) // TODO:
baseURL
case .peer2peer(let p2pTransaction):
let details = p2pTransaction.details //
TODO: details
- QRCodeDetails(transaction: transaction)
+ if pending {
+ QRCodeDetails(transaction: transaction)
+ }
ThreeAmounts(common: common, topTitle: String(localized:
"Peer to Peer:"),
baseURL: details.exchangeBaseUrl, large:
false)
}
diff --git a/TalerWallet1/Views/Transactions/TransactionsListView.swift
b/TalerWallet1/Views/Transactions/TransactionsListView.swift
index 218bf75..6303b49 100644
--- a/TalerWallet1/Views/Transactions/TransactionsListView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionsListView.swift
@@ -6,7 +6,7 @@ import SwiftUI
import SymLog
struct TransactionsListView: View {
- private let symLog = SymLogV()
+ private let symLog = SymLogV(0)
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
let navTitle: String
@@ -16,6 +16,8 @@ struct TransactionsListView: View {
let reloadOneAction: ((_ transactionId: String) async throws ->
Transaction)
let deleteAction: (_ transactionId: String) async throws -> ()
let abortAction: (_ transactionId: String) async throws -> ()
+ let suspendAction: (_ transactionId: String) async throws -> ()
+ let resumeAction: (_ transactionId: String) async throws -> ()
var body: some View {
#if DEBUG
@@ -26,9 +28,16 @@ struct TransactionsListView: View {
// TODO: Unlock the power of grammatical agreement
// let title = AttributedString(localized: "^[\(count) Ticket](inflect:
true)")
let title: String = "\(count) \(navTitle)"
- Content(symLog: symLog, currency: currency, transactions:
transactions, myListStyle: $myListStyle,
- reloadAllAction: reloadAllAction, reloadOneAction:
reloadOneAction,
- deleteAction: deleteAction, abortAction: abortAction)
+ Content(symLog: symLog,
+ currency: currency,
+ transactions: transactions,
+ myListStyle: $myListStyle,
+ reloadAllAction: reloadAllAction,
+ reloadOneAction: reloadOneAction,
+ deleteAction: deleteAction,
+ abortAction: abortAction,
+ suspendAction: suspendAction,
+ resumeAction: resumeAction)
.navigationTitle(title)
.navigationBarTitleDisplayMode(.large) // .inline
.onAppear {
@@ -51,6 +60,8 @@ extension TransactionsListView {
let reloadOneAction: ((_ transactionId: String) async throws ->
Transaction)
let deleteAction: (_ transactionId: String) async throws -> ()
let abortAction: (_ transactionId: String) async throws -> ()
+ let suspendAction: (_ transactionId: String) async throws -> ()
+ let resumeAction: (_ transactionId: String) async throws -> ()
@State private var upAction: () -> Void = {}
@State private var downAction: () -> Void = {}
@@ -92,7 +103,9 @@ extension TransactionsListView {
TransactionDetailView(transaction: transaction,
reloadAction: reloadOneAction,
deleteAction: deleteAction,
- abortAction: abortAction)
+ abortAction: abortAction,
+ suspendAction: suspendAction,
+ resumeAction: resumeAction)
}} label: {
TransactionRowView(transaction: transaction)
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-ios] 12/54: Localization, (continued)
- [taler-taler-ios] 12/54: Localization, gnunet, 2023/06/30
- [taler-taler-ios] 08/54: Preparations for localization + accessability, gnunet, 2023/06/30
- [taler-taler-ios] 19/54: remove dismissFirst, gnunet, 2023/06/30
- [taler-taler-ios] 14/54: Made Model a Singleton, gnunet, 2023/06/30
- [taler-taler-ios] 40/54: TransactionType, gnunet, 2023/06/30
- [taler-taler-ios] 26/54: PeerPullDebit, gnunet, 2023/06/30
- [taler-taler-ios] 16/54: Dummy, gnunet, 2023/06/30
- [taler-taler-ios] 34/54: sizeCategory, task, gnunet, 2023/06/30
- [taler-taler-ios] 06/54: Notifications, gnunet, 2023/06/30
- [taler-taler-ios] 42/54: BalanceRow, gnunet, 2023/06/30
- [taler-taler-ios] 15/54: Suspend-Resume,
gnunet <=
- [taler-taler-ios] 21/54: Sounds, P2P receive, gnunet, 2023/06/30
- [taler-taler-ios] 07/54: Big Model update, removed unneccessary thread-safety code, gnunet, 2023/06/30
- [taler-taler-ios] 41/54: playSound, gnunet, 2023/06/30
- [taler-taler-ios] 30/54: bugfix, gnunet, 2023/06/30
- [taler-taler-ios] 43/54: confirmTransferUrl, gnunet, 2023/06/30
- [taler-taler-ios] 33/54: log only release builds, gnunet, 2023/06/30
- [taler-taler-ios] 27/54: Logging, gnunet, 2023/06/30
- [taler-taler-ios] 38/54: actions, gnunet, 2023/06/30
- [taler-taler-ios] 28/54: playSound, gnunet, 2023/06/30
- [taler-taler-ios] 32/54: Adjust DebugView for Notch, gnunet, 2023/06/30