taler-ios

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

commit 7b05cff290c57036f19d25259a521be989be7470
parent 070a6d41b7dd58173547fd3b188eb0c9a0d474b0
Author: Marc Stibane <marc@taler.net>
Date:   Mon,  5 Oct 2026 08:24:04 +0200

use timeToPay

Diffstat:
MTalerWallet1/Views/Sheets/Payment/PaymentScan.swift | 67+++++++++++++++++++++++++++++++++++--------------------------------
MTalerWallet1/Views/Transactions/TransactionSummaryList.swift | 4+++-
2 files changed, 38 insertions(+), 33 deletions(-)

diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentScan.swift b/TalerWallet1/Views/Sheets/Payment/PaymentScan.swift @@ -243,32 +243,16 @@ struct PaySafeArea: View, Sendable { let terms: MerchantContractTerms let amountString: String let amountA11y: String + @Binding var isFinished: Bool? @Binding var payNow: Bool @EnvironmentObject private var controller: Controller @State private var wasTapped: Bool = false - - func timeToPay(_ terms: MerchantContractTerms) -> Int { - if let milliseconds = try? terms.payDeadline.milliseconds() { - let date = Date(milliseconds: milliseconds) - let now = Date.now - let timeInterval = now.timeIntervalSince(date) - if timeInterval < 0 { - symLog?.log("\(timeInterval) seconds left to pay") - return Int(-timeInterval) - } else { - symLog?.log("\(date) - \(now) = \(timeInterval)") - } - } else { - symLog?.log("no milliseconds") - } - return 0 - } + @State private var timeToPay: Int? var body: some View { - let timeToPay = timeToPay(terms) - let showTime = timeToPay > 0 && timeToPay < 300 + let fiveMinutes = 5 * 60 let button = Button("Pay \(amountString) now") { if !wasTapped { wasTapped = true @@ -282,7 +266,7 @@ struct PaySafeArea: View, Sendable { payNow = true #endif } - } + }.id("payNow") .accessibilityLabel(Text("Pay \(amountA11y) now", comment: "a11y")) .buttonStyle(TalerButtonStyle(type: .prominent, disabled: wasTapped)) .disabled(wasTapped) @@ -290,22 +274,41 @@ struct PaySafeArea: View, Sendable { if !newValue { wasTapped = false } // this attempt finished (success or failure) - allow retry } .padding(.horizontal) - - if showTime { - let view = VStack { - TimeView(String(localized: "Time to pay:"), - seconds: timeToPay) - .padding(.top) - button + .task { + timeToPay = terms.timeToPay(true) + if let timeToPay { + if timeToPay >= fiveMinutes { + let nextCheck = timeToPay - fiveMinutes + DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(nextCheck)) { + self.timeToPay = terms.timeToPay(true) + } + } else if timeToPay < 2 { + isFinished = true + } + } } - if #available(iOS 26.0, *) { - view - .glassEffect(in: .rect(cornerRadius: 16.0)) + + if let timeToPay { + if timeToPay < fiveMinutes { + let view = VStack { + TimeView(String(localized: "Time to pay:"), + seconds: timeToPay, + isFinished: $isFinished) + .padding(.top) + button + } + if #available(iOS 26.0, *) { + view + .glassEffect(in: .rect(cornerRadius: 16.0)) + } else { + view + } } else { - view + let _ = symLog?.log("timeToPay \(timeToPay) seconds not shown") + button } } else { - let _ = symLog?.log("\(timeToPay) not shown") + let _ = symLog?.log("no timeToPay") button } } diff --git a/TalerWallet1/Views/Transactions/TransactionSummaryList.swift b/TalerWallet1/Views/Transactions/TransactionSummaryList.swift @@ -59,6 +59,7 @@ struct TransactionSummaryList: View { @State private var effective: Amount? = nil @State private var paymentPossible: Bool? = nil @State private var scope: ScopeInfo? = nil + @State private var isFinished: Bool? = false @State private var payNow: Bool = false @State private var isWorking: Bool = false @Namespace var topID @@ -359,13 +360,14 @@ struct TransactionSummaryList: View { let bottomButton = ZStack { if isPaying, case .payment(let paymentTransaction) = talerTX { let details = paymentTransaction.details - if let effective, let terms = details.contractTerms { + if let effective, let terms = details.contractTerms, isFinished != true { let formatted = effective.formatted(currencyInfo) PaySafeArea(symLog: symLog, stack: stack.push(), terms: terms, amountString: formatted.0, amountA11y: formatted.1, + isFinished: $isFinished, payNow: $payNow) } else { cancelButton