[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-ios] 02/10: started with PayTemplates
From: |
gnunet |
Subject: |
[taler-taler-ios] 02/10: started with PayTemplates |
Date: |
Tue, 08 Aug 2023 12:29:21 +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 e728e0f48e9bb6f384b205db82c8c1dadd700c00
Author: Marc Stibane <marc@taler.net>
AuthorDate: Tue Aug 8 12:00:12 2023 +0200
started with PayTemplates
---
TalerWallet.xcodeproj/project.pbxproj | 4 +
TalerWallet1/Controllers/Controller.swift | 3 +
TalerWallet1/Controllers/DebugViewC.swift | 1 +
TalerWallet1/Model/Model+Payment.swift | 18 ++++
TalerWallet1/Views/Payment/PayTemplateView.swift | 113 +++++++++++++++++++++++
TalerWallet1/Views/Sheets/URLSheet.swift | 6 +-
6 files changed, 144 insertions(+), 1 deletion(-)
diff --git a/TalerWallet.xcodeproj/project.pbxproj
b/TalerWallet.xcodeproj/project.pbxproj
index 5024d76..eae83d9 100644
--- a/TalerWallet.xcodeproj/project.pbxproj
+++ b/TalerWallet.xcodeproj/project.pbxproj
@@ -96,6 +96,7 @@
4EB095702989CBFE0043A8A1 /* PendingOpsListView.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB0954E2989CBFE0043A8A1 /*
PendingOpsListView.swift */; };
4EB3136129FEE79B007D68BC /* SendDone.swift in Sources */ = {isa
= PBXBuildFile; fileRef = 4EB3136029FEE79B007D68BC /* SendDone.swift */; };
4EB431672A1E55C700C5690E /* ManualWithdrawDone.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB431662A1E55C700C5690E /*
ManualWithdrawDone.swift */; };
+ 4EBA56412A7FF5200084948B /* PayTemplateView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EBA56402A7FF5200084948B /*
PayTemplateView.swift */; };
4EBA82AB2A3EB2CA00E5F39A /* TransactionButton.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EBA82AA2A3EB2CA00E5F39A /*
TransactionButton.swift */; };
4EBA82AD2A3F580500E5F39A /* QuiteSomeCoins.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EBA82AC2A3F580500E5F39A /*
QuiteSomeCoins.swift */; };
4EC90C782A1B528B0071DC58 /* ExchangeSectionView.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EC90C772A1B528B0071DC58 /*
ExchangeSectionView.swift */; };
@@ -234,6 +235,7 @@
4EB0954E2989CBFE0043A8A1 /* PendingOpsListView.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = PendingOpsListView.swift; sourceTree = "<group>"; };
4EB3136029FEE79B007D68BC /* SendDone.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= SendDone.swift; sourceTree = "<group>"; };
4EB431662A1E55C700C5690E /* ManualWithdrawDone.swift */ = {isa
= PBXFileReference; lastKnownFileType = sourcecode.swift; path =
ManualWithdrawDone.swift; sourceTree = "<group>"; };
+ 4EBA56402A7FF5200084948B /* PayTemplateView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= PayTemplateView.swift; sourceTree = "<group>"; };
4EBA82AA2A3EB2CA00E5F39A /* TransactionButton.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= TransactionButton.swift; sourceTree = "<group>"; };
4EBA82AC2A3F580500E5F39A /* QuiteSomeCoins.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path =
QuiteSomeCoins.swift; sourceTree = "<group>"; };
4EC90C772A1B528B0071DC58 /* ExchangeSectionView.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = ExchangeSectionView.swift; sourceTree = "<group>"; };
@@ -452,6 +454,7 @@
isa = PBXGroup;
children = (
4EB0952D2989CBFE0043A8A1 /* PaymentView.swift
*/,
+ 4EBA56402A7FF5200084948B /*
PayTemplateView.swift */,
);
path = Payment;
sourceTree = "<group>";
@@ -791,6 +794,7 @@
4EB3136129FEE79B007D68BC /* SendDone.swift in
Sources */,
4EB0956B2989CBFE0043A8A1 /*
TextFieldAlert.swift in Sources */,
4EBA82AD2A3F580500E5F39A /*
QuiteSomeCoins.swift in Sources */,
+ 4EBA56412A7FF5200084948B /*
PayTemplateView.swift in Sources */,
4EB431672A1E55C700C5690E /*
ManualWithdrawDone.swift in Sources */,
4E9320472A164BC700A87B0E /*
PaymentPurpose.swift in Sources */,
4E753A082A0B6A5F002D9328 /* ShareSheet.swift in
Sources */,
diff --git a/TalerWallet1/Controllers/Controller.swift
b/TalerWallet1/Controllers/Controller.swift
index 96e1fef..17201f5 100644
--- a/TalerWallet1/Controllers/Controller.swift
+++ b/TalerWallet1/Controllers/Controller.swift
@@ -21,6 +21,7 @@ enum UrlCommand {
case pay
case payPull
case payPush
+ case payTemplate
}
// MARK: -
@@ -103,6 +104,8 @@ extension Controller {
return UrlCommand.payPull
case "pay-push":
return UrlCommand.payPush
+ case "pay-template":
+ return UrlCommand.payTemplate
default:
symLog.log("unknown command taler://\(command)")
}
diff --git a/TalerWallet1/Controllers/DebugViewC.swift
b/TalerWallet1/Controllers/DebugViewC.swift
index f25b353..4cd365c 100644
--- a/TalerWallet1/Controllers/DebugViewC.swift
+++ b/TalerWallet1/Controllers/DebugViewC.swift
@@ -73,6 +73,7 @@ public let SHEET_WITHDRAW_CONFIRM = SHEET_WITHDRAW_ACCEPT + 1
// 133 waiti
// MARK: Merchant Payment
// openURL (Link, NFC or scan QR) ==> pays merchant
public let SHEET_PAYMENT = SHEET_WITHDRAWAL + 10 // 140 Pay
Merchant
+public let SHEET_PAY_TEMPLATE = SHEET_PAYMENT + 2 // 142 Pay
Merchant Template
// MARK: Reward - Receive Coins (from merchant)
// openURL (Link, NFC or scan QR) ==> receive coins from merchant
diff --git a/TalerWallet1/Model/Model+Payment.swift
b/TalerWallet1/Model/Model+Payment.swift
index 51e8d57..88872e2 100644
--- a/TalerWallet1/Model/Model+Payment.swift
+++ b/TalerWallet1/Model/Model+Payment.swift
@@ -147,6 +147,17 @@ fileprivate struct PreparePayForUri:
WalletBackendFormattedRequest {
var talerPayUri: String
}
}
+/// A request to get an exchange's payment contract terms.
+fileprivate struct PreparePayForTemplate: WalletBackendFormattedRequest {
+ typealias Response = PreparePayResult
+ func operation() -> String { return "preparePayForTemplate" }
+ func args() -> Args { return Args(talerPayTemplateUri:
talerPayTemplateUri) }
+
+ var talerPayTemplateUri: String
+ struct Args: Encodable {
+ var talerPayTemplateUri: String
+ }
+}
// MARK: -
/// The result from confirmPayForUri
struct ConfirmPayResult: Decodable {
@@ -176,6 +187,13 @@ extension WalletModel {
return response
}
@MainActor
+ func preparePayForTemplateM(_ talerPayTemplateUri: String) // M for
MainActor
+ async throws -> PreparePayResult {
+ let request = PreparePayForTemplate(talerPayTemplateUri:
talerPayTemplateUri)
+ let response = try await sendRequest(request, ASYNCDELAY)
+ return response
+ }
+ @MainActor
func confirmPayM(_ transactionId: String) // M for MainActor
async throws -> ConfirmPayResult {
let request = confirmPayForUri(transactionId: transactionId)
diff --git a/TalerWallet1/Views/Payment/PayTemplateView.swift
b/TalerWallet1/Views/Payment/PayTemplateView.swift
new file mode 100644
index 0000000..526d0b0
--- /dev/null
+++ b/TalerWallet1/Views/Payment/PayTemplateView.swift
@@ -0,0 +1,113 @@
+/*
+ * This file is part of GNU Taler, ©2022-23 Taler Systems S.A.
+ * See LICENSE.md
+ */
+import SwiftUI
+import taler_swift
+import SymLog
+
+// Will be called either by the user scanning a QR code or tapping the
provided link,
+// both from the shop's website. We show the payment details
+struct PayTemplateView: View {
+ private let symLog = SymLogV()
+ let navTitle = String(localized: "Confirm Payment", comment:"pay merchant")
+
+ @EnvironmentObject private var controller: Controller
+ @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
+
+ // the scanned URL
+ let url: URL
+
+ @EnvironmentObject private var model: WalletModel
+
+ func acceptAction(preparePayResult: PreparePayResult) {
+ Task {
+ do {
+ let confirmPayResult = try await
model.confirmPayM(preparePayResult.transactionId)
+ // symLog.log(confirmPayResult as Any)
+ if confirmPayResult.type != "done" {
+ controller.playSound(0)
+ // TODO: show error
+ }
+ } catch {
+ controller.playSound(0)
+ // TODO: error
+ symLog.log(error.localizedDescription)
+ }
+ dismissTop()
+ }
+ }
+
+ @State var preparePayResult: PreparePayResult? = nil
+
+ func query(url: URL) -> String? {
+ if let query = url.query {
+ let array = query.components(separatedBy: "&")
+ }
+ return nil
+ }
+
+ var body: some View {
+ if let preparePayResult {
+ let effective = preparePayResult.amountEffective
+ List {
+ let baseURL =
preparePayResult.contractTerms.exchanges.first?.url
+ let raw = preparePayResult.amountRaw
+ let currency = raw.currencyStr
+ let topTitle = String(localized: "Amount to pay:")
+ if let effective {
+ // TODO: already paid
+ let fee = try! Amount.diff(raw, effective) // TODO:
different currencies
+ ThreeAmountsView(topTitle: topTitle,
+ topAmount: raw, fee: fee,
+ bottomTitle: String(localized:
"\(currency) to be spent:"),
+ bottomAmount: effective,
+ large: false, pending: false, incoming:
false,
+ baseURL: baseURL)
+ // TODO: payment: popup with all possible exchanges, check
fees
+ } else if let balanceDetails = preparePayResult.balanceDetails
{ // Insufficient
+ Text("You don't have enough \(currency)")
+ ThreeAmountsView(topTitle: topTitle,
+ topAmount: raw, fee: nil,
+ bottomTitle: String(localized:
"\(currency) available:"),
+ bottomAmount:
balanceDetails.balanceAvailable,
+ large: false, pending: false, incoming:
false,
+ baseURL: baseURL)
+ } else {
+ // TODO: Error - neither effective nor balanceDetails
+ Text("Error")
+ }
+ }
+ .listStyle(myListStyle.style).anyView
+ .safeAreaInset(edge: .bottom) {
+ if let effective {
+ Button(navTitle, action: { acceptAction(preparePayResult:
preparePayResult) })
+ .buttonStyle(TalerButtonStyle(type: .prominent))
+ .padding(.horizontal)
+ } else {
+ Button("Cancel", action: { dismissTop() })
+ .buttonStyle(TalerButtonStyle(type: .bordered))
+ .padding(.horizontal)
+ }
+ }
+ .navigationTitle(navTitle)
+ .onAppear() {
+ symLog.log("onAppear")
+ DebugViewC.shared.setSheetID(SHEET_PAY_TEMPLATE)
+ }
+ } else {
+ let badURL = "Error in Link: \(url)"
+ WithdrawProgressView(message: url.host ?? badURL)
+ .navigationTitle("Find Exchange")
+ .task {
+ do {
+ symLog.log(".task")
+ let result = try await
model.preparePayForTemplateM(url.absoluteString)
+ preparePayResult = result
+ } catch { // TODO: error
+ symLog.log(error.localizedDescription)
+ }
+ }
+ }
+ }
+}
diff --git a/TalerWallet1/Views/Sheets/URLSheet.swift
b/TalerWallet1/Views/Sheets/URLSheet.swift
index 42ec8b2..1db6169 100644
--- a/TalerWallet1/Views/Sheets/URLSheet.swift
+++ b/TalerWallet1/Views/Sheets/URLSheet.swift
@@ -24,7 +24,11 @@ struct URLSheet: View {
P2pPayURIView(url: urlToOpen)
case .payPush:
P2pReceiveURIView(url: urlToOpen)
- case .unknown: // Error view
+ case .payTemplate:
+ PayTemplateView(url: urlToOpen)
+// case .reward:
+// RewardURIView(url: urlToOpen)
+ default: // Error view
VStack {
Text("unknown command")
.font(.title)
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-ios] branch master updated (dbf44d6 -> 7792241), gnunet, 2023/08/08
- [taler-taler-ios] 03/10: tip -> reward, gnunet, 2023/08/08
- [taler-taler-ios] 07/10: Wallet changes + bugfixes, gnunet, 2023/08/08
- [taler-taler-ios] 01/10: PaymentView, gnunet, 2023/08/08
- [taler-taler-ios] 10/10: iOS: bump version to 0.9.3 (17), gnunet, 2023/08/08
- [taler-taler-ios] 05/10: SuperScriptDigits, gnunet, 2023/08/08
- [taler-taler-ios] 04/10: Payment Sounds by carlo von lynX, gnunet, 2023/08/08
- [taler-taler-ios] 02/10: started with PayTemplates,
gnunet <=
- [taler-taler-ios] 09/10: Usability improved for manual withdrawal + P2P, gnunet, 2023/08/08
- [taler-taler-ios] 08/10: NavigationLinksView, gnunet, 2023/08/08
- [taler-taler-ios] 06/10: GetScopedCurrencyInfo, gnunet, 2023/08/08