gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]