commit bfaf17c0dd86af27ec33dce206dad8b0dc3a8158
parent 05eed763d0f142dd2ebd78fcae4dc35fc6663824
Author: Marc Stibane <marc@taler.net>
Date: Sat, 9 Nov 2024 10:02:31 +0100
Transactions
Diffstat:
4 files changed, 50 insertions(+), 61 deletions(-)
diff --git a/TalerWallet1/Model/Model+Transactions.swift b/TalerWallet1/Model/Model+Transactions.swift
@@ -57,14 +57,14 @@ struct TransactionOffset: Codable {
/// A request to get the transactions in the wallet's history.
fileprivate struct GetTransactionsV2: WalletBackendFormattedRequest {
func operation() -> String { "getTransactionsV2" }
- func args() -> Args { Args(scopeInfo: scopeInfo,
+ func args() -> Args { Args(scopeInfo: scope,
filterByState: filterByState,
includeRefreshes: includeRefreshes,
limit: -limit, // descending
offsetTransactionId: offset?.txID,
offsetTimestamp: offset?.txTime) }
- var scopeInfo: ScopeInfo?
+ var scope: ScopeInfo?
var filterByState: TransactionStateFilter?
var limit: Int
var offset: TransactionOffset?
@@ -139,69 +139,51 @@ struct ResumeTransaction: WalletBackendFormattedRequest {
}
// MARK: -
extension WalletModel {
- /// ask wallet-core for its list of transactions filtered by searchString
- func transactionsT(_ stack: CallStack, scopeInfo: ScopeInfo, // searchString: String? = nil, <= never worked anyway
- sort: String = "descending", filterByState: TransactionStateFilter? = nil,
- includeRefreshes: Bool = false, viewHandles: Bool = false)
- async throws -> [Transaction] {
- let request = GetTransactions(scopeInfo: scopeInfo, currency: scopeInfo.currency, // search: searchString, <= never worked
- sort: sort, filterByState: filterByState, includeRefreshes: includeRefreshes)
- let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
- return response.transactions
- }
- /// fetch transactions from Wallet-Core. No networking involved
- @MainActor func transactionsM(_ stack: CallStack, scopeInfo: ScopeInfo, // searchString: String? = nil,
- sort: String = "descending", filterByState: TransactionStateFilter? = nil,
- viewHandles: Bool = false)
- async throws -> [Transaction] { // M for MainActor
- return try await transactionsT(stack.push(), scopeInfo: scopeInfo, // searchString: searchString,
- sort: sort, filterByState: filterByState, viewHandles: viewHandles)
- }
- /// ask wallet-core for its list of transactions filtered by searchString
- func transactionsT2(_ stack: CallStack,
- scopeInfo: ScopeInfo,
- filterByState: TransactionStateFilter,
- limit: Int = 1_000_000,
- offset: TransactionOffset? = nil,
- includeRefreshes: Bool = false,
- viewHandles: Bool = false)
+ /// ask wallet-core for its list of transactions filtered by state
+ nonisolated func getTransactionsV2(_ stack: CallStack,
+ scope: ScopeInfo,
+ filterByState: TransactionStateFilter,
+ limit: Int = 1_000_000,
+ offset: TransactionOffset? = nil,
+ includeRefreshes: Bool = false,
+ viewHandles: Bool = false)
async throws -> [Transaction] {
- let request = GetTransactionsV2(scopeInfo: scopeInfo,
- filterByState: filterByState,
- limit: limit,
- offset: offset,
- includeRefreshes: includeRefreshes)
+ let request = GetTransactionsV2(scope: scope,
+ filterByState: filterByState,
+ limit: limit,
+ offset: offset,
+ includeRefreshes: includeRefreshes)
let response = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
return response.transactions
}
// MARK: -
/// abort the specified transaction from Wallet-Core. No networking involved
- func abortTransaction(transactionId: String, viewHandles: Bool = false) async throws {
+ nonisolated func abortTransaction(transactionId: String, viewHandles: Bool = false) async throws {
let request = AbortTransaction(transactionId: transactionId)
logger.notice("abortTransaction: \(transactionId, privacy: .private(mask: .hash))")
let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
}
/// delete the specified transaction from Wallet-Core. No networking involved
- func deleteTransaction(transactionId: String, viewHandles: Bool = false) async throws {
+ nonisolated func deleteTransaction(transactionId: String, viewHandles: Bool = false) async throws {
let request = DeleteTransaction(transactionId: transactionId)
logger.notice("deleteTransaction: \(transactionId, privacy: .private(mask: .hash))")
let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
}
- func failTransaction(transactionId: String, viewHandles: Bool = false) async throws {
+ nonisolated func failTransaction(transactionId: String, viewHandles: Bool = false) async throws {
let request = FailTransaction(transactionId: transactionId)
logger.notice("failTransaction: \(transactionId, privacy: .private(mask: .hash))")
let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
}
- func suspendTransaction(transactionId: String, viewHandles: Bool = false) async throws {
+ nonisolated func suspendTransaction(transactionId: String, viewHandles: Bool = false) async throws {
let request = SuspendTransaction(transactionId: transactionId)
logger.notice("suspendTransaction: \(transactionId, privacy: .private(mask: .hash))")
let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
}
- func resumeTransaction(transactionId: String, viewHandles: Bool = false) async throws {
+ nonisolated func resumeTransaction(transactionId: String, viewHandles: Bool = false) async throws {
let request = ResumeTransaction(transactionId: transactionId)
logger.notice("resumeTransaction: \(transactionId, privacy: .private(mask: .hash))")
let _ = try await sendRequest(request, ASYNCDELAY, viewHandles: viewHandles)
diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift b/TalerWallet1/Views/Balances/BalancesSectionView.swift
@@ -52,33 +52,36 @@ struct BalancesSectionView {
@State private var sectionID = UUID()
@State private var shownSectionID = UUID() // guaranteed to be different the first time
+ @MainActor
func loadRecent(_ stack: CallStack) async -> () {
- if let transactions = try? await model.transactionsT2(stack.push("loadRecent - \(balance.scopeInfo.url?.trimURL)"),
- scopeInfo: balance.scopeInfo,
- filterByState: .final,
- limit: MAXRECENT,
- includeRefreshes: false) {
+ if let transactions = try? await model.getTransactionsV2(stack.push("loadRecent - \(balance.scopeInfo.url?.trimURL)"),
+ scope: balance.scopeInfo,
+ filterByState: .final,
+ limit: MAXRECENT,
+ includeRefreshes: false) {
// let recent = WalletModel.completedTransactions(transactions)
// let slice = recent.prefix(MAXRECENT) // already sorted
// withAnimation { recentTransactions = Array(slice) }
withAnimation { recentTransactions = transactions }
}
}
+ @MainActor
func loadCompleted(_ stack: CallStack) async -> () {
- if let transactions = try? await model.transactionsT2(stack.push("loadCompleted - \(balance.scopeInfo.url?.trimURL)"),
- scopeInfo: balance.scopeInfo,
- filterByState: .final,
- includeRefreshes: developerMode) {
+ if let transactions = try? await model.getTransactionsV2(stack.push("loadCompleted - \(balance.scopeInfo.url?.trimURL)"),
+ scope: balance.scopeInfo,
+ filterByState: .final,
+ includeRefreshes: developerMode) {
// let completed = WalletModel.completedTransactions(transactions)
// withAnimation { completedTransactions = completed }
withAnimation { completedTransactions = transactions }
}
}
+ @MainActor
func loadPending(_ stack: CallStack) async -> () {
- if let transactions = try? await model.transactionsT2(stack.push("loadPending - \(balance.scopeInfo.url?.trimURL)"),
- scopeInfo: balance.scopeInfo,
- filterByState: .nonfinal,
- includeRefreshes: developerMode) {
+ if let transactions = try? await model.getTransactionsV2(stack.push("loadPending - \(balance.scopeInfo.url?.trimURL)"),
+ scope: balance.scopeInfo,
+ filterByState: .nonfinal,
+ includeRefreshes: developerMode) {
// let pending = WalletModel.pendingTransactions(transactions)
// withAnimation { pendingTransactions = pending }
withAnimation { pendingTransactions = transactions }
diff --git a/TalerWallet1/Views/HelperViews/BarGraph.swift b/TalerWallet1/Views/HelperViews/BarGraph.swift
@@ -22,6 +22,18 @@ struct BarGraphHeader: View {
@State private var completedTransactions: [Transaction] = []
@ScaledMetric var barHeight = 9 // relative to fontSize
+ @MainActor
+ private func loadCompleted() async {
+ symLog.log(".task for BarGraphHeader(\(scope.currency)) - load \(MAXBARS) Transactions")
+ if let response = try? await model.getTransactionsV2(stack.push("BarGraphHeader - \(scope.url?.trimURL)"),
+ scope: scope,
+ filterByState: .done,
+ limit: MAXBARS
+ ) {
+ completedTransactions = response
+ }
+ }
+
var body: some View {
let currencyInfo = controller.info(for: scope, controller.currencyTicker)
HStack (alignment: .center, spacing: 10) {
@@ -34,16 +46,7 @@ struct BarGraphHeader: View {
maxBars: MAXBARS, barHeight: barHeight)
}
// .headerProminence(.increased) // unfortunately this is not useful
- .task(id: shouldReloadBalances + 2_000_000) {
- symLog.log(".task for BarGraphHeader(\(scope.currency)) - load \(MAXBARS) Transactions")
- if let response = try? await model.transactionsT2(stack.push("BarGraphHeader - \(scope.url?.trimURL)"),
- scopeInfo: scope,
- filterByState: .done,
- limit: MAXBARS
- ) {
- completedTransactions = response
- }
- }
+ .task(id: shouldReloadBalances + 2_000_000) { await loadCompleted() }
}
}
// MARK: -
diff --git a/TalerWallet1/Views/HelperViews/TransactionButton.swift b/TalerWallet1/Views/HelperViews/TransactionButton.swift
@@ -67,6 +67,7 @@ struct TransactionButton: View {
@State private var executed: Bool = false
@State private var buttonTitle: String = EMPTYSTRING
+ @MainActor
private func doAction() {
disabled = true // don't try this more than once
Task { // runs on MainActor