gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-ios] branch master updated (dbf44d6 -> 7792241)


From: gnunet
Subject: [taler-taler-ios] branch master updated (dbf44d6 -> 7792241)
Date: Tue, 08 Aug 2023 12:29:19 +0200

This is an automated email from the git hooks/post-receive script.

marc-stibane pushed a change to branch master
in repository taler-ios.

    from dbf44d6  iOS: bump version to 0.9.3 (16)
     new f6a8385  PaymentView
     new e728e0f  started with PayTemplates
     new 9ba37a1  tip -> reward
     new d25e933  Payment Sounds by carlo von lynX
     new 98be8e4  SuperScriptDigits
     new 949faaf  GetScopedCurrencyInfo
     new bf9bfba  Wallet changes + bugfixes
     new 18a2d40  NavigationLinksView
     new 3cfbfdf  Usability improved for manual withdrawal + P2P
     new 7792241  iOS: bump version to 0.9.3 (17)

The 10 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 TalerWallet.xcodeproj/project.pbxproj              |  36 +++++--
 TalerWallet1/Backend/Transaction.swift             |  22 +----
 TalerWallet1/Backend/WalletBackendRequest.swift    |  13 +--
 TalerWallet1/Backend/WalletCore.swift              |   2 +-
 TalerWallet1/Controllers/Controller.swift          |   8 +-
 TalerWallet1/Controllers/DebugViewC.swift          |   1 +
 TalerWallet1/Helper/SuperScriptDigits.swift        |  25 +++++
 TalerWallet1/Helper/playSound.swift                |  19 +++-
 TalerWallet1/Model/Model+Exchange.swift            |  28 ++++++
 TalerWallet1/Model/Model+Payment.swift             |  18 ++++
 TalerWallet1/Model/WalletModel.swift               |   2 +-
 TalerWallet1/Sounds/payment_received.m4a           | Bin 0 -> 68854 bytes
 TalerWallet1/Sounds/payment_sent.m4a               | Bin 0 -> 69508 bytes
 .../Views/Balances/BalancesSectionView.swift       | 103 +++++++++++++--------
 TalerWallet1/Views/Exchange/ManualWithdraw.swift   |   2 +-
 .../Views/HelperViews/QRCodeDetailView.swift       |  35 +++----
 TalerWallet1/Views/HelperViews/SelectDays.swift    |  12 +--
 TalerWallet1/Views/Payment/DeleteMe.swift          |  79 ----------------
 ...{PaymentURIView.swift => PayTemplateView.swift} |  68 +++-----------
 .../{PaymentURIView.swift => PaymentView.swift}    |   8 +-
 TalerWallet1/Views/Peer2peer/PaymentPurpose.swift  |  24 ++---
 TalerWallet1/Views/Peer2peer/SendPurpose.swift     |  24 ++---
 TalerWallet1/Views/Settings/SettingsItem.swift     |  47 +++++++++-
 TalerWallet1/Views/Settings/SettingsView.swift     |   6 +-
 TalerWallet1/Views/Sheets/URLSheet.swift           |   8 +-
 .../Views/Transactions/ManualDetails.swift         |  28 ++++--
 TalerWallet1/Views/Transactions/ThreeAmounts.swift |  12 +--
 .../Views/Transactions/TransactionDetailView.swift |   8 +-
 TestFlight/WhatToTest.en-US.txt                    |   7 ++
 29 files changed, 352 insertions(+), 293 deletions(-)
 create mode 100644 TalerWallet1/Helper/SuperScriptDigits.swift
 create mode 100644 TalerWallet1/Sounds/payment_received.m4a
 create mode 100644 TalerWallet1/Sounds/payment_sent.m4a
 delete mode 100644 TalerWallet1/Views/Payment/DeleteMe.swift
 copy TalerWallet1/Views/Payment/{PaymentURIView.swift => 
PayTemplateView.swift} (58%)
 rename TalerWallet1/Views/Payment/{PaymentURIView.swift => PaymentView.swift} 
(96%)

diff --git a/TalerWallet.xcodeproj/project.pbxproj 
b/TalerWallet.xcodeproj/project.pbxproj
index 8352c2c..14555ba 100644
--- a/TalerWallet.xcodeproj/project.pbxproj
+++ b/TalerWallet.xcodeproj/project.pbxproj
@@ -8,6 +8,8 @@
 
 /* Begin PBXBuildFile section */
                4E16E12329F3BB99008B9C86 /* CurrencyFormatter.swift in Sources 
*/ = {isa = PBXBuildFile; fileRef = 4E16E12229F3BB99008B9C86 /* 
CurrencyFormatter.swift */; };
+               4E2254972A822B8100E41D29 /* payment_received.m4a in Resources 
*/ = {isa = PBXBuildFile; fileRef = 4E2254952A822B8100E41D29 /* 
payment_received.m4a */; };
+               4E2254982A822B8100E41D29 /* payment_sent.m4a in Resources */ = 
{isa = PBXBuildFile; fileRef = 4E2254962A822B8100E41D29 /* payment_sent.m4a */; 
};
                4E363CBC2A237E0900D7E98C /* URL+id+iban.swift in Sources */ = 
{isa = PBXBuildFile; fileRef = 4E363CBB2A237E0900D7E98C /* URL+id+iban.swift 
*/; };
                4E363CBE2A23CB2100D7E98C /* AnyTransition+backslide.swift in 
Sources */ = {isa = PBXBuildFile; fileRef = 4E363CBD2A23CB2100D7E98C /* 
AnyTransition+backslide.swift */; };
                4E363CC02A24754200D7E98C /* Settings.bundle in Resources */ = 
{isa = PBXBuildFile; fileRef = 4E363CBF2A24754200D7E98C /* Settings.bundle */; 
};
@@ -68,7 +70,7 @@
                4EB095502989CBFE0043A8A1 /* SettingsItem.swift in Sources */ = 
{isa = PBXBuildFile; fileRef = 4EB095262989CBFE0043A8A1 /* SettingsItem.swift 
*/; };
                4EB095522989CBFE0043A8A1 /* ExchangeListView.swift in Sources 
*/ = {isa = PBXBuildFile; fileRef = 4EB095292989CBFE0043A8A1 /* 
ExchangeListView.swift */; };
                4EB095542989CBFE0043A8A1 /* Model+Payment.swift in Sources */ = 
{isa = PBXBuildFile; fileRef = 4EB0952C2989CBFE0043A8A1 /* Model+Payment.swift 
*/; };
-               4EB095552989CBFE0043A8A1 /* PaymentURIView.swift in Sources */ 
= {isa = PBXBuildFile; fileRef = 4EB0952D2989CBFE0043A8A1 /* 
PaymentURIView.swift */; };
+               4EB095552989CBFE0043A8A1 /* PaymentView.swift in Sources */ = 
{isa = PBXBuildFile; fileRef = 4EB0952D2989CBFE0043A8A1 /* PaymentView.swift 
*/; };
                4EB095562989CBFE0043A8A1 /* TransactionsListView.swift in 
Sources */ = {isa = PBXBuildFile; fileRef = 4EB0952F2989CBFE0043A8A1 /* 
TransactionsListView.swift */; };
                4EB095572989CBFE0043A8A1 /* TransactionRowView.swift in Sources 
*/ = {isa = PBXBuildFile; fileRef = 4EB095302989CBFE0043A8A1 /* 
TransactionRowView.swift */; };
                4EB095582989CBFE0043A8A1 /* TransactionDetailView.swift in 
Sources */ = {isa = PBXBuildFile; fileRef = 4EB095312989CBFE0043A8A1 /* 
TransactionDetailView.swift */; };
@@ -96,6 +98,8 @@
                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 */; };
+               4EBA563F2A7FD9390084948B /* SuperScriptDigits.swift in Sources 
*/ = {isa = PBXBuildFile; fileRef = 4EBA563E2A7FD9390084948B /* 
SuperScriptDigits.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 */; };
@@ -142,6 +146,8 @@
 
 /* Begin PBXFileReference section */
                4E16E12229F3BB99008B9C86 /* CurrencyFormatter.swift */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path 
= CurrencyFormatter.swift; sourceTree = "<group>"; };
+               4E2254952A822B8100E41D29 /* payment_received.m4a */ = {isa = 
PBXFileReference; lastKnownFileType = file; path = payment_received.m4a; 
sourceTree = "<group>"; };
+               4E2254962A822B8100E41D29 /* payment_sent.m4a */ = {isa = 
PBXFileReference; lastKnownFileType = file; path = payment_sent.m4a; sourceTree 
= "<group>"; };
                4E363CBB2A237E0900D7E98C /* URL+id+iban.swift */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path 
= "URL+id+iban.swift"; sourceTree = "<group>"; };
                4E363CBD2A23CB2100D7E98C /* AnyTransition+backslide.swift */ = 
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = 
sourcecode.swift; path = "AnyTransition+backslide.swift"; sourceTree = 
"<group>"; };
                4E363CBF2A24754200D7E98C /* Settings.bundle */ = {isa = 
PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = 
Settings.bundle; sourceTree = "<group>"; };
@@ -206,7 +212,7 @@
                4EB095262989CBFE0043A8A1 /* SettingsItem.swift */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path 
= SettingsItem.swift; sourceTree = "<group>"; };
                4EB095292989CBFE0043A8A1 /* ExchangeListView.swift */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path 
= ExchangeListView.swift; sourceTree = "<group>"; };
                4EB0952C2989CBFE0043A8A1 /* Model+Payment.swift */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path 
= "Model+Payment.swift"; sourceTree = "<group>"; };
-               4EB0952D2989CBFE0043A8A1 /* PaymentURIView.swift */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path 
= PaymentURIView.swift; sourceTree = "<group>"; };
+               4EB0952D2989CBFE0043A8A1 /* PaymentView.swift */ = {isa = 
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path 
= PaymentView.swift; sourceTree = "<group>"; };
                4EB0952F2989CBFE0043A8A1 /* TransactionsListView.swift */ = 
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = 
sourcecode.swift; path = TransactionsListView.swift; sourceTree = "<group>"; };
                4EB095302989CBFE0043A8A1 /* TransactionRowView.swift */ = {isa 
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; 
path = TransactionRowView.swift; sourceTree = "<group>"; };
                4EB095312989CBFE0043A8A1 /* TransactionDetailView.swift */ = 
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = 
sourcecode.swift; path = TransactionDetailView.swift; sourceTree = "<group>"; };
@@ -234,6 +240,8 @@
                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>"; };
+               4EBA563E2A7FD9390084948B /* SuperScriptDigits.swift */ = {isa = 
PBXFileReference; lastKnownFileType = sourcecode.swift; path = 
SuperScriptDigits.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>"; };
@@ -280,6 +288,15 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+               4E2254942A822B8100E41D29 /* Sounds */ = {
+                       isa = PBXGroup;
+                       children = (
+                               4E2254952A822B8100E41D29 /* 
payment_received.m4a */,
+                               4E2254962A822B8100E41D29 /* payment_sent.m4a */,
+                       );
+                       path = Sounds;
+                       sourceTree = "<group>";
+               };
                4E3B4BBF2A41E64000CC88B8 /* P2P_Sheets */ = {
                        isa = PBXGroup;
                        children = (
@@ -319,6 +336,7 @@
                                4EB095052989CB7C0043A8A1 /* Helper */,
                                4EB0950C2989CB9A0043A8A1 /* Quickjs */,
                                4EB094EF298979D30043A8A1 /* Assets.xcassets */,
+                               4E2254942A822B8100E41D29 /* Sounds */,
                                4E8C171B2A6509BB005B2392 /* 
Atkinson-Hyperlegible */,
                                4E363CBF2A24754200D7E98C /* Settings.bundle */,
                                4EB094F529897A9A0043A8A1 /* Preview Content */,
@@ -370,6 +388,7 @@
                                4E363CBB2A237E0900D7E98C /* URL+id+iban.swift 
*/,
                                4E9320422A14F6EA00A87B0E /* WalletColors.swift 
*/,
                                4E8E25322A1CD39700A27BFA /* 
EqualIconWidthDomain.swift */,
+                               4EBA563E2A7FD9390084948B /* 
SuperScriptDigits.swift */,
                        );
                        path = Helper;
                        sourceTree = "<group>";
@@ -451,7 +470,8 @@
                4EB0952A2989CBFE0043A8A1 /* Payment */ = {
                        isa = PBXGroup;
                        children = (
-                               4EB0952D2989CBFE0043A8A1 /* 
PaymentURIView.swift */,
+                               4EB0952D2989CBFE0043A8A1 /* PaymentView.swift 
*/,
+                               4EBA56402A7FF5200084948B /* 
PayTemplateView.swift */,
                        );
                        path = Payment;
                        sourceTree = "<group>";
@@ -724,8 +744,10 @@
                                4E8C17202A6509BB005B2392 /* 
Atkinson-Hyperlegible-Regular-102.otf in Resources */,
                                4E8C17222A6509BB005B2392 /* 
Atkinson-Hyperlegible-Bold-102.otf in Resources */,
                                4E8C17232A6509BB005B2392 /* 
Atkinson-Hyperlegible-BoldItalic-102.otf in Resources */,
+                               4E2254972A822B8100E41D29 /* 
payment_received.m4a in Resources */,
                                4E8C17212A6509BB005B2392 /* 
Atkinson-Hyperlegible-Italic-102.otf in Resources */,
                                4EB094F0298979D30043A8A1 /* Assets.xcassets in 
Resources */,
+                               4E2254982A822B8100E41D29 /* payment_sent.m4a in 
Resources */,
                        );
                        runOnlyForDeploymentPostprocessing = 0;
                };
@@ -772,10 +794,11 @@
                                4E87C8752A34B411001C6406 /* 
UncompletedRowView.swift in Sources */,
                                4E40E0BE29F25ABB00B85369 /* SendAmount.swift in 
Sources */,
                                4E8E25332A1CD39700A27BFA /* 
EqualIconWidthDomain.swift in Sources */,
+                               4EBA563F2A7FD9390084948B /* 
SuperScriptDigits.swift in Sources */,
                                4E578E942A4822D500F21F1C /* P2pPayURIView.swift 
in Sources */,
                                4EB095542989CBFE0043A8A1 /* Model+Payment.swift 
in Sources */,
                                4EB0954F2989CBFE0043A8A1 /* SettingsView.swift 
in Sources */,
-                               4EB095552989CBFE0043A8A1 /* 
PaymentURIView.swift in Sources */,
+                               4EB095552989CBFE0043A8A1 /* PaymentView.swift 
in Sources */,
                                4EB095612989CBFE0043A8A1 /* 
WithdrawURIView.swift in Sources */,
                                4EF840A72A0B85F400EE0D47 /* CopyShare.swift in 
Sources */,
                                4EB094ED298979620043A8A1 /* 
TalerWallet1App.swift in Sources */,
@@ -791,6 +814,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 */,
@@ -997,7 +1021,7 @@
                                CODE_SIGN_ENTITLEMENTS = "GNU 
Taler.entitlements";
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone 
Developer";
                                CODE_SIGN_STYLE = Manual;
-                               CURRENT_PROJECT_VERSION = 16;
+                               CURRENT_PROJECT_VERSION = 17;
                                DEVELOPMENT_TEAM = "";
                                "DEVELOPMENT_TEAM[sdk=iphoneos*]" = GUDDQ9428Y;
                                ENABLE_PREVIEWS = YES;
@@ -1039,7 +1063,7 @@
                                CODE_SIGN_ENTITLEMENTS = "GNU 
Taler.entitlements";
                                "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone 
Distribution";
                                CODE_SIGN_STYLE = Manual;
-                               CURRENT_PROJECT_VERSION = 16;
+                               CURRENT_PROJECT_VERSION = 17;
                                DEVELOPMENT_TEAM = "";
                                "DEVELOPMENT_TEAM[sdk=iphoneos*]" = GUDDQ9428Y;
                                ENABLE_PREVIEWS = YES;
diff --git a/TalerWallet1/Backend/Transaction.swift 
b/TalerWallet1/Backend/Transaction.swift
index 128a47a..ffbdd38 100644
--- a/TalerWallet1/Backend/Transaction.swift
+++ b/TalerWallet1/Backend/Transaction.swift
@@ -119,7 +119,7 @@ enum TransactionType: String, Codable {
     case payment
     case refund
     case refresh
-    case reward         = "tip"     // TODO: reward        // get paid for 
e.g. survey participation
+    case reward                                 // get paid for e.g. survey 
participation
 //    case tip                                  // tip personnel at restaurants
     case peerPushDebit  = "peer-push-debit"     // send coins to peer, show QR
     case scanPushCredit = "peer-push-credit"    // scan QR, receive coins from 
peer
@@ -132,7 +132,6 @@ enum TransactionType: String, Codable {
     var isRefund     : Bool { self == .refund }
     var isRefresh    : Bool { self == .refresh }
     var isReward     : Bool { self == .reward }
-    //    var isTipPayment : Bool { self == .tip }
     var isSendCoins  : Bool { self == .peerPushDebit }
     var isRcvCoins   : Bool { self == .scanPushCredit }
     var isSendInvoice: Bool { self == .peerPullCredit }
@@ -266,16 +265,6 @@ struct RewardTransaction {
     var details: RewardTransactionDetails
 }
 
-//struct TipTransactionDetails: Decodable {
-//    /// The exchange that the tip will be withdrawn from
-//    var exchangeBaseUrl: String
-//}
-
-//struct TipTransaction {
-//    var common: TransactionCommon
-//    var details: TipTransactionDetails
-//}
-
 enum RefreshReason: String, Decodable {
     case manual
     case payMerchant = "pay-merchant"
@@ -327,7 +316,6 @@ enum Transaction: Decodable, Hashable, Identifiable {
     case payment (PaymentTransaction)
     case refund (RefundTransaction)
     case reward (RewardTransaction)
-//    case tip (TipTransaction)
     case refresh (RefreshTransaction)
     case peer2peer (P2PTransaction)
 
@@ -347,9 +335,6 @@ enum Transaction: Decodable, Hashable, Identifiable {
                 case .reward:
                     let details = try RewardTransactionDetails.init(from: 
decoder)
                     self = .reward(RewardTransaction(common: common, details: 
details))
-//                case .tip:
-//                    let details = try TipTransactionDetails.init(from: 
decoder)
-//                    self = .tip(TipTransaction(common: common, details: 
details))
                 case .refresh:
                     let details = try RefreshTransactionDetails.init(from: 
decoder)
                     self = .refresh(RefreshTransaction(common: common, 
details: details))
@@ -405,7 +390,6 @@ enum Transaction: Decodable, Hashable, Identifiable {
     var isRefund     : Bool { common.type == .refund }
     var isRefresh    : Bool { common.type == .refresh }
     var isReward     : Bool { common.type == .reward }
-//    var isTipPayment : Bool { common.type == .tip }
     var isSendCoins  : Bool { common.type == .peerPushDebit }
     var isRcvCoins   : Bool { common.type == .scanPushCredit }
     var isSendInvoice: Bool { common.type == .peerPullCredit }
@@ -452,8 +436,6 @@ enum Transaction: Decodable, Hashable, Identifiable {
                 return refundTransaction.common
             case .reward(let rewardTransaction):
                 return rewardTransaction.common
-//            case .tip(let tipTransaction):
-//                return tipTransaction.common
             case .refresh(let refreshTransaction):
                 return refreshTransaction.common
             case .peer2peer(let p2pTransaction):
@@ -476,8 +458,6 @@ enum Transaction: Decodable, Hashable, Identifiable {
                 }
             case .reward(let rewardTransaction):
                 result[EXCHANGEBASEURL] = 
rewardTransaction.details.exchangeBaseUrl
-//            case .tip(let tipTransaction):
-//                result[EXCHANGEBASEURL] = 
tipTransaction.details.exchangeBaseUrl
             case .refresh(let refreshTransaction):
                 result["reason"] = 
refreshTransaction.details.refreshReason.rawValue
             case .peer2peer(let p2pTransaction):
diff --git a/TalerWallet1/Backend/WalletBackendRequest.swift 
b/TalerWallet1/Backend/WalletBackendRequest.swift
index 9bf8d80..ec9d2ca 100644
--- a/TalerWallet1/Backend/WalletBackendRequest.swift
+++ b/TalerWallet1/Backend/WalletBackendRequest.swift
@@ -28,18 +28,19 @@ struct ScopeInfo: Codable, Hashable {
     enum ScopeInfoType: String, Codable {
         case global
         case exchange
+        case auditor
     }
     var type: ScopeInfoType
-    var exchangeBaseUrl: String?    // only for "exchange"
+    var url: String?    // only for "exchange"
     var currency: String
 
     public static func == (lhs: ScopeInfo, rhs: ScopeInfo) -> Bool {
-        if let lhsBaseURL = lhs.exchangeBaseUrl {
-            if let rhsBaseURL = rhs.exchangeBaseUrl {
+        if let lhsBaseURL = lhs.url {
+            if let rhsBaseURL = rhs.url {
                 if lhsBaseURL != rhsBaseURL { return false }    // different 
exchanges
                                                                 // else fall 
thru and check type & currency
             } else { return false }                             // left but 
not right
-        } else if rhs.exchangeBaseUrl != nil {
+        } else if rhs.url != nil {
             return false                                        // right but 
not left
         }
         return lhs.type == rhs.type &&
@@ -47,8 +48,8 @@ struct ScopeInfo: Codable, Hashable {
     }
     public func hash(into hasher: inout Hasher) {
         hasher.combine(type)
-        if let baseURL = exchangeBaseUrl {
-            hasher.combine(baseURL)
+        if let url {
+            hasher.combine(url)
         }
         hasher.combine(currency)
     }
diff --git a/TalerWallet1/Backend/WalletCore.swift 
b/TalerWallet1/Backend/WalletCore.swift
index 3def60d..f2f0460 100644
--- a/TalerWallet1/Backend/WalletCore.swift
+++ b/TalerWallet1/Backend/WalletCore.swift
@@ -186,7 +186,7 @@ extension WalletCore {
         do {
             let decoded = try JSONDecoder().decode(TransactionTransition.self, 
from: jsonData)
             if decoded.newTxState != decoded.oldTxState {
-                let components = decoded.transactionId.components(separatedBy: 
[":"])
+                let components = decoded.transactionId.components(separatedBy: 
":")
                 if components.count >= 3 {  // txn:$txtype:$uid
                     if let type = TransactionType(rawValue: components[1]) {
                         guard type != .refresh else { return }
diff --git a/TalerWallet1/Controllers/Controller.swift 
b/TalerWallet1/Controllers/Controller.swift
index 96e1fef..d2d3c30 100644
--- a/TalerWallet1/Controllers/Controller.swift
+++ b/TalerWallet1/Controllers/Controller.swift
@@ -3,6 +3,7 @@
  * See LICENSE.md
  */
 import Foundation
+import AVFoundation
 import SwiftUI
 import SymLog
 import os.log
@@ -21,6 +22,8 @@ enum UrlCommand {
     case pay
     case payPull
     case payPush
+    case payTemplate
+    case reward
 }
 
 // MARK: -
@@ -29,8 +32,9 @@ class Controller: ObservableObject {
     private let symLog = SymLogC()
 
     @Published var backendState: BackendState = .none       // only used for 
launch animation
-    @AppStorage("playSounds") var playSounds: Bool = false  // extension 
mustn't define this, so it must be here
+    @AppStorage("playSounds") var playSounds: Int = 0       // extension 
mustn't define this, so it must be here
     let logger = Logger (subsystem: "net.taler.gnu", category: "Controller")
+    let player = AVQueuePlayer()
 
     var messageForSheet: String? = nil
 
@@ -103,6 +107,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/Helper/SuperScriptDigits.swift 
b/TalerWallet1/Helper/SuperScriptDigits.swift
new file mode 100644
index 0000000..4f9f896
--- /dev/null
+++ b/TalerWallet1/Helper/SuperScriptDigits.swift
@@ -0,0 +1,25 @@
+/*
+ * This file is part of GNU Taler, ©2022-23 Taler Systems S.A.
+ * See LICENSE.md
+ */
+import Foundation
+
+func SuperScriptDigits(_ number: String) -> String {
+    var result = ""
+    for char in number {
+        switch char {
+            case "0": result = result + String("\u{2070}")
+            case "1": result = result + String("\u{00B9}")
+            case "2": result = result + String("\u{00B2}")
+            case "3": result = result + String("\u{00B3}")
+            case "4": result = result + String("\u{2074}")
+            case "5": result = result + String("\u{2075}")
+            case "6": result = result + String("\u{2076}")
+            case "7": result = result + String("\u{2077}")
+            case "8": result = result + String("\u{2078}")
+            case "9": result = result + String("\u{2079}")
+            default: result = result + String(char)
+        }
+    }
+    return result
+}
diff --git a/TalerWallet1/Helper/playSound.swift 
b/TalerWallet1/Helper/playSound.swift
index 0b4c428..14f4077 100644
--- a/TalerWallet1/Helper/playSound.swift
+++ b/TalerWallet1/Helper/playSound.swift
@@ -9,18 +9,29 @@ extension Controller {
 
     func playSound(_ number: Int) {
         var soundID: SystemSoundID = 0
-        if number < 999 {
+        if number > 9 {
+            soundID = UInt32(number)
+        } else {
             let sound = (number == 0) ? "payment_failure" :
                         (number == 1) ? "payment_success" : "PaymentReceived"
             let fileURL = URL(fileURLWithPath: 
"/System/Library/Audio/UISounds/"
                               + sound + ".caf")
             AudioServicesCreateSystemSoundID(fileURL as CFURL, &soundID)
             logger.log("\(sound, privacy: .public) \(soundID)")
-        } else {
-            soundID = UInt32(number)
         }
-        if playSounds {
+        if number == 0 || number > 9 || playSounds < 0 {
             AudioServicesPlaySystemSound(soundID);
+        } else if playSounds > 0 {
+            if let url = Bundle.main.url(forResource: (number == 1) ? 
"payment_received"
+                                                                    : 
"payment_sent",
+                                         withExtension: "m4a") {
+                player.removeAllItems()
+                player.insert(AVPlayerItem(url: url), after: nil)
+                logger.log("\(url, privacy: .public) \(soundID)")
+                player.play()
+            } else {
+                AudioServicesPlaySystemSound(soundID);
+            }
         }
     }
 }
diff --git a/TalerWallet1/Model/Model+Exchange.swift 
b/TalerWallet1/Model/Model+Exchange.swift
index 8446893..434311d 100644
--- a/TalerWallet1/Model/Model+Exchange.swift
+++ b/TalerWallet1/Model/Model+Exchange.swift
@@ -76,6 +76,26 @@ fileprivate struct AddExchange: 
WalletBackendFormattedRequest {
         var exchangeBaseUrl: String
     }
 }
+
+/// A request to get info about a currency
+struct ScopedCurrencyInfo: Decodable {
+    var decimalSeparator: String
+    var numFractionalDigits: Int        // 0 Yen, 2 €,$, 3 arabic
+    var numTinyDigits: Int              // SuperScriptDigits
+    var isCurrencyNameLeading: Bool
+}
+
+fileprivate struct GetScopedCurrencyInfo: WalletBackendFormattedRequest {
+    typealias Response = ScopedCurrencyInfo
+    func operation() -> String { return "getScopedCurrencyInfo" }
+    func args() -> Args { return Args(scope: scope) }
+
+    var scope: ScopeInfo
+
+    struct Args: Encodable {
+        var scope: ScopeInfo
+    }
+}
 // MARK: -
 extension WalletModel {
     /// ask wallet-core for its list of known exchanges
@@ -97,4 +117,12 @@ extension WalletModel {
         logger.info("adding exchange: \(url, privacy: .public)")
         _ = try await sendRequest(request)
     }
+
+    @MainActor func getScopedCurrencyInfoM(scope: ScopeInfo)
+    async throws -> ScopedCurrencyInfo {   // M for MainActor
+        let request = GetScopedCurrencyInfo(scope: scope)
+        let response = try await sendRequest(request, ASYNCDELAY)
+        return response
+    }
+
 }
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/Model/WalletModel.swift 
b/TalerWallet1/Model/WalletModel.swift
index 1de0aff..d5dc714 100644
--- a/TalerWallet1/Model/WalletModel.swift
+++ b/TalerWallet1/Model/WalletModel.swift
@@ -69,7 +69,7 @@ fileprivate struct GetTransactionById: 
WalletBackendFormattedRequest {
 // MARK: -
 /// The info returned from Wallet-core init
 struct VersionInfo: Decodable {
-    var hash: String
+    var hash: String?
     var version: String
     var exchange: String
     var merchant: String
diff --git a/TalerWallet1/Sounds/payment_received.m4a 
b/TalerWallet1/Sounds/payment_received.m4a
new file mode 100644
index 0000000..c15ff63
Binary files /dev/null and b/TalerWallet1/Sounds/payment_received.m4a differ
diff --git a/TalerWallet1/Sounds/payment_sent.m4a 
b/TalerWallet1/Sounds/payment_sent.m4a
new file mode 100644
index 0000000..b16372a
Binary files /dev/null and b/TalerWallet1/Sounds/payment_sent.m4a differ
diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift 
b/TalerWallet1/Views/Balances/BalancesSectionView.swift
index 6cf640c..bc93f93 100644
--- a/TalerWallet1/Views/Balances/BalancesSectionView.swift
+++ b/TalerWallet1/Views/Balances/BalancesSectionView.swift
@@ -24,7 +24,6 @@ struct BalancesSectionView: View {
     @EnvironmentObject private var model: WalletModel
 
     @State private var isShowingDetailView = false
-    @State private var buttonSelected: Int? = nil
 
     @State private var transactions: [Transaction] = []
     @State private var completedTransactions: [Transaction] = []
@@ -86,38 +85,13 @@ struct BalancesSectionView: View {
                 Text("You can spend these KUDOS in the [Demo 
Shop](https://shop.demo.taler.net), or send them to another wallet.")
                     .multilineTextAlignment(.leading)
             }
-            HStack(spacing: 0) {
-                NavigationLink(destination: LazyView {
-                    SendAmount(amountAvailable: balance.available,
-                               centsToTransfer: $centsToTransfer,
-                                       summary: $summary)
-                  }, tag: 1, selection: $buttonSelected
-                ) { EmptyView() }.frame(width: 0).opacity(0).hidden()          
 // SendAmount
-
-                NavigationLink(destination: LazyView {
-                    RequestPayment(scopeInfo: balance.scopeInfo,
-                             centsToTransfer: $centsToTransfer,
-                                     summary: $summary)
-                  }, tag: 2, selection: $buttonSelected
-                ) { EmptyView() }.frame(width: 0).opacity(0).hidden()          
 // RequestPayment
-
-                NavigationLink(destination: LazyView {
-                    TransactionsListView(navTitle: String(localized: 
"Transactions"), currency: currency,
-                                     transactions: completedTransactions,
-                                       showUpDown: true,
-                                  reloadAllAction: reloadCompleted,
-                                  reloadOneAction: reloadOneAction)
-                  }, tag: 3, selection: $buttonSelected
-                ) { EmptyView() }.frame(width: 0).opacity(0).hidden()          
 // TransactionsListView
-
-                BalanceRowView(amount: balance.available, sendAction: {
-                        buttonSelected = 1      // will trigger SendAmount 
NavigationLink
-                    }, recvAction: {
-                        buttonSelected = 2      // will trigger RequestPayment 
NavigationLink
-                    }, rowAction: {
-                        buttonSelected = 3      // will trigger 
TransactionList NavigationLink
-                    })
-            }
+            NavigationLinksView(balance: balance,
+                        centsToTransfer: $centsToTransfer,
+                                summary: $summary,
+//                         buttonSelected: $buttonSelected,
+                  completedTransactions: $completedTransactions,
+                        reloadAllAction: reloadCompleted,
+                        reloadOneAction: reloadOneAction)
             let hasPending = pendingTransactions.count > 0
             if hasPending {
                 let (pendingIncoming, pendingOutgoing) = 
computePending(currency: currency)
@@ -153,11 +127,12 @@ struct BalancesSectionView: View {
                 NavigationLink {
 //let _ = print("button: Uncompleted Transactions: \(currency)")
                     LazyView {
-                        TransactionsListView(navTitle: String(localized: 
"Uncompleted"), currency: currency,
-                                             transactions: 
uncompletedTransactions,
-                                               showUpDown: false,
-                                          reloadAllAction: reloadUncompleted,
-                                          reloadOneAction: reloadOneAction)
+                        TransactionsListView(navTitle: String(localized: 
"Uncompleted"),
+                                             currency: currency,
+                                         transactions: uncompletedTransactions,
+                                           showUpDown: false,
+                                      reloadAllAction: reloadUncompleted,
+                                      reloadOneAction: reloadOneAction)
                     }
                 } label: {
                     UncompletedRowView(uncompletedTransactions: 
$uncompletedTransactions)
@@ -201,12 +176,60 @@ struct BalancesSectionView: View {
                                      transactions: threeTransactions,
                                      reloadOneAction: reloadOneAction)
             } header: {
-                Text("Last transactions")
+                Text("Recent transactions")
                     .font(.callout)
             }
         }
     } // body
 }
+
+fileprivate struct NavigationLinksView : View {
+    let balance: Balance
+//    let sectionCount: Int
+    @Binding var centsToTransfer: UInt64
+    @Binding var summary: String
+    @Binding var completedTransactions: [Transaction]
+    let reloadAllAction: () async -> ()
+    let reloadOneAction: ((_ transactionId: String) async throws -> 
Transaction)
+
+    @State private var buttonSelected: Int? = nil
+
+    var body: some View {
+        let currency = balance.available.currencyStr
+        HStack(spacing: 0) {
+            NavigationLink(destination: LazyView {
+                SendAmount(amountAvailable: balance.available,
+                           centsToTransfer: $centsToTransfer,
+                           summary: $summary)
+            }, tag: 1, selection: $buttonSelected
+            ) { EmptyView() }.frame(width: 0).opacity(0).hidden()           // 
SendAmount
+
+            NavigationLink(destination: LazyView {
+                RequestPayment(scopeInfo: balance.scopeInfo,
+                               centsToTransfer: $centsToTransfer,
+                               summary: $summary)
+            }, tag: 2, selection: $buttonSelected
+            ) { EmptyView() }.frame(width: 0).opacity(0).hidden()           // 
RequestPayment
+
+            NavigationLink(destination: LazyView {
+                TransactionsListView(navTitle: String(localized: 
"Transactions"), currency: currency,
+                                     transactions: completedTransactions,
+                                     showUpDown: true,
+                                     reloadAllAction: reloadAllAction,
+                                     reloadOneAction: reloadOneAction)
+            }, tag: 3, selection: $buttonSelected
+            ) { EmptyView() }.frame(width: 0).opacity(0).hidden()           // 
TransactionsListView
+
+            BalanceRowView(amount: balance.available, sendAction: {
+                buttonSelected = 1      // will trigger SendAmount 
NavigationLink
+            }, recvAction: {
+                buttonSelected = 2      // will trigger RequestPayment 
NavigationLink
+            }, rowAction: {
+                buttonSelected = 3      // will trigger TransactionList 
NavigationLink
+            })
+        }
+    }
+}
 // MARK: -
 #if DEBUG
 fileprivate struct BindingViewContainer : View {
@@ -214,7 +237,7 @@ fileprivate struct BindingViewContainer : View {
     @State private var summary: String = "bla-bla"
 
     var body: some View {
-        let scopeInfo = ScopeInfo(type: ScopeInfo.ScopeInfoType.exchange, 
exchangeBaseUrl: DEMOEXCHANGE, currency: LONGCURRENCY)
+        let scopeInfo = ScopeInfo(type: ScopeInfo.ScopeInfoType.exchange, url: 
DEMOEXCHANGE, currency: LONGCURRENCY)
         let balance = Balance(available: try! Amount(fromString: LONGCURRENCY 
+ ":0.1"),
                               scopeInfo: scopeInfo,
                       requiresUserInput: false,
diff --git a/TalerWallet1/Views/Exchange/ManualWithdraw.swift 
b/TalerWallet1/Views/Exchange/ManualWithdraw.swift
index 6077474..5486073 100644
--- a/TalerWallet1/Views/Exchange/ManualWithdraw.swift
+++ b/TalerWallet1/Views/Exchange/ManualWithdraw.swift
@@ -25,7 +25,7 @@ struct ManualWithdraw: View {
         let _ = Self._printChanges()
         let _ = symLog.vlog()       // just to get the # to compare it with 
.onAppear & onDisappear
 #endif
-        let currency = exchange.currency!
+        let currency = exchange.currency ?? String(localized: "Unknown", 
comment: "unknown currency")
         let navTitle = String(localized: "Withdraw \(currency)")
         let currencyField = CurrencyField(value: $centsToTransfer, currency: 
currency) // becomeFirstResponder
 //        let agePicker = AgePicker(ageMenuList: $ageMenuList, selectedAge: 
$selectedAge)
diff --git a/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift 
b/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
index dfacf5e..091a1ab 100644
--- a/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
+++ b/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
@@ -15,13 +15,27 @@ struct QRCodeDetailView: View {
     var body: some View {
         if talerURI.count > 10 {
             VStack (alignment: .leading) {
+                Text("Either copy and send this link:")
+                    .multilineTextAlignment(.leading)
+                    .font(.title3)
+                    .padding(.vertical)
+
+                Text(talerURI)
+                    .multilineTextAlignment(.center)
+                    .fixedSize(horizontal: false, vertical: true)       // 
wrap in scrollview
+                    .padding(.bottom)
+
+                CopyShare(textToCopy: talerURI)
+                    .disabled(false)
+                    .padding(.bottom)
+
                 // TODO: use currency formatter instead of .readableDescription
                 let amountStr = (amount == nil) ?
-                    (incoming ? String(localized: "Let the payer scan this QR 
code to pay:")
-                              : String(localized: "Let the payee scan this QR 
code to receive:"))
-                :   (incoming ? String(localized: "Let the payer scan this QR 
code to pay \(amount!.readableDescription):",
+                    (incoming ? String(localized: "or let the payer scan this 
QR code to pay:")
+                              : String(localized: "or let the payee scan this 
QR code to receive:"))
+                :   (incoming ? String(localized: "or let the payer scan this 
QR code to pay \(amount!.readableDescription):",
                                        comment: "amount.readableDescription: 
5,3 €")
-                              : String(localized: "Let the payee scan this QR 
code to receive \(amount!.readableDescription):",
+                              : String(localized: "or let the payee scan this 
QR code to receive \(amount!.readableDescription):",
                                        comment: "amount.readableDescription: 
7.41 $"))
                 Text(amountStr)
                     .fixedSize(horizontal: false, vertical: true)       // 
wrap in scrollview
@@ -32,19 +46,6 @@ struct QRCodeDetailView: View {
                     QRGeneratorView(text: talerURI)
                     Spacer()
                 }
-
-                Text("Alternatively, copy and send this link:")
-                    .multilineTextAlignment(.leading)
-                    .font(.title3)
-                    .padding(.vertical)
-
-                Text(talerURI)
-                    .multilineTextAlignment(.center)
-                    .fixedSize(horizontal: false, vertical: true)       // 
wrap in scrollview
-                    .padding(.bottom)
-
-                CopyShare(textToCopy: talerURI)
-                    .disabled(false)
             }
         }
     }
diff --git a/TalerWallet1/Views/HelperViews/SelectDays.swift 
b/TalerWallet1/Views/HelperViews/SelectDays.swift
index 208c4e2..95a7182 100644
--- a/TalerWallet1/Views/HelperViews/SelectDays.swift
+++ b/TalerWallet1/Views/HelperViews/SelectDays.swift
@@ -65,9 +65,9 @@ struct SelectDays: View {
     }
 }
 
-struct SelectDays_Previews: PreviewProvider {
-    static var previews: some View {
-        @State var expireDays: UInt = 1
-        SelectDays(selected: $expireDays, maxExpiration: 20)
-    }
-}
+//struct SelectDays_Previews: PreviewProvider {
+//    static var previews: some View {
+//        @State var expireDays: UInt = 1
+//        SelectDays(selected: $expireDays, maxExpiration: 20)
+//    }
+//}
diff --git a/TalerWallet1/Views/Payment/DeleteMe.swift 
b/TalerWallet1/Views/Payment/DeleteMe.swift
deleted file mode 100644
index 1ff5352..0000000
--- a/TalerWallet1/Views/Payment/DeleteMe.swift
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * This file is part of GNU Taler, ©2022-23 Taler Systems S.A.
- * See LICENSE.md
- */
-import SwiftUI
-import taler_swift
-import AVFoundation
-import SymLog
-
-struct PaymentAcceptView: View {
-    private let symLog = SymLogV()
-
-    let detailsForUri: PaymentDetailsForUri
-    let acceptAction: () -> Void
-
-    let navTitle = String(localized: "Accept Payment")
-
-    @State private var disabled = false
-    var body: some View {
-        Group {
-            let raw = detailsForUri.amountRaw
-            let effective = detailsForUri.amountEffective
-            let currency = raw.currencyStr
-            let fee = try! Amount.diff(raw, effective)      // TODO: different 
currencies
-            ThreeAmountsView(topTitle: String(localized: "Amount to pay:"),
-                             topAmount: raw, fee: fee,
-                             bottomTitle: String(localized: "\(currency) to be 
spent:"),
-                             bottomAmount: effective,
-                             large: true, pending: false, incoming: false,
-                             baseURL: 
detailsForUri.contractTerms.exchanges.first?.url)
-                // TODO: payment: popup with all possible exchanges, check fees
-            .safeAreaInset(edge: .bottom) {
-                Button(String(localized: "Accept"), action: acceptAction)
-                    .buttonStyle(TalerButtonStyle(type: .prominent))
-                    .padding(.horizontal)
-            }
-        }
-            .navigationTitle(navTitle)
-    }
-}
-// MARK: -
-struct PaymentAccept_Previews: PreviewProvider {
-    static var previews: some View {
-        let merchant = Merchant(name: "Merchant")
-        let extra = Extra(articleName: "articleName")
-        let product = Product(description: "description")
-        let terms = ContractTerms(amount: try! Amount(fromString: LONGCURRENCY 
+ ":2.2"),
-                                  maxFee: try! Amount(fromString: LONGCURRENCY 
+ ":0.2"),
-                                  maxWireFee: try! Amount(fromString: 
LONGCURRENCY + ":0.2"),
-                                  merchant: merchant,
-                                  extra: extra,
-                                  summary: "summary",
-                                  timestamp: Timestamp.now(),
-                                  payDeadline: Timestamp.tomorrow(),
-                                  refundDeadline: Timestamp.tomorrow(),
-                                  wireTransferDeadline: Timestamp.tomorrow(),
-                                  merchantBaseURL: "merchantBaseURL",
-                                  fulfillmentURL: "fulfillmentURL",
-                                  publicReorderURL: "publicReorderURL",
-                                  auditors: [],
-                                  exchanges: [],
-                                  orderID: "orderID",
-                                  nonce: "nonce",
-                                  merchantPub: "merchantPub",
-                                  products: [product],
-                                  hWire: "hWire",
-                                  wireMethod: "wireMethod",
-                                  wireFeeAmortization: 0)
-        let details = PaymentDetailsForUri(
-            amountRaw: try! Amount(fromString: LONGCURRENCY + ":2.2"),
-            amountEffective: try! Amount(fromString: LONGCURRENCY + ":2.4"),
-            noncePriv: "noncePriv",
-            proposalId: "proposalId",
-            contractTerms: terms,
-            contractTermsHash: "termsHash"
-        )
-        PaymentAcceptView(detailsForUri: details, acceptAction: {})
-    }
-}
diff --git a/TalerWallet1/Views/Payment/PaymentURIView.swift 
b/TalerWallet1/Views/Payment/PayTemplateView.swift
similarity index 58%
copy from TalerWallet1/Views/Payment/PaymentURIView.swift
copy to TalerWallet1/Views/Payment/PayTemplateView.swift
index 4b0150d..526d0b0 100644
--- a/TalerWallet1/Views/Payment/PaymentURIView.swift
+++ b/TalerWallet1/Views/Payment/PayTemplateView.swift
@@ -8,7 +8,7 @@ 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 PaymentURIView: View {
+struct PayTemplateView: View {
     private let symLog = SymLogV()
     let navTitle = String(localized: "Confirm Payment", comment:"pay merchant")
 
@@ -24,7 +24,7 @@ struct PaymentURIView: View {
         Task {
             do {
                 let confirmPayResult = try await 
model.confirmPayM(preparePayResult.transactionId)
-//                symLog.log(confirmPayResult as Any)
+                //                symLog.log(confirmPayResult as Any)
                 if confirmPayResult.type != "done" {
                     controller.playSound(0)
                     // TODO: show error
@@ -40,6 +40,13 @@ struct PaymentURIView: View {
 
     @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
@@ -84,6 +91,10 @@ struct PaymentURIView: View {
                 }
             }
             .navigationTitle(navTitle)
+            .onAppear() {
+                symLog.log("onAppear")
+                DebugViewC.shared.setSheetID(SHEET_PAY_TEMPLATE)
+            }
         } else {
             let badURL = "Error in Link: \(url)"
             WithdrawProgressView(message: url.host ?? badURL)
@@ -91,7 +102,7 @@ struct PaymentURIView: View {
                 .task {
                     do {
                         symLog.log(".task")
-                        let result = try await 
model.preparePayForUriM(url.absoluteString)
+                        let result = try await 
model.preparePayForTemplateM(url.absoluteString)
                         preparePayResult = result
                     } catch {    // TODO: error
                         symLog.log(error.localizedDescription)
@@ -100,54 +111,3 @@ struct PaymentURIView: View {
         }
     }
 }
-// MARK: -
-struct PaymentURIView_Previews: PreviewProvider {
-    static var previews: some View {
-        let merchant = Merchant(name: "Merchant")
-        let extra = Extra(articleName: "articleName")
-        let product = Product(description: "description")
-        let terms = MerchantContractTerms(hWire: "hWire",
-                                          wireMethod: "wireMethod",
-                                          summary: "summary",
-                                            summaryI18n: nil,
-                                          nonce: "nonce",
-                                          amount: try! Amount(fromString: 
LONGCURRENCY + ":2.2"),
-                                          payDeadline: Timestamp.tomorrow(),
-                                          maxFee: try! Amount(fromString: 
LONGCURRENCY + ":0.2"),
-                                          merchant: merchant,
-                                          merchantPub: "merchantPub",
-                                            deliveryDate: nil,
-                                            deliveryLocation: nil,
-                                          exchanges: [],
-                                          products: [product],
-                                          refundDeadline: Timestamp.tomorrow(),
-                                          wireTransferDeadline: 
Timestamp.tomorrow(),
-                                          timestamp: Timestamp.now(),
-                                          orderID: "orderID",
-                                          merchantBaseURL: "merchantBaseURL",
-                                            fulfillmentURL: "fulfillmentURL",
-                                            publicReorderURL: 
"publicReorderURL",
-                                            fulfillmentMessage: nil,
-                                            fulfillmentMessageI18n: nil,
-                                          wireFeeAmortization: 0,
-                                          maxWireFee: try! Amount(fromString: 
LONGCURRENCY + ":0.2"),
-                                            minimumAge: nil,
-                                          extra: extra
-//                                          auditors: [],
-                                  )
-        let details = PreparePayResult(
-            status: PreparePayResultType.paymentPossible,
-            transactionId: "txn:payment:012345",
-            contractTerms: terms,
-            contractTermsHash: "termsHash",
-            amountRaw: try! Amount(fromString: LONGCURRENCY + ":2.2"),
-            amountEffective: try! Amount(fromString: LONGCURRENCY + ":2.4"),
-            balanceDetails: nil,
-            paid: nil
-//        ,   talerUri: "talerURI"
-        )
-        let url = URL(string: "taler://pay/some_amount")!
-        
-        PaymentURIView(url: url, preparePayResult: details)
-    }
-}
diff --git a/TalerWallet1/Views/Payment/PaymentURIView.swift 
b/TalerWallet1/Views/Payment/PaymentView.swift
similarity index 96%
rename from TalerWallet1/Views/Payment/PaymentURIView.swift
rename to TalerWallet1/Views/Payment/PaymentView.swift
index 4b0150d..27db640 100644
--- a/TalerWallet1/Views/Payment/PaymentURIView.swift
+++ b/TalerWallet1/Views/Payment/PaymentView.swift
@@ -8,7 +8,7 @@ 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 PaymentURIView: View {
+struct PaymentView: View {
     private let symLog = SymLogV()
     let navTitle = String(localized: "Confirm Payment", comment:"pay merchant")
 
@@ -84,6 +84,10 @@ struct PaymentURIView: View {
                 }
             }
             .navigationTitle(navTitle)
+            .onAppear() {
+                symLog.log("onAppear")
+                DebugViewC.shared.setSheetID(SHEET_PAYMENT)
+            }
         } else {
             let badURL = "Error in Link: \(url)"
             WithdrawProgressView(message: url.host ?? badURL)
@@ -148,6 +152,6 @@ struct PaymentURIView_Previews: PreviewProvider {
         )
         let url = URL(string: "taler://pay/some_amount")!
         
-        PaymentURIView(url: url, preparePayResult: details)
+        PaymentView(url: url, preparePayResult: details)
     }
 }
diff --git a/TalerWallet1/Views/Peer2peer/PaymentPurpose.swift 
b/TalerWallet1/Views/Peer2peer/PaymentPurpose.swift
index 373aceb..eb4a054 100644
--- a/TalerWallet1/Views/Peer2peer/PaymentPurpose.swift
+++ b/TalerWallet1/Views/Peer2peer/PaymentPurpose.swift
@@ -95,17 +95,17 @@ struct PaymentPurpose: View {
 }
 // MARK: -
 #if DEBUG
-struct PaymentPurpose_Previews: PreviewProvider {
-    static var previews: some View {
-        let scopeInfo = ScopeInfo(type: ScopeInfo.ScopeInfoType.exchange, 
exchangeBaseUrl: DEMOEXCHANGE, currency: LONGCURRENCY)
-        @State var summary: String = "pUrPoSe"
-        @State var expireDays: UInt = 0
-        PaymentPurpose(scopeInfo: scopeInfo,
-                 centsToTransfer: 5,
-                             fee: "fee",
-                         summary: $summary,
-                      expireDays: $expireDays)
+//struct PaymentPurpose_Previews: PreviewProvider {
+//    static var previews: some View {
+//        let scopeInfo = ScopeInfo(type: ScopeInfo.ScopeInfoType.exchange, 
exchangeBaseUrl: DEMOEXCHANGE, currency: LONGCURRENCY)
+//        @State var summary: String = "pUrPoSe"
+//        @State var expireDays: UInt = 0
+//        PaymentPurpose(scopeInfo: scopeInfo,
+//                 centsToTransfer: 5,
+//                             fee: "fee",
+//                         summary: $summary,
+//                      expireDays: $expireDays)
 //        { print("deactivateAction") }
-    }
-}
+//    }
+//}
 #endif
diff --git a/TalerWallet1/Views/Peer2peer/SendPurpose.swift 
b/TalerWallet1/Views/Peer2peer/SendPurpose.swift
index fa8202b..463d79c 100644
--- a/TalerWallet1/Views/Peer2peer/SendPurpose.swift
+++ b/TalerWallet1/Views/Peer2peer/SendPurpose.swift
@@ -103,17 +103,17 @@ struct SendPurpose: View {
 }
 // MARK: -
 #if DEBUG
-struct SendPurpose_Previews: PreviewProvider {
-    static var previews: some View {
-        @State var summary: String = ""
-        @State var expireDays: UInt = 0
-        let amount = Amount(currency: LONGCURRENCY, integer: 10, fraction: 0)
-        SendPurpose(amountAvailable: amount,
-                    centsToTransfer: 543,
-                                fee: "0,43",
-                            summary: $summary,
-                         expireDays: $expireDays)
+//struct SendPurpose_Previews: PreviewProvider {
+//    static var previews: some View {
+//        @State var summary: String = ""
+//        @State var expireDays: UInt = 0
+//        let amount = Amount(currency: LONGCURRENCY, integer: 10, fraction: 0)
+//        SendPurpose(amountAvailable: amount,
+//                    centsToTransfer: 543,
+//                                fee: "0,43",
+//                            summary: $summary,
+//                         expireDays: $expireDays)
 //        { print("deactivateAction") }
-    }
-}
+//    }
+//}
 #endif
diff --git a/TalerWallet1/Views/Settings/SettingsItem.swift 
b/TalerWallet1/Views/Settings/SettingsItem.swift
index b8443fe..df26904 100644
--- a/TalerWallet1/Views/Settings/SettingsItem.swift
+++ b/TalerWallet1/Views/Settings/SettingsItem.swift
@@ -56,13 +56,58 @@ struct SettingsToggle: View {
     }
 }
 // MARK: -
+struct SettingsSpeaker: View {
+    var name: String
+    @Binding var value: Int
+    var description: String?
+    var action: (_ value: Int) -> Void = {value in }
+
+    var body: some View {
+        VStack {
+            let image = (value == 0) ? "speaker.slash"
+                      : (value == 1) ? "speaker.fill"
+                                     : "speaker"
+            HStack {
+                Text(name)
+                    .font(.title2)
+                Text(" ")
+                    .font(.largeTitle)
+                Spacer()
+                Image(systemName: image)
+                    .font(.largeTitle)
+                    .onTapGesture {
+                        if value > 0 {
+                            value = -1
+                        } else {
+                            value = value + 1
+                        }
+                    }
+            }
+//                .onChange(of: value) { value in
+//                    action(value)
+//                }
+
+            if let desc = description {
+                Text(desc)
+                    .frame(maxWidth: .infinity, alignment: .leading)
+                    .font(.caption)
+            }
+        }.padding([.bottom], 4)
+    }
+}
+// MARK: -
 #if DEBUG
 struct SettingsItemPreview : View {
     @State var developerMode: Bool = false
+    @State var playSounds: Int = 0
 
     var body: some View {
         VStack {
-            SettingsToggle(name: "Developer Mode", value: $developerMode, 
description: "More information intended for debugging")
+            SettingsToggle(name: "Developer Mode", value: $developerMode,
+                    description: "More information intended for debugging")
+            SettingsSpeaker(name: String(localized: "Play Payment Sounds"), 
value: $playSounds,
+                     description: String(localized: "After a transaction 
finished"))
+
         }
     }
 }
diff --git a/TalerWallet1/Views/Settings/SettingsView.swift 
b/TalerWallet1/Views/Settings/SettingsView.swift
index ee7d4e6..e9c458b 100644
--- a/TalerWallet1/Views/Settings/SettingsView.swift
+++ b/TalerWallet1/Views/Settings/SettingsView.swift
@@ -26,7 +26,7 @@ struct SettingsView: View {
 #else
     @AppStorage("developerMode") var developerMode: Bool = false
 #endif
-    @AppStorage("playSounds") var playSounds: Bool = false
+    @AppStorage("playSounds") var playSounds: Int = 0
     @AppStorage("developDelay") var developDelay: Bool = false
     @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
 
@@ -73,8 +73,8 @@ struct SettingsView: View {
         let walletCore = WalletCore.shared
         Group {
             List {
-                SettingsToggle(name: String(localized: "Play Payment Sounds"), 
value: $playSounds,
-                        description: String(localized: "After a transaction 
finished"))
+                SettingsSpeaker(name: String(localized: "Play Payment 
Sounds"), value: $playSounds,
+                         description: String(localized: "After a transaction 
finished"))
                 HStack {
                     Text("Liststyle:")
                         .font(.title2)
diff --git a/TalerWallet1/Views/Sheets/URLSheet.swift 
b/TalerWallet1/Views/Sheets/URLSheet.swift
index 4a3cacd..1db6169 100644
--- a/TalerWallet1/Views/Sheets/URLSheet.swift
+++ b/TalerWallet1/Views/Sheets/URLSheet.swift
@@ -19,12 +19,16 @@ struct URLSheet: View {
                 case .withdraw:
                     WithdrawURIView(url: urlToOpen)
                 case .pay:
-                    PaymentURIView(url: urlToOpen)
+                    PaymentView(url: urlToOpen)
                 case .payPull:
                     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)
diff --git a/TalerWallet1/Views/Transactions/ManualDetails.swift 
b/TalerWallet1/Views/Transactions/ManualDetails.swift
index 6663ef1..b788072 100644
--- a/TalerWallet1/Views/Transactions/ManualDetails.swift
+++ b/TalerWallet1/Views/Transactions/ManualDetails.swift
@@ -14,31 +14,39 @@ struct ManualDetails: View {
             let payURL = URL(string: payto)
             let iban = payURL?.iban ?? "unknown IBAN"
             let amount = common.amountRaw.readableDescription
-            Text("From your regular bank account, make a wire transfer of 
\(amount) to:")
+            Text("You need to transfer \(amount) from your regular bank 
account to the Exchange.")
+            Text("Step 1: Copy this code and paste it into the subject/purpose 
field in your banking app or bank website.\nThis is mandatory, otherwise your 
money will not arrive in this wallet.")
                 .multilineTextAlignment(.leading)
                 .listRowSeparator(.hidden)
             HStack {
-                Text(iban)
+                Text(details.reservePub)
                     .monospacedDigit()
+                    .accessibilityLabel("Cryptocode")
                 Spacer()
-                CopyButton(textToCopy: iban, vertical: true)
-                    .accessibilityLabel("Copy the IBAN")
+                CopyButton(textToCopy: details.reservePub, vertical: true)
+                    .accessibilityLabel("Copy the cryptocode")
                     .disabled(false)
             }   .padding(.leading)
-                .padding(.vertical, -8)
                 .listRowSeparator(.hidden)
-            Text("with the code below as subject to receive the money in this 
wallet:")
+            Text("Step 2: If you dont already have it in your banking 
favourites list, then copy and paste this IBAN into the receiver IBAN field in 
your banking app or website:")
                 .multilineTextAlignment(.leading)
                 .listRowSeparator(.hidden)
             HStack {
-                Text(details.reservePub)
+                Text(iban)
                     .monospacedDigit()
-                    .accessibilityLabel("Cryptocode")
                 Spacer()
-                CopyButton(textToCopy: details.reservePub, vertical: true)
-                    .accessibilityLabel("Copy the cryptocode")
+                CopyButton(textToCopy: iban, vertical: true)
+                    .accessibilityLabel("Copy the IBAN")
                     .disabled(false)
             }   .padding(.leading)
+                .padding(.top, -8)
+                .listRowSeparator(.hidden)
+            Text("Step 3: Finish the wire transfer of \(amount) in your 
banking app or website, then this withdrawal will proceed automatically.")
+                .multilineTextAlignment(.leading)
+                .listRowSeparator(.visible)
+            Text("Alternative: If your bank already supports PayTo, you can 
use this PayTo-Link instead:")
+                .multilineTextAlignment(.leading)
+                .padding(.top, 2)
                 .listRowSeparator(.hidden)
             HStack {
                 Text(verbatim: "|")       // only reason for this 
leading-aligned text is to get a nice full length listRowSeparator
diff --git a/TalerWallet1/Views/Transactions/ThreeAmounts.swift 
b/TalerWallet1/Views/Transactions/ThreeAmounts.swift
index 8f2287a..7b1397b 100644
--- a/TalerWallet1/Views/Transactions/ThreeAmounts.swift
+++ b/TalerWallet1/Views/Transactions/ThreeAmounts.swift
@@ -46,9 +46,6 @@ struct ThreeAmountsView: View {
         let labelColor = Color(UIColor.label)
         let foreColor = pending ? WalletColors().pendingColor(incoming)
                                 : WalletColors().transactionColor(incoming)
-        let feeColor = WalletColors().transactionColor(false)
-        let feeSign = incoming ? "-" : "+"
-
         VStack {
             AmountView(title: topTitle,
                        value: topAmount.readableDescription,
@@ -56,9 +53,10 @@ struct ThreeAmountsView: View {
                        large: large)
                 .padding(.bottom, 4)
             if let fee {
-                AmountView(title: "Exchange fee:",
-                           value: feeSign + fee.readableDescription,
-                           color: fee.isZero ? labelColor : feeColor,
+                let feeSign = incoming ? "- " : "+ "
+                AmountView(title: feeSign + String(localized: "Exchange fee:"),
+                           value: fee.readableDescription,
+                           color: labelColor,
                            large: false)
                 .padding(.bottom, 4)
             }
@@ -68,7 +66,7 @@ struct ThreeAmountsView: View {
                        large: large)
             if let baseURL {
                 VStack(alignment: .leading) {
-                    Text(incoming ? "from Exchange:" : "to Exchange:")
+                    Text("Using Exchange:")
                         .multilineTextAlignment(.leading)
                         .font(.body)
                     HStack {
diff --git a/TalerWallet1/Views/Transactions/TransactionDetailView.swift 
b/TalerWallet1/Views/Transactions/TransactionDetailView.swift
index bb2f404..3178519 100644
--- a/TalerWallet1/Views/Transactions/TransactionDetailView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionDetailView.swift
@@ -52,9 +52,7 @@ struct TransactionDetailView: View {
         let common = transaction.common
         let pending = transaction.isPending
         let dateString = TalerDater.dateString(from: common.timestamp)
-        let localizedType = transaction.localizedType
-        let navTitle2 = pending ? String(localized: "Pending")
-                               : localizedType
+        let navTitle2 = transaction.localizedType
         Group {
             List {
                 if developerMode {
@@ -224,10 +222,6 @@ struct TransactionDetailView: View {
                         let details = rewardTransaction.details                
 // TODO: more details
                         ThreeAmountsSheet(common: common, topTitle: 
String(localized: "Received Reward:"),
                                          baseURL: details.exchangeBaseUrl, 
large: true)
-//                case .tip(let tipTransaction):
-//                    let details = tipTransaction.details                  // 
TODO: details
-//                    ThreeAmountsSheet(common: common, topTitle: 
String(localized: "Received Tip:"),
-//                                      baseURL: nil, large: true)
                     case .refresh(let refreshTransaction):
                         let details = refreshTransaction.details               
 // TODO: details
                         ThreeAmountsSheet(common: common, topTitle: 
String(localized: "Refreshed amount:"),
diff --git a/TestFlight/WhatToTest.en-US.txt b/TestFlight/WhatToTest.en-US.txt
index 6b0aa3b..6fb04f7 100644
--- a/TestFlight/WhatToTest.en-US.txt
+++ b/TestFlight/WhatToTest.en-US.txt
@@ -1,4 +1,11 @@
 
+Version 0.9.3 (17)
+
+• New Feature: Payment Sounds from carlo von lynX
+
+- Usability improved for manual withdrawal + P2P
+
+
 Version 0.9.3 (16)
 
 • Switch on Developer Mode in Settings, then

-- 
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]