commit 29db29f2ec249ff94bc8286006b0c22b12b6705a
parent d16a62de5809a46688b8ffc8671cf5d7ecc95e87
Author: Marc Stibane <marc@taler.net>
Date: Fri, 14 Aug 2026 20:22:42 +0200
AI: PreparedTemplate to avoid instantiiating twice
Diffstat:
2 files changed, 32 insertions(+), 3 deletions(-)
diff --git a/TalerWallet1/Views/Sheets/Payment/PayTemplateScan.swift b/TalerWallet1/Views/Sheets/Payment/PayTemplateScan.swift
@@ -41,6 +41,9 @@ struct PayTemplateScan: View {
@State private var isPaivana = false
@State private var summary: String = EMPTYSTRING // templateParam
@State private var scope: ScopeInfo? = nil
+ /// survives PaymentScan being popped and pushed again, so that we don't
+ /// instantiate the template (= create another order) a second time
+ @State private var prepared: PreparedTemplate? = nil
// @State private var feeAmount: Amount? = nil
// @State private var feeStr: String = EMPTYSTRING
@@ -122,7 +125,8 @@ struct PayTemplateScan: View {
amountToTransfer: $amountToTransfer,
summary: $summary,
amountIsEditable: amountIsEditable,
- summaryIsEditable: summaryIsEditable)
+ summaryIsEditable: summaryIsEditable,
+ prepared: $prepared)
// final destination with amountShortcut, when user tapped a shortcut
let finalDestinationS = PaymentScan(stack: stack.push(),
@@ -131,7 +135,8 @@ struct PayTemplateScan: View {
amountToTransfer: $amountShortcut,
summary: $summary,
amountIsEditable: amountIsEditable,
- summaryIsEditable: summaryIsEditable)
+ summaryIsEditable: summaryIsEditable,
+ prepared: $prepared)
// destination to subject input
let inputDestination = SubjectInputV(stack: stack.push(),
@@ -196,7 +201,8 @@ struct PayTemplateScan: View {
amountToTransfer: $amountToTransfer,
summary: $summary,
amountIsEditable: amountIsEditable,
- summaryIsEditable: summaryIsEditable)
+ summaryIsEditable: summaryIsEditable,
+ prepared: $prepared)
}
} .navigationTitle(navTitle)
// .ignoresSafeArea(.keyboard, edges: .bottom)
diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentScan.swift b/TalerWallet1/Views/Sheets/Payment/PaymentScan.swift
@@ -15,6 +15,12 @@ fileprivate func feeLabel(_ feeString: String) -> String {
feeString.isEmpty ? EMPTYSTRING : String(localized: "+ \(feeString) fee")
}
+/// The pay-template instantiation which already created an order at the merchant
+struct PreparedTemplate: Equatable {
+ let key: String // the parameters that order was created for
+ let transactionId: String
+}
+
// MARK: -
// Will be called either by the user scanning a <pay> QR code or tapping the provided link,
// both from the shop's website - or even from a printed QR code.
@@ -31,6 +37,7 @@ struct PaymentScan: View, Sendable {
@Binding var summary: String
let amountIsEditable: Bool //
let summaryIsEditable: Bool //
+ var prepared: Binding<PreparedTemplate?>? = nil // template only, lives in PayTemplateScan
@EnvironmentObject private var model: WalletModel
@EnvironmentObject private var controller: Controller
@@ -42,14 +49,30 @@ struct PaymentScan: View, Sendable {
@State private var elapsed: Int = 0
@State private var talerTX = TalerTransaction(dummyCurrency: DEMOCURRENCY)
+ /// the parameters an already instantiated template order belongs to
+ private var templateKey: String {
+ url.trimmedString + "\n"
+ + (amountIsEditable ? amountToTransfer.description : EMPTYSTRING) + "\n"
+ + (summaryIsEditable ? summary : EMPTYSTRING)
+ }
+
@MainActor
private func viewDidLoad() async {
// symLog.log(".task")
if template {
+ /// Instantiating a template creates a fresh order at the merchant, and this view is
+ /// pushed anew (with new @State) whenever the user navigates back and forward again
+ /// - so only instantiate once per amount/subject the user entered.
+ let key = templateKey
+ if let already = prepared?.wrappedValue, already.key == key {
+ txId = already.transactionId
+ return
+ }
if let templateResponse = try? await model.preparePayForTemplate(url.trimmedString,
amount: amountIsEditable ? amountToTransfer : nil,
summary: summaryIsEditable ? summary : nil) {
txId = templateResponse.transactionId
+ prepared?.wrappedValue = PreparedTemplate(key: key, transactionId: templateResponse.transactionId)
// preparePayResult = templateResponse
// let raw = templateResponse.amountRaw
// controller.updateAmount(raw, forSaved: url)