[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-ios] branch master updated (4167b6d -> 4e7f6ff)
From: |
gnunet |
Subject: |
[taler-taler-ios] branch master updated (4167b6d -> 4e7f6ff) |
Date: |
Sat, 10 Feb 2024 15:04:26 +0100 |
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 4167b6d Bump version to 0.9.4 (1)
new 97d7bbd remove Mac support
new 803cb7e TransactionSummaryV
new c38420b Settings, About
new 96736e7 Fake Euro
new f2a4f7e Bump version to 0.9.4 (2)
new c26d217 Cleanup, logging
new d5038ac PaymentDone
new 35d8752 Past Tense
new 6d808db Deposit
new 5c236f1 ScrollVStack
new cb8db09 Identifiable
new 8e12799 devExperiment Refresh
new f335830 ScrollVStack
new ed13c1a shouldReloadBalances
new a96b0f3 githash 7 chars
new 2b12596 wording
new c828ee8 currency formatter
new 52ae044 Dismiss P2P without showing details again
new faccb37 Show merchant in payment details
new d2f60e6 wording
new 8aa2eb2 minimalistic
new 19745a2 CallStack
new 2f07168 TransactionDetailV
new 17e0e92 static func <
new 4eea188 use ScopeInfo
new 17fca55 more scopeInfo
new 8bcbb7d don't dismiss after done
new 19d17ba RotatingTaler while waiting for tx to finish
new 400ad71 cleanup
new 6978983 Bump version to 0.9.4 (3)
new 6776327 Wording
new 4e7f6ff remove reward
The 32 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 | 34 ++++--
TalerWallet1/Backend/WalletBackendRequest.swift | 62 +++++------
TalerWallet1/Backend/WalletCore.swift | 2 +-
TalerWallet1/Controllers/Controller.swift | 2 +-
TalerWallet1/Controllers/DebugViewC.swift | 18 +--
TalerWallet1/Controllers/PublicConstants.swift | 6 +-
TalerWallet1/Helper/CurrencySpecification.swift | 12 ++
TalerWallet1/Model/Model+Exchange.swift | 9 ++
TalerWallet1/Model/Model+Transactions.swift | 12 +-
TalerWallet1/Model/Transaction.swift | 73 +++++++-----
TalerWallet1/Model/WalletModel.swift | 43 ++++++-
TalerWallet1/Views/Balances/BalanceRowView.swift | 10 +-
TalerWallet1/Views/Balances/BalancesListView.swift | 5 +-
.../Views/Balances/BalancesSectionView.swift | 49 ++++----
TalerWallet1/Views/Balances/PendingRowView.swift | 6 +-
TalerWallet1/Views/Banking/ExchangeListView.swift | 104 ++++++-----------
TalerWallet1/Views/Banking/ExchangeRowView.swift | 8 +-
.../Views/Banking/ExchangeSectionView.swift | 31 ++++--
TalerWallet1/Views/Banking/ManualWithdraw.swift | 12 +-
.../Views/Banking/ManualWithdrawDone.swift | 2 +-
TalerWallet1/Views/HelperViews/BarGraph.swift | 26 +++--
TalerWallet1/Views/HelperViews/Buttons.swift | 44 ++++----
.../Views/HelperViews/QRCodeDetailView.swift | 23 +++-
TalerWallet1/Views/HelperViews/ToSButtonView.swift | 8 +-
TalerWallet1/Views/Main/MainView.swift | 10 +-
TalerWallet1/Views/Peer2peer/P2PReadyV.swift | 13 ++-
TalerWallet1/Views/Peer2peer/P2PSubjectV.swift | 7 +-
TalerWallet1/Views/Peer2peer/RequestPayment.swift | 8 +-
TalerWallet1/Views/Peer2peer/SendAmount.swift | 8 +-
TalerWallet1/Views/Settings/AboutView.swift | 51 ++++++---
TalerWallet1/Views/Settings/SettingsView.swift | 33 +++++-
.../Views/Sheets/P2P_Sheets/P2pAcceptDone.swift | 24 +---
.../Views/Sheets/P2P_Sheets/P2pPayURIView.swift | 17 ++-
.../Sheets/P2P_Sheets/P2pReceiveURIView.swift | 21 ++--
.../Views/Sheets/Payment/PayTemplateView.swift | 18 +--
.../Views/Sheets/Payment/PaymentDone.swift | 77 +++++++++++++
.../Views/Sheets/Payment/PaymentView.swift | 73 ++++++------
.../Views/Sheets/Refund/RefundURIView.swift | 4 +-
TalerWallet1/Views/Sheets/URLSheet.swift | 2 -
.../WithdrawAcceptDone.swift | 2 +-
.../WithdrawBankIntegrated/WithdrawURIView.swift | 17 ++-
TalerWallet1/Views/Sheets/WithdrawExchangeV.swift | 1 +
.../Views/Transactions/ManualDetailsV.swift | 31 +++---
.../Views/Transactions/ThreeAmountsV.swift | 70 +++++++-----
.../Views/Transactions/TransactionDetailV.swift | 52 +++++++++
.../Views/Transactions/TransactionRowView.swift | 21 +++-
...nDetailView.swift => TransactionSummaryV.swift} | 123 ++++++++++++---------
.../Views/Transactions/TransactionsEmptyView.swift | 4 +-
.../Views/Transactions/TransactionsListView.swift | 14 +--
TestFlight/WhatToTest.en-US.txt | 16 +++
50 files changed, 823 insertions(+), 495 deletions(-)
create mode 100644 TalerWallet1/Views/Sheets/Payment/PaymentDone.swift
create mode 100644 TalerWallet1/Views/Transactions/TransactionDetailV.swift
rename TalerWallet1/Views/Transactions/{TransactionDetailView.swift =>
TransactionSummaryV.swift} (79%)
diff --git a/TalerWallet.xcodeproj/project.pbxproj
b/TalerWallet.xcodeproj/project.pbxproj
index 1739f81..6c1064a 100644
--- a/TalerWallet.xcodeproj/project.pbxproj
+++ b/TalerWallet.xcodeproj/project.pbxproj
@@ -89,7 +89,7 @@
4E3EAE5F2A990778009F1BE8 /* QRSheet.swift in Sources */ = {isa
= PBXBuildFile; fileRef = 4EEC157929F9427F00D46A03 /* QRSheet.swift */; };
4E3EAE602A990778009F1BE8 /* P2pReceiveURIView.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4E3B4BC02A41E6C200CC88B8 /*
P2pReceiveURIView.swift */; };
4E3EAE612A990778009F1BE8 /* ListStyle.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E6EDD862A363D8D0031D520 /* ListStyle.swift */;
};
- 4E3EAE622A990778009F1BE8 /* TransactionDetailView.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EB095312989CBFE0043A8A1 /*
TransactionDetailView.swift */; };
+ 4E3EAE622A990778009F1BE8 /* TransactionSummaryV.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EB095312989CBFE0043A8A1 /*
TransactionSummaryV.swift */; };
4E3EAE632A990778009F1BE8 /* WalletCore.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0951C2989CBCB0043A8A1 /* WalletCore.swift */;
};
4E3EAE642A990778009F1BE8 /* LaunchAnimationView.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EB095432989CBFE0043A8A1 /*
LaunchAnimationView.swift */; };
4E3EAE682A990778009F1BE8 /* WalletModel.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095112989CBB00043A8A1 /* WalletModel.swift
*/; };
@@ -150,6 +150,10 @@
4E605DBB2AB05FB6002FB9A7 /* BarGraph.swift in Sources */ = {isa
= PBXBuildFile; fileRef = 4E605DB92AB05FB6002FB9A7 /* BarGraph.swift */; };
4E6EDD852A3615BE0031D520 /* ManualDetailsV.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4E6EDD842A3615BE0031D520 /*
ManualDetailsV.swift */; };
4E6EDD872A363D8D0031D520 /* ListStyle.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E6EDD862A363D8D0031D520 /* ListStyle.swift */;
};
+ 4E6EF56B2B65A33300AF252A /* PaymentDone.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E6EF56A2B65A33300AF252A /* PaymentDone.swift
*/; };
+ 4E6EF56C2B65A33300AF252A /* PaymentDone.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E6EF56A2B65A33300AF252A /* PaymentDone.swift
*/; };
+ 4E6EF56E2B669C7000AF252A /* TransactionDetailV.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4E6EF56D2B669C7000AF252A /*
TransactionDetailV.swift */; };
+ 4E6EF56F2B669C7000AF252A /* TransactionDetailV.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4E6EF56D2B669C7000AF252A /*
TransactionDetailV.swift */; };
4E753A062A0952F8002D9328 /* DebugViewC.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E753A052A0952F7002D9328 /* DebugViewC.swift */;
};
4E753A082A0B6A5F002D9328 /* ShareSheet.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E753A072A0B6A5F002D9328 /* ShareSheet.swift */;
};
4E7940DE29FC307C00A9AEA1 /* P2PSubjectV.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E7940DD29FC307C00A9AEA1 /* P2PSubjectV.swift
*/; };
@@ -197,7 +201,7 @@
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 */; };
+ 4EB095582989CBFE0043A8A1 /* TransactionSummaryV.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EB095312989CBFE0043A8A1 /*
TransactionSummaryV.swift */; };
4EB095592989CBFE0043A8A1 /* Model+Transactions.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB095322989CBFE0043A8A1 /*
Model+Transactions.swift */; };
4EB0955A2989CBFE0043A8A1 /* URLSheet.swift in Sources */ = {isa
= PBXBuildFile; fileRef = 4EB095332989CBFE0043A8A1 /* URLSheet.swift */; };
4EB0955C2989CBFE0043A8A1 /* BalanceRowView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095362989CBFE0043A8A1 /*
BalanceRowView.swift */; };
@@ -328,6 +332,8 @@
4E605DB92AB05FB6002FB9A7 /* BarGraph.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= BarGraph.swift; sourceTree = "<group>"; };
4E6EDD842A3615BE0031D520 /* ManualDetailsV.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= ManualDetailsV.swift; sourceTree = "<group>"; };
4E6EDD862A363D8D0031D520 /* ListStyle.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= ListStyle.swift; sourceTree = "<group>"; };
+ 4E6EF56A2B65A33300AF252A /* PaymentDone.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path =
PaymentDone.swift; sourceTree = "<group>"; };
+ 4E6EF56D2B669C7000AF252A /* TransactionDetailV.swift */ = {isa
= PBXFileReference; lastKnownFileType = sourcecode.swift; path =
TransactionDetailV.swift; sourceTree = "<group>"; };
4E753A042A08E720002D9328 /* transactions.json */ = {isa =
PBXFileReference; lastKnownFileType = text.json; path = transactions.json;
sourceTree = "<group>"; };
4E753A052A0952F7002D9328 /* DebugViewC.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= DebugViewC.swift; sourceTree = "<group>"; };
4E753A072A0B6A5F002D9328 /* ShareSheet.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= ShareSheet.swift; sourceTree = "<group>"; };
@@ -375,7 +381,7 @@
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>"; };
+ 4EB095312989CBFE0043A8A1 /* TransactionSummaryV.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = TransactionSummaryV.swift; sourceTree = "<group>"; };
4EB095322989CBFE0043A8A1 /* Model+Transactions.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = "Model+Transactions.swift"; sourceTree = "<group>"; };
4EB095332989CBFE0043A8A1 /* URLSheet.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= URLSheet.swift; sourceTree = "<group>"; };
4EB095362989CBFE0043A8A1 /* BalanceRowView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= BalanceRowView.swift; sourceTree = "<group>"; };
@@ -679,6 +685,7 @@
isa = PBXGroup;
children = (
4EB0952D2989CBFE0043A8A1 /* PaymentView.swift
*/,
+ 4E6EF56A2B65A33300AF252A /* PaymentDone.swift
*/,
4EBA56402A7FF5200084948B /*
PayTemplateView.swift */,
);
path = Payment;
@@ -689,7 +696,8 @@
children = (
4EB0952F2989CBFE0043A8A1 /*
TransactionsListView.swift */,
4EB095302989CBFE0043A8A1 /*
TransactionRowView.swift */,
- 4EB095312989CBFE0043A8A1 /*
TransactionDetailView.swift */,
+ 4EB095312989CBFE0043A8A1 /*
TransactionSummaryV.swift */,
+ 4E6EF56D2B669C7000AF252A /*
TransactionDetailV.swift */,
4E87C8722A31CB7F001C6406 /*
TransactionsEmptyView.swift */,
4E6EDD842A3615BE0031D520 /*
ManualDetailsV.swift */,
4ED2F94A2A278F5100453B40 /* ThreeAmountsV.swift
*/,
@@ -1101,6 +1109,7 @@
4EFA39602AA7946B00742548 /* ToSButtonView.swift
in Sources */,
4E3EAE4F2A990778009F1BE8 /* TwoRowButtons.swift
in Sources */,
4E3EAE502A990778009F1BE8 /*
Model+Transactions.swift in Sources */,
+ 4E6EF56E2B669C7000AF252A /*
TransactionDetailV.swift in Sources */,
4E3EAE512A990778009F1BE8 /*
Controller+playSound.swift in Sources */,
4E3EAE522A990778009F1BE8 /*
WalletEmptyView.swift in Sources */,
4E3EAE532A990778009F1BE8 /*
CurrencySpecification.swift in Sources */,
@@ -1120,7 +1129,7 @@
4E3EAE5F2A990778009F1BE8 /* QRSheet.swift in
Sources */,
4E3EAE602A990778009F1BE8 /*
P2pReceiveURIView.swift in Sources */,
4E3EAE612A990778009F1BE8 /* ListStyle.swift in
Sources */,
- 4E3EAE622A990778009F1BE8 /*
TransactionDetailView.swift in Sources */,
+ 4E3EAE622A990778009F1BE8 /*
TransactionSummaryV.swift in Sources */,
4E3EAE632A990778009F1BE8 /* WalletCore.swift in
Sources */,
4E3EAE642A990778009F1BE8 /*
LaunchAnimationView.swift in Sources */,
E37AA62A2AF197E5003850CF /* Model+Refund.swift
in Sources */,
@@ -1130,6 +1139,7 @@
4E3EAE6B2A990778009F1BE8 /*
Model+Withdraw.swift in Sources */,
4E3EAE6C2A990778009F1BE8 /*
ExchangeSectionView.swift in Sources */,
4E3EAE6D2A990778009F1BE8 /* P2PSubjectV.swift
in Sources */,
+ 4E6EF56B2B65A33300AF252A /* PaymentDone.swift
in Sources */,
4E3EAE6E2A990778009F1BE8 /* Model+P2P.swift in
Sources */,
4E3EAE6F2A990778009F1BE8 /* TalerStrings.swift
in Sources */,
4E3EAE702A990778009F1BE8 /*
CurrencyInputView.swift in Sources */,
@@ -1207,6 +1217,7 @@
4EFA39612AA7946B00742548 /* ToSButtonView.swift
in Sources */,
4EB065442A4CD1A80039B91D /* TwoRowButtons.swift
in Sources */,
4EB095592989CBFE0043A8A1 /*
Model+Transactions.swift in Sources */,
+ 4E6EF56F2B669C7000AF252A /*
TransactionDetailV.swift in Sources */,
4E578E922A481D8600F21F1C /*
Controller+playSound.swift in Sources */,
4EB0955F2989CBFE0043A8A1 /*
WalletEmptyView.swift in Sources */,
4E16E12329F3BB99008B9C86 /*
CurrencySpecification.swift in Sources */,
@@ -1226,7 +1237,7 @@
4EEC157A29F9427F00D46A03 /* QRSheet.swift in
Sources */,
4E3B4BC12A41E6C200CC88B8 /*
P2pReceiveURIView.swift in Sources */,
4E6EDD872A363D8D0031D520 /* ListStyle.swift in
Sources */,
- 4EB095582989CBFE0043A8A1 /*
TransactionDetailView.swift in Sources */,
+ 4EB095582989CBFE0043A8A1 /*
TransactionSummaryV.swift in Sources */,
4EB095202989CBCB0043A8A1 /* WalletCore.swift in
Sources */,
4EB095672989CBFE0043A8A1 /*
LaunchAnimationView.swift in Sources */,
E37AA62B2AF197E5003850CF /* Model+Refund.swift
in Sources */,
@@ -1236,6 +1247,7 @@
4EB095622989CBFE0043A8A1 /*
Model+Withdraw.swift in Sources */,
4EC90C782A1B528B0071DC58 /*
ExchangeSectionView.swift in Sources */,
4E7940DE29FC307C00A9AEA1 /* P2PSubjectV.swift
in Sources */,
+ 4E6EF56C2B65A33300AF252A /* PaymentDone.swift
in Sources */,
4ECB62802A0BA6DF004ABBB7 /* Model+P2P.swift in
Sources */,
4EB0950A2989CB7C0043A8A1 /* TalerStrings.swift
in Sources */,
4EA551252A2C923600FEC9A8 /*
CurrencyInputView.swift in Sources */,
@@ -1293,7 +1305,7 @@
CODE_SIGN_ENTITLEMENTS =
"$(TARGET_NAME).entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = GUDDQ9428Y;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1335,7 +1347,7 @@
CODE_SIGN_ENTITLEMENTS =
"$(TARGET_NAME).entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = GUDDQ9428Y;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1494,7 +1506,7 @@
CODE_SIGN_ENTITLEMENTS =
"$(TARGET_NAME).entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = GUDDQ9428Y;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1536,7 +1548,7 @@
CODE_SIGN_ENTITLEMENTS =
"$(TARGET_NAME).entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 1;
+ CURRENT_PROJECT_VERSION = 3;
DEVELOPMENT_TEAM = GUDDQ9428Y;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1632,6 +1644,7 @@
MARKETING_VERSION = 0.9.3;
PRODUCT_BUNDLE_IDENTIFIER =
com.taler.TalerUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_OBJC_BRIDGING_HEADER =
"TalerUITests/TalerUITests-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -1655,6 +1668,7 @@
MARKETING_VERSION = 0.9.3;
PRODUCT_BUNDLE_IDENTIFIER =
com.taler.TalerUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
+ SUPPORTS_MACCATALYST = NO;
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_OBJC_BRIDGING_HEADER =
"TalerUITests/TalerUITests-Bridging-Header.h";
TARGETED_DEVICE_FAMILY = "1,2";
diff --git a/TalerWallet1/Backend/WalletBackendRequest.swift
b/TalerWallet1/Backend/WalletBackendRequest.swift
index 9a95db2..124e855 100644
--- a/TalerWallet1/Backend/WalletBackendRequest.swift
+++ b/TalerWallet1/Backend/WalletBackendRequest.swift
@@ -34,6 +34,30 @@ struct ScopeInfo: Codable, Hashable {
var url: String? // only for "exchange"
var currency: String // 3-char ISO 4217 code for global currency.
Regional MUST be >= 4 letters
+ public static func < (lhs: ScopeInfo, rhs: ScopeInfo) -> Bool {
+ if lhs.type == .global {
+ if rhs.type == .global { // both global ==> alphabetic
currency
+ return lhs.currency < rhs.currency
+ }
+ return true // global comes first
+ }
+ if rhs.type == .global {
+ return false // global comes first
+ }
+ if lhs.currency == rhs.currency {
+ if let lhsBaseURL = lhs.url {
+ if let rhsBaseURL = rhs.url {
+ return lhsBaseURL < rhsBaseURL
+ }
+ return true
+ }
+ if let rhsBaseURL = rhs.url {
+ return false
+ }
+ // fall thru
+ }
+ return lhs.currency < rhs.currency
+ }
public static func == (lhs: ScopeInfo, rhs: ScopeInfo) -> Bool {
if let lhsBaseURL = lhs.url {
if let rhsBaseURL = rhs.url {
@@ -84,7 +108,7 @@ struct Tax: Codable {
/// A product being purchased from a merchant.
/// https://docs.taler.net/core/api-merchant.html#the-contract-terms
-struct Product: Codable {
+struct Product: Codable, Identifiable {
var product_id: String?
var description: String
// var description_i18n: ?
@@ -94,6 +118,8 @@ struct Product: Codable {
var image: String? // URL to a product image
var taxes: [Tax]?
var delivery_date: Timestamp?
+
+ var id: String { product_id ?? "unknown" }
}
/// Brief information about an order.
@@ -187,40 +213,6 @@ struct WalletBackendConfirmPayRequest:
WalletBackendFormattedRequest {
struct Response: Decodable {}
}
-
-// MARK: -
-/// The result from PrepareReward
-struct PrepareRewardResponse: Decodable {
- var walletRewardId: String
- var accepted: Bool
- var rewardAmountRaw: Amount
- var rewardAmountEffective: Amount
- var exchangeBaseUrl: String
- var expirationTimestamp: Timestamp
-}
-/// A request to prepare a reward.
-struct PrepareRewardRequest: WalletBackendFormattedRequest {
- typealias Response = PrepareRewardResponse
- func operation() -> String { "prepareReward" }
- func args() -> Args { Args(talerRewardUri: talerRewardUri) }
-
- var talerRewardUri: String
- struct Args: Encodable {
- var talerRewardUri: String
- }
-}
-// MARK: -
-/// A request to accept a reward.
-struct AcceptRewardRequest: WalletBackendFormattedRequest {
- struct Response: Decodable {}
- func operation() -> String { "acceptReward" }
- func args() -> Args { Args(walletRewardId: walletRewardId) }
-
- var walletRewardId: String
- struct Args: Encodable {
- var walletRewardId: String
- }
-}
// MARK: -
/// A request to abort a failed payment.
struct WalletBackendAbortFailedPaymentRequest: WalletBackendFormattedRequest {
diff --git a/TalerWallet1/Backend/WalletCore.swift
b/TalerWallet1/Backend/WalletCore.swift
index f081aac..d251897 100644
--- a/TalerWallet1/Backend/WalletCore.swift
+++ b/TalerWallet1/Backend/WalletCore.swift
@@ -388,7 +388,7 @@ extension WalletCore {
sendRequest(request: reqData) { requestId, timeSent, result, error
in
let timeUsed = Date.now - timeSent
let millisecs = timeUsed.milliseconds
- self.logger.info("Request \(requestId, privacy: .public) took
\(millisecs, privacy: .public) ms")
+ self.logger.info("Request \"id\":\(requestId, privacy:
.public) took \(millisecs, privacy: .public) ms")
var err: Error? = nil
if let json = result {
do {
diff --git a/TalerWallet1/Controllers/Controller.swift
b/TalerWallet1/Controllers/Controller.swift
index 78a3686..0aa2824 100644
--- a/TalerWallet1/Controllers/Controller.swift
+++ b/TalerWallet1/Controllers/Controller.swift
@@ -26,7 +26,6 @@ enum UrlCommand {
case payPush
case payTemplate
case refund
- case reward
}
// MARK: -
@@ -70,6 +69,7 @@ class Controller: ObservableObject {
}
func info(for currency: String) -> CurrencyInfo? {
+// return CurrencyInfo.euro() // FAKE EURO instead of the
real Currency
for info in currencyInfos {
if info.scope.currency == currency {
return info
diff --git a/TalerWallet1/Controllers/DebugViewC.swift
b/TalerWallet1/Controllers/DebugViewC.swift
index 33a15d5..3e9f9b8 100644
--- a/TalerWallet1/Controllers/DebugViewC.swift
+++ b/TalerWallet1/Controllers/DebugViewC.swift
@@ -30,21 +30,22 @@ public let VIEW_BALANCES = VIEW_EMPTY + 1
// 11 Balanc
public let VIEW_EXCHANGES = VIEW_BALANCES + 1 // 12
ExchangeListView
public let VIEW_SETTINGS = VIEW_EXCHANGES + 1 // 13
SettingsView
public let VIEW_ABOUT = VIEW_SETTINGS + 1 // 14
AboutView
-public let VIEW_PENDING = VIEW_ABOUT + 1 // 15
PendingOpsListView
+//public let VIEW_PENDING = VIEW_ABOUT + 1 // 15
PendingOpsListView
// MARK: Transactions
public let VIEW_TRANSACTIONLIST = VIEW_EMPTY + 10 // 20
TransactionsListView
-public let VIEW_TRANSACTIONDETAIL = VIEW_TRANSACTIONLIST + 1 // 21
TransactionDetail
+public let VIEW_TRANSACTIONSUMMARY = VIEW_TRANSACTIONLIST + 1 // 21
TransactionSummary
+public let VIEW_TRANSACTIONDETAIL = VIEW_TRANSACTIONSUMMARY + 1 // 22
TransactionDetail
-// MARK: - Manual Withdrawal (from ExchangeList)
+// MARK: - Manual Withdrawal (from Banking / ExchangeList)
// receive coins from bank ==> shows IBAN + Purpose/Subject for manual wire
transfer
public let VIEW_WITHDRAWAL = VIEW_TRANSACTIONLIST + 10 // 30
WithdrawAmount
public let VIEW_WITHDRAW_TOS = VIEW_WITHDRAWAL + 1 // 31
WithdrawTOSView
public let VIEW_WITHDRAW_ACCEPT = VIEW_WITHDRAW_TOS + 1 // 32
-// MARK: Manual Deposit (from ExchangeList)
+// MARK: Manual Deposit (from Banking / ExchangeList)
// send coins back to bank account ==> orders exchange to make the wire
transfer
public let VIEW_DEPOSIT = VIEW_WITHDRAWAL + 10 // 40
Deposit Coins
//public let VIEW_DEPOSIT_TOS // - user
already accepted the ToS at withdrawal, invoice or receive
@@ -79,7 +80,8 @@ 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
+public let SHEET_PAY_TEMPLATE = SHEET_PAYMENT + 1 // 141 Pay
Merchant Template
+public let SHEET_PAY_ACCEPT = SHEET_PAY_TEMPLATE + 1 // 142 Pay
Accept
// MARK: P2P Pay Invoice
// p2p pull debit - openURL (Link or scan QR)
@@ -92,11 +94,9 @@ public let SHEET_RCV_P2P = SHEET_PAY_P2P + 10
// 160 Recei
public let SHEET_RCV_P2P_TOS = SHEET_RCV_P2P + 1 // 161
Receive P2P TOSView
public let SHEET_RCV_P2P_ACCEPT = SHEET_RCV_P2P_TOS + 1 // 162
Receive P2P AcceptView
-// MARK: Reward - Receive Coins (from merchant)
+// MARK: Refund - Get Coins back from merchant
// openURL (Link, NFC or scan QR) ==> receive coins from merchant
-public let SHEET_RCV_REWARD = SHEET_RCV_P2P + 10 // 170
Receive Reward
-
-public let SHEET_REFUND = SHEET_RCV_REWARD + 10 // 180
Receive Refunds
+public let SHEET_REFUND = SHEET_RCV_P2P + 10 // 170
Receive Refunds
extension UIDevice {
var hasNotch: Bool {
diff --git a/TalerWallet1/Controllers/PublicConstants.swift
b/TalerWallet1/Controllers/PublicConstants.swift
index 248ce6c..f5baa82 100644
--- a/TalerWallet1/Controllers/PublicConstants.swift
+++ b/TalerWallet1/Controllers/PublicConstants.swift
@@ -4,6 +4,8 @@
*/
import Foundation
+public let MAXRECENT = 4
+public let ICONLEADING = CGFloat(-8)
public let HSPACING = CGFloat(10) // space between items in
HStack
public let LAUNCHDURATION: Double = 1.60
@@ -14,8 +16,8 @@ public let SEVENDAYS: UInt = 7 // 3..9
public let THIRTYDAYS: UInt = 30 // 10..30
public let EMPTYSTRING = "" // avoid automatic
translation of empty "" textLiterals in Text()
-public let CONFIRM_BANK = "circle.fill" // badge in PendingRow,
TransactionRow and TransactionDetail
-public let NEEDS_KYC = "star.fill" // badge in PendingRow,
TransactionRow and TransactionDetail
+public let CONFIRM_BANK = "circle.fill" // badge in PendingRow,
TransactionRow and TransactionSummary
+public let NEEDS_KYC = "star.fill" // badge in PendingRow,
TransactionRow and TransactionSummary
public let PENDING_INCOMING = "plus.diamond"
public let PENDING_OUTGOING = "minus.diamond"
public let DONE_INCOMING = "plus.circle.fill"
diff --git a/TalerWallet1/Helper/CurrencySpecification.swift
b/TalerWallet1/Helper/CurrencySpecification.swift
index 5422183..2f0319b 100644
--- a/TalerWallet1/Helper/CurrencySpecification.swift
+++ b/TalerWallet1/Helper/CurrencySpecification.swift
@@ -78,6 +78,18 @@ public struct CurrencyInfo {
return CurrencyInfo(scope: scope, specs: specs, formatter: formatter)
}
+ public static func euro() -> CurrencyInfo {
+ let currency = "Euro"
+ let scope = ScopeInfo(type: .global, currency: currency)
+ let specs = CurrencySpecification(name: currency,
+ fractionalInputDigits: 2,
+ fractionalNormalDigits: 2,
+ fractionalTrailingZeroDigits: 2,
+ altUnitNames: [0 : "€"])
+ let formatter = CurrencyFormatter.formatter(scope: scope, specs: specs)
+ return CurrencyInfo(scope: scope, specs: specs, formatter: formatter)
+ }
+
/// returns all characters left from the decimalSeparator
func integerPartStr(_ integerStr: String, decimalSeparator: String) ->
String {
if let integerIndex = integerStr.endIndex(of: decimalSeparator) {
diff --git a/TalerWallet1/Model/Model+Exchange.swift
b/TalerWallet1/Model/Model+Exchange.swift
index 5b362f0..6de9b6a 100644
--- a/TalerWallet1/Model/Model+Exchange.swift
+++ b/TalerWallet1/Model/Model+Exchange.swift
@@ -29,6 +29,15 @@ enum ExchangeUpdateStatus: String, Codable {
// MARK: -
/// The result from wallet-core's ListExchanges
struct Exchange: Codable, Hashable, Identifiable {
+ static func < (lhs: Exchange, rhs: Exchange) -> Bool {
+ if let leftScope = lhs.scopeInfo {
+ if let rightScope = rhs.scopeInfo {
+ return leftScope < rightScope
+ }
+ return true // scopeInfo comes first
+ }
+ return false
+ }
static func == (lhs: Exchange, rhs: Exchange) -> Bool {
return lhs.exchangeBaseUrl == rhs.exchangeBaseUrl
&& lhs.tosStatus == rhs.tosStatus
diff --git a/TalerWallet1/Model/Model+Transactions.swift
b/TalerWallet1/Model/Model+Transactions.swift
index d6226cc..3b91b7a 100644
--- a/TalerWallet1/Model/Model+Transactions.swift
+++ b/TalerWallet1/Model/Model+Transactions.swift
@@ -26,12 +26,14 @@ extension WalletModel {
fileprivate struct GetTransactions: WalletBackendFormattedRequest {
func operation() -> String { "getTransactions" }
// func operation() -> String { "testingGetSampleTransactions" }
- func args() -> Args { Args(currency: currency, search: search, sort: sort)
}
+ func args() -> Args { Args(scopeInfo: scopeInfo, currency: currency,
search: search, sort: sort) }
+ var scopeInfo: ScopeInfo?
var currency: String?
var search: String?
var sort: String?
struct Args: Encodable {
+ var scopeInfo: ScopeInfo?
var currency: String?
var search: String?
var sort: String?
@@ -99,10 +101,10 @@ struct ResumeTransaction: WalletBackendFormattedRequest {
// MARK: -
extension WalletModel {
/// ask wallet-core for its list of transactions filtered by searchString
- func transactionsT(_ stack: CallStack, currency: String? = nil,
searchString: String? = nil, sort: String = "descending")
+ func transactionsT(_ stack: CallStack, scopeInfo: ScopeInfo, searchString:
String? = nil, sort: String = "descending")
async -> [Transaction] { // might
be called from a background thread itself
do {
- let request = GetTransactions(currency: currency, search:
searchString, sort: sort)
+ let request = GetTransactions(scopeInfo: scopeInfo, currency:
scopeInfo.currency, search: searchString, sort: sort)
let response = try await sendRequest(request, ASYNCDELAY)
return response.transactions
} catch {
@@ -110,9 +112,9 @@ extension WalletModel {
}
}
/// fetch transactions from Wallet-Core. No networking involved
- @MainActor func transactionsMA(_ stack: CallStack, currency: String? =
nil, searchString: String? = nil, sort: String = "descending")
+ @MainActor func transactionsMA(_ stack: CallStack, scopeInfo: ScopeInfo,
searchString: String? = nil, sort: String = "descending")
async -> [Transaction] { // M for MainActor
- return await transactionsT(stack.push(), currency: currency,
searchString: searchString, sort: sort)
+ return await transactionsT(stack.push(), scopeInfo: scopeInfo,
searchString: searchString, sort: sort)
}
/// abort the specified transaction from Wallet-Core. No networking
involved
diff --git a/TalerWallet1/Model/Transaction.swift
b/TalerWallet1/Model/Transaction.swift
index 4fb492b..31bd873 100644
--- a/TalerWallet1/Model/Transaction.swift
+++ b/TalerWallet1/Model/Transaction.swift
@@ -152,13 +152,13 @@ enum TxAction: String, Codable {
var localizedActionTitle: String {
return switch self {
- case .delete: String(localized: "TxAction.Delete", defaultValue:
"Delete from list", comment: "TxAction button")
+ case .delete: String(localized: "TxAction.Delete", defaultValue:
"Delete from history", comment: "TxAction button")
case .suspend: String("Suspend")
case .resume: String("Resume")
case .abort: String(localized: "TxAction.Abort", defaultValue:
"Abort", comment: "TxAction button")
// case .revive: String(localized: "TxAction.Revive",
defaultValue: "Revive", comment: "TxAction button")
case .fail: String(localized: "TxAction.Fail", defaultValue:
"Fail", comment: "TxAction button")
- case .retry: String(localized: "TxAction.Retry", defaultValue:
"Retry", comment: "TxAction button")
+ case .retry: String(localized: "TxAction.Retry", defaultValue:
"Retry now", comment: "TxAction button")
}
}
var localizedActionImage: String? {
@@ -197,7 +197,6 @@ enum TransactionType: String, Codable {
case payment
case refund
case refresh
- 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
@@ -209,7 +208,6 @@ enum TransactionType: String, Codable {
var isPayment : Bool { self == .payment }
var isRefund : Bool { self == .refund }
var isRefresh : Bool { self == .refresh }
- var isReward : Bool { self == .reward }
var isSendCoins : Bool { self == .peerPushDebit }
var isRcvCoins : Bool { self == .scanPushCredit }
var isSendInvoice: Bool { self == .peerPullCredit }
@@ -217,7 +215,7 @@ enum TransactionType: String, Codable {
var isP2pOutgoing: Bool { isSendCoins || isPayInvoice}
var isP2pIncoming: Bool { isSendInvoice || isRcvCoins}
- var isIncoming : Bool { isP2pIncoming || isWithdrawal || isRefund ||
isReward }
+ var isIncoming : Bool { isP2pIncoming || isWithdrawal || isRefund }
}
struct TransactionCommon: Decodable, Sendable {
@@ -243,8 +241,6 @@ struct TransactionCommon: Decodable, Sendable {
comment: "TransactionType")
case .refresh: return String(localized: "Refresh",
comment: "TransactionType")
- case .reward: return String(localized: "Reward",
- comment: "TransactionType")
case .peerPushDebit: return String(localized: "Send Money",
comment: "TransactionType,
send coins to another wallet")
case .scanPushCredit: return String(localized: "Receive Money",
@@ -255,6 +251,19 @@ struct TransactionCommon: Decodable, Sendable {
comment: "TransactionType,
scan invoice to pay to another wallet")
}
}
+ func localizedTypePast(_ type: TransactionType) -> String {
+ switch type {
+ case .peerPushDebit: return String(localized: "Sent Money",
+ comment: "TransactionType,
sent coins to another wallet")
+ case .scanPushCredit: return String(localized: "Received Money",
+ comment: "TransactionType,
received coins sent from another wallet")
+ case .peerPullCredit: return String(localized: "Requested Money",
// Invoice?
+ comment: "TransactionType,
sent invoice to another wallet")
+ case .scanPullDebit: return String(localized: "Paid Request",
// Pay Invoice is the same as Payment
+ comment: "TransactionType,
paid invoice from another wallet")
+ default: return localizedType(type)
+ }
+ }
func fee() -> Amount {
do {
@@ -269,7 +278,6 @@ struct TransactionCommon: Decodable, Sendable {
func incoming() -> Bool {
return type == .withdrawal
|| type == .refund
- || type == .reward
|| type == .peerPullCredit
|| type == .scanPushCredit
}
@@ -305,6 +313,27 @@ struct WithdrawalTransaction : Sendable{
var details: WithdrawalTransactionDetails
}
+struct TrackingState : Decodable {
+ var wireTransferId: String
+ var timestampExecuted: Timestamp
+ var amountRaw: Amount
+ var wireFee: Amount
+}
+
+struct DepositTransactionDetails: Decodable {
+ var depositGroupId: String
+ var targetPaytoUri: String
+ var wireTransferProgress: Int
+ var wireTransferDeadline: Timestamp
+ var deposited: Bool
+ var trackingState: [TrackingState]?
+}
+
+struct DepositTransaction : Sendable {
+ var common: TransactionCommon
+ var details: DepositTransactionDetails
+}
+
struct RefundInfo: Decodable {
var amountEffective: Amount
var amountRaw: Amount
@@ -341,16 +370,6 @@ struct RefundTransaction : Sendable{
var details: RefundTransactionDetails
}
-struct RewardTransactionDetails: Decodable {
- /// The exchange that the reward will be withdrawn from
- var exchangeBaseUrl: String
-}
-
-struct RewardTransaction : Sendable{
- var common: TransactionCommon
- var details: RewardTransactionDetails
-}
-
enum RefreshReason: String, Decodable {
case manual
case payMerchant = "pay-merchant"
@@ -408,9 +427,9 @@ struct DummyTransaction : Sendable{
enum Transaction: Decodable, Hashable, Identifiable, Sendable {
case dummy (DummyTransaction)
case withdrawal (WithdrawalTransaction)
+ case deposit (DepositTransaction)
case payment (PaymentTransaction)
case refund (RefundTransaction)
- case reward (RewardTransaction)
case refresh (RefreshTransaction)
case peer2peer (P2PTransaction)
@@ -421,15 +440,15 @@ enum Transaction: Decodable, Hashable, Identifiable,
Sendable {
case .withdrawal:
let details = try WithdrawalTransactionDetails.init(from:
decoder)
self = .withdrawal(WithdrawalTransaction(common: common,
details: details))
+ case .deposit:
+ let details = try DepositTransactionDetails.init(from:
decoder)
+ self = .deposit(DepositTransaction(common: common,
details: details))
case .payment:
let details = try PaymentTransactionDetails.init(from:
decoder)
self = .payment(PaymentTransaction(common: common,
details: details))
case .refund:
let details = try RefundTransactionDetails.init(from:
decoder)
self = .refund(RefundTransaction(common: common, details:
details))
- case .reward:
- let details = try RewardTransactionDetails.init(from:
decoder)
- self = .reward(RewardTransaction(common: common, details:
details))
case .refresh:
let details = try RefreshTransactionDetails.init(from:
decoder)
self = .refresh(RefreshTransaction(common: common,
details: details))
@@ -469,6 +488,9 @@ enum Transaction: Decodable, Hashable, Identifiable,
Sendable {
var localizedType: String {
common.localizedType(common.type)
}
+ var localizedTypePast: String {
+ common.localizedTypePast(common.type)
+ }
static func == (lhs: Transaction, rhs: Transaction) -> Bool {
return lhs.id == rhs.id
@@ -484,7 +506,6 @@ enum Transaction: Decodable, Hashable, Identifiable,
Sendable {
var isPayment : Bool { common.type == .payment }
var isRefund : Bool { common.type == .refund }
var isRefresh : Bool { common.type == .refresh }
- var isReward : Bool { common.type == .reward }
var isSendCoins : Bool { common.type == .peerPushDebit }
var isRcvCoins : Bool { common.type == .scanPushCredit }
var isSendInvoice: Bool { common.type == .peerPullCredit }
@@ -528,9 +549,9 @@ enum Transaction: Decodable, Hashable, Identifiable,
Sendable {
return switch self {
case .dummy(let dummyTransaction):
dummyTransaction.common
case .withdrawal(let withdrawalTransaction):
withdrawalTransaction.common
+ case .deposit(let depositTransaction):
depositTransaction.common
case .payment(let paymentTransaction):
paymentTransaction.common
case .refund(let refundTransaction):
refundTransaction.common
- case .reward(let rewardTransaction):
rewardTransaction.common
case .refresh(let refreshTransaction):
refreshTransaction.common
case .peer2peer(let p2pTransaction): p2pTransaction.common
}
@@ -543,14 +564,14 @@ enum Transaction: Decodable, Hashable, Identifiable,
Sendable {
break
case .withdrawal(let withdrawalTransaction):
result[EXCHANGEBASEURL] =
withdrawalTransaction.details.exchangeBaseUrl
+ case .deposit(let depositTransaction):
+ result[EXCHANGEBASEURL] =
depositTransaction.details.depositGroupId
case .payment(let paymentTransaction):
result["summary"] = paymentTransaction.details.info.summary
case .refund(let refundTransaction):
if let info = refundTransaction.details.info {
result["summary"] = info.summary
}
- case .reward(let rewardTransaction):
- result[EXCHANGEBASEURL] =
rewardTransaction.details.exchangeBaseUrl
case .refresh(let refreshTransaction):
result["reason"] =
refreshTransaction.details.refreshReason.rawValue
case .peer2peer(let p2pTransaction):
diff --git a/TalerWallet1/Model/WalletModel.swift
b/TalerWallet1/Model/WalletModel.swift
index b309c38..86cf4e6 100644
--- a/TalerWallet1/Model/WalletModel.swift
+++ b/TalerWallet1/Model/WalletModel.swift
@@ -79,6 +79,8 @@ fileprivate struct GetTransactionById:
WalletBackendFormattedRequest {
// MARK: -
/// The info returned from Wallet-core init
struct VersionInfo: Decodable {
+ var implementationSemver: String?
+ var implementationGitHash: String?
var version: String
var exchange: String
var merchant: String
@@ -89,21 +91,31 @@ struct VersionInfo: Decodable {
fileprivate struct InitRequest: WalletBackendFormattedRequest {
func operation() -> String { "init" }
func args() -> Args {
+ let testing = Testing(devModeActive: false) // true, false
+ let config = Config(testing: testing)
return Args(persistentStoragePath: persistentStoragePath,
// cryptoWorkerType: "sync",
- logLevel: "info", // trace, info, warn,
error, none
+ logLevel: "info", // trace, info, warn,
error, none
+ config: config,
useNativeLogging: true)
}
+ var persistentStoragePath: String
+
+ struct Testing: Encodable {
+ var devModeActive: Bool
+ // more to come...
+ }
+ struct Config: Encodable {
+ var testing: Testing
+ }
struct Args: Encodable {
var persistentStoragePath: String
// var cryptoWorkerType: String
var logLevel: String
+ var config: Config
var useNativeLogging: Bool
}
-
- var persistentStoragePath: String
-
struct Response: Decodable {
var versionInfo: VersionInfo
}
@@ -156,7 +168,7 @@ extension WalletModel {
}
}
// MARK: -
-/// A request to initialize Wallet-core
+/// A request to reset Wallet-core to a virgin DB. WILL DESTROY ALL COINS
fileprivate struct ResetRequest: WalletBackendFormattedRequest {
func operation() -> String { "clearDb" }
func args() -> Args { Args() }
@@ -174,3 +186,24 @@ extension WalletModel {
}
}
// MARK: -
+
+fileprivate struct DevExperimentRequest: WalletBackendFormattedRequest {
+ func operation() -> String { "applyDevExperiment" }
+ func args() -> Args { Args(devExperimentUri: talerUri) }
+
+ var talerUri: String
+
+ struct Args: Encodable {
+ var devExperimentUri: String
+ }
+ struct Response: Decodable {}
+}
+
+extension WalletModel {
+ /// tell wallet-core to mock new transactions
+ func devExperimentT(talerUri: String) async throws {
+ // T for any Thread
+ let request = DevExperimentRequest(talerUri: talerUri)
+ _ = try await sendRequest(request, 0)
+ }
+}
diff --git a/TalerWallet1/Views/Balances/BalanceRowView.swift
b/TalerWallet1/Views/Balances/BalanceRowView.swift
index 130c379..a96f07c 100644
--- a/TalerWallet1/Views/Balances/BalanceRowView.swift
+++ b/TalerWallet1/Views/Balances/BalanceRowView.swift
@@ -12,7 +12,7 @@ struct BalanceCell: View {
let balanceDest: LazyView<TransactionsListView>?
@Environment(\.colorSchemeContrast) private var colorSchemeContrast
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
/// Renders the Balance button. "Balance" leading, amountStr trailing. If
it doesn't fit in one row then
/// amount (trailing) goes underneath "Balance" (leading).
@@ -24,7 +24,7 @@ struct BalanceCell: View {
amountV
}
let balanceCell = Group {
- if iconOnly {
+ if minimalistic {
hLayout
} else {
let balanceText = Text("Balance:", comment: "Main view")
@@ -69,7 +69,7 @@ struct BalanceRowView: View {
@Environment(\.sizeCategory) var sizeCategory
@EnvironmentObject private var controller: Controller
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
let sendTitle0 = String(localized: "SendButton_Short", defaultValue:
"Send",
@@ -89,8 +89,8 @@ struct BalanceRowView: View {
balanceDest: balanceDest)
// .border(.red)
- let sendTitle = iconOnly ? sendTitle0 : sendTitle1
- let requTitle = iconOnly ? requestTitle0 : requestTitle1
+ let sendTitle = minimalistic ? sendTitle0 : sendTitle1
+ let requTitle = minimalistic ? requestTitle0 : requestTitle1
let twoRowButtons = TwoRowButtons(sendTitle: sendTitle,
recvTitle: requTitle,
fitsSideBySide: false,
diff --git a/TalerWallet1/Views/Balances/BalancesListView.swift
b/TalerWallet1/Views/Balances/BalancesListView.swift
index 43cceb9..f12483d 100644
--- a/TalerWallet1/Views/Balances/BalancesListView.swift
+++ b/TalerWallet1/Views/Balances/BalancesListView.swift
@@ -95,6 +95,7 @@ struct BalancesListView: View {
#endif
Content(symLog: symLog, stack: stack.push(), balances: $balances,
amountToTransfer: $amountToTransfer, summary: $summary,
+ shouldReloadBalances: $shouldReloadBalances,
reloadBalances: reloadBalances)
.navigationTitle(navTitle)
.navigationBarItems(trailing: QRButton(action:
checkCameraAvailable))
@@ -124,6 +125,7 @@ extension BalancesListView {
@Binding var balances: [Balance]
@Binding var amountToTransfer: Amount
@Binding var summary: String
+ @Binding var shouldReloadBalances: Int
var reloadBalances: (_ stack: CallStack, _ invalidateCache: Bool)
async -> Int
var body: some View {
@@ -141,7 +143,8 @@ extension BalancesListView {
balance: balance,
// this is the currency to be used
sectionCount: count,
amountToTransfer: $amountToTransfer,
// does still have the wrong currency
- summary: $summary)
+ summary: $summary,
+ shouldReloadBalances: $shouldReloadBalances)
}
.onAppear() {
DebugViewC.shared.setViewID(VIEW_BALANCES, stack:
stack.push("onAppear"))
diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift
b/TalerWallet1/Views/Balances/BalancesSectionView.swift
index 0667225..908f56d 100644
--- a/TalerWallet1/Views/Balances/BalancesSectionView.swift
+++ b/TalerWallet1/Views/Balances/BalancesSectionView.swift
@@ -21,10 +21,11 @@ struct BalancesSectionView {
let sectionCount: Int
@Binding var amountToTransfer: Amount // does still have the
wrong currency
@Binding var summary: String
+ @Binding var shouldReloadBalances: Int
@EnvironmentObject private var model: WalletModel
@EnvironmentObject private var controller: Controller
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var showSpendingHint = true
@State private var isShowingDetailView = false
@@ -40,14 +41,12 @@ struct BalancesSectionView {
@State private var shownSectionID = UUID() // guaranteed to be different
the first time
func reloadCompleted(_ stack: CallStack) async -> () {
- let currency = balance.scopeInfo.currency
- transactions = await model.transactionsT(stack.push(), currency:
currency)
+ transactions = await model.transactionsT(stack.push(), scopeInfo:
balance.scopeInfo)
completedTransactions = WalletModel.completedTransactions(transactions)
}
func reloadPending(_ stack: CallStack) async -> () {
- let currency = balance.scopeInfo.currency
- transactions = await model.transactionsT(stack.push(), currency:
currency)
+ transactions = await model.transactionsT(stack.push(), scopeInfo:
balance.scopeInfo)
pendingTransactions = WalletModel.pendingTransactions(transactions)
}
}
@@ -58,14 +57,15 @@ extension BalancesSectionView: View {
let _ = Self._printChanges()
let _ = symLog.vlog() // just to get the # to compare it with
.onAppear & onDisappear
#endif
- let currency = balance.scopeInfo.currency
- let currencyInfo = controller.info(for: currency,
controller.currencyTicker)
+ let scopeInfo = balance.scopeInfo
+ let currency = scopeInfo.currency
+ let currencyInfo = controller.info(for: currency)
Section {
let showSpendingButton = "KUDOS" == currency &&
!balance.available.isZero
if showSpendingButton {
- if !iconOnly && showSpendingHint {
- Text("You can spend these KUDOS in the Demo Shop, or send
them to another wallet.")
+ if !minimalistic && showSpendingHint {
+ Text("You can spend these \(currencyInfo?.scope.currency
?? currency) in the Demo shop, or send them to another wallet.")
.accessibilityFont(.body)
.multilineTextAlignment(.leading)
.listRowSeparator(.hidden)
@@ -96,14 +96,18 @@ extension BalancesSectionView: View {
pendingTransactions: $pendingTransactions,
reloadPending: reloadPending,
reloadOneAction: reloadOneAction)
+ .padding(.leading, ICONLEADING)
}
} header: {
- BarGraphHeader(stack: stack.push(), currency: currency)
+ BarGraphHeader(stack: stack.push(), scopeInfo: scopeInfo,
+ currencyName: currencyInfo?.scope.currency ?? currency,
+ shouldReloadBalances: $shouldReloadBalances)
}.id(sectionID)
- .task {
+ .task(id: shouldReloadBalances + 1_000_000) {
// if shownSectionID != sectionID {
symLog.log(".task for BalancesSectionView - reload
Transactions")
- let response = await model.transactionsT(stack.push(".task -
reload Transactions"), currency: currency)
+ // TODO: only load the MAXRECENT most recent transactions
+ let response = await model.transactionsT(stack.push(".task -
reload Transactions"), scopeInfo: scopeInfo)
transactions = response
pendingTransactions = WalletModel.pendingTransactions(response)
completedTransactions =
WalletModel.completedTransactions(response)
@@ -113,19 +117,22 @@ extension BalancesSectionView: View {
// }
}
let transactionCount = completedTransactions.count
- /// if there is only one currency, then show recent transactions
+ /// if there is only one currency, then show MAXRECENT recent
transactions
if sectionCount == 1 && transactionCount > 0 {
Section {
- let slice = completedTransactions.prefix(3) // already
sorted
+ let slice = completedTransactions.prefix(MAXRECENT) //
already sorted
let threeTransactions = Array(slice)
TransactionsArraySliceV(symLog: symLog,
stack: stack.push(),
- currency: currency,
+ scopeInfo: scopeInfo,
transactions: threeTransactions,
reloadOneAction: reloadOneAction)
+ .padding(.leading, ICONLEADING)
} header: {
- if !iconOnly {
- Text("Recent transactions")
+ if !minimalistic {
+ let count = transactionCount > MAXRECENT ? MAXRECENT :
transactionCount
+ Text(count > 1 ? "Recent \(count) transactions"
+ : "Recent transaction")
.accessibilityFont(.callout)
// .foregroundColor(colorSchemeContrast == .increased ?
.primary : .secondary)
}
@@ -133,7 +140,7 @@ extension BalancesSectionView: View {
} // recent transactions
} // body
} // BalancesSectionView
-
+// MARK: -
fileprivate struct BalancesPendingRowView: View {
let symLog: SymLogV?
let stack: CallStack
@@ -155,7 +162,7 @@ fileprivate struct BalancesPendingRowView: View {
LazyView {
TransactionsListView(stack: stack.push(),
navTitle: String(localized: "Pending",
comment: "ViewTitle of TransactionList"),
- currency: balance.scopeInfo.currency,
+ scopeInfo: balance.scopeInfo,
transactions: pendingTransactions,
showUpDown: false,
reloadAllAction: reloadPending,
@@ -222,7 +229,7 @@ fileprivate struct BalancesNavigationLinksView: View {
}
var body: some View {
- let currency = balance.scopeInfo.currency
+ let scopeInfo = balance.scopeInfo
HStack(spacing: 0) {
NavigationLink(destination: LazyView {
SendAmount(stack: stack.push(),
@@ -242,7 +249,7 @@ fileprivate struct BalancesNavigationLinksView: View {
let balanceDest = LazyView {
TransactionsListView(stack: stack.push(),
navTitle: String(localized: "Transactions",
comment: "ViewTitle of TransactionList"),
- currency: currency,
+ scopeInfo: scopeInfo,
transactions: completedTransactions,
showUpDown: true,
reloadAllAction: reloadAllAction,
diff --git a/TalerWallet1/Views/Balances/PendingRowView.swift
b/TalerWallet1/Views/Balances/PendingRowView.swift
index 65bf5d6..7be6011 100644
--- a/TalerWallet1/Views/Balances/PendingRowView.swift
+++ b/TalerWallet1/Views/Balances/PendingRowView.swift
@@ -13,7 +13,7 @@ struct PendingRowView: View {
let needsKYC: Bool
// @Environment(\.sizeCategory) var sizeCategory
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
let inTitle0 = String(localized: "TitleIncoming_Short", defaultValue:
"Incoming",
comment: "Abbreviation of `Pending incoming´ in
Balances")
@@ -29,8 +29,8 @@ struct PendingRowView: View {
let pendingColor = WalletColors().pendingColor(incoming)
let iconBadge = IconBadge(foreColor: pendingColor, done: false,
incoming: incoming,
shouldConfirm: shouldConfirm, needsKYC:
needsKYC)
- let inTitle = iconOnly ? inTitle0 : inTitle1
- let outTitle = iconOnly ? outTitle0 : outTitle1
+ let inTitle = minimalistic ? inTitle0 : inTitle1
+ let outTitle = minimalistic ? outTitle0 : outTitle1
let pendingTitle = incoming ? inTitle : outTitle
let amountText = AmountV(amount)
diff --git a/TalerWallet1/Views/Banking/ExchangeListView.swift
b/TalerWallet1/Views/Banking/ExchangeListView.swift
index 718291f..243f1fc 100644
--- a/TalerWallet1/Views/Banking/ExchangeListView.swift
+++ b/TalerWallet1/Views/Banking/ExchangeListView.swift
@@ -31,25 +31,25 @@ struct ExchangeListView: View {
}
var body: some View {
- let accessibilityLabelStr = String(localized: "Add Exchange", comment:
"accessibilityLabel for the + button")
+ let accessibilityLabelStr = String(localized: "Add Payment Service",
comment: "accessibilityLabel for the + button")
let plusButton = PlusButton(accessibilityLabelStr:
accessibilityLabelStr) {
showAlert = true
}
- let addTitleStr = String(localized: "Add Exchange", comment: "title of
the addExchange alert")
+ let addTitleStr = String(localized: "Add Payment Service", comment:
"title of the addExchange alert")
let addButtonStr = String(localized: "Add", comment: "button in the
addExchange alert")
if #available(iOS 16.0, *) {
ExchangeListCommonV(symLog: symLog, stack: stack.push(), balances:
$balances)
.navigationTitle(navTitle)
.navigationBarItems(trailing: plusButton)
.alert(addTitleStr, isPresented: $showAlert) {
- TextField("Exchange address", text: $newExchange)
+ TextField("Address of Payment Service", text: $newExchange)
// .textFieldStyle(.roundedBorder) Yikes: when adding
style the alert will stop showing the textfield! Don't do this.
Button(addButtonStr) {
addExchange(newExchange)
}
Button("Cancel", role: .cancel) { }
} message: {
- Text("Please enter the exchange URL")
+ Text("Please enter the URL")
}
} else { // iOS 15 cannot have a textfield in an alert, so we must
ExchangeListCommonV(symLog: symLog, stack: stack.push(), balances:
$balances)
@@ -64,13 +64,14 @@ struct ExchangeListView: View {
}
}
}
-
-struct ExchangeListCommonV: View {
+// MARK: -
+struct ExchangeListCommonV {
let symLog: SymLogV?
let stack: CallStack
@Binding var balances: [Balance]
@EnvironmentObject private var model: WalletModel
+ @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
@State private var exchanges: [Exchange] = []
@@ -81,82 +82,45 @@ struct ExchangeListCommonV: View {
exchanges = await model.listExchangesM()
}
+}
+// MARK: -
+extension ExchangeListCommonV: View {
var body: some View {
#if PRINT_CHANGES
let _ = Self._printChanges()
let _ = symLog?.vlog() // just to get the # to compare it with
.onAppear & onDisappear
#endif
- //Text("Exchanges...")
- Content(symLog: symLog,
- stack: stack.push(),
- balances: $balances,
- exchanges: $exchanges,
- amountToTransfer: $amountToTransfer,
- reloadExchanges: reloadExchanges)
+ let sortedExchanges = exchanges.sorted { $0 < $1 }
+ // TODO: Balances for amountAvailable for Deposit
+ Group {
+ List(sortedExchanges, id: \.self) { exchange in
+ ExchangeSectionView(stack: stack.push(),
+ exchange: exchange,
+ amountToTransfer: $amountToTransfer) //
does still have the wrong currency
+ }
+ .refreshable {
+ symLog?.log("refreshing")
+ await reloadExchanges()
+ }
+ .listStyle(myListStyle.style).anyView
+ }
+ .onAppear() {
+ DebugViewC.shared.setViewID(VIEW_EXCHANGES, stack: stack.push())
+ }
.overlay {
if exchanges.isEmpty {
- Text("No Exchanges yet...")
+ Text("No Payment Services yet...")
.accessibilityFont(.body)
}
}
+ .onNotification(.ExchangeAdded) { notification in
+ // doesn't need to be received on main thread because we just
reload in the background anyway
+ symLog?.log(".onNotification(.ExchangeAdded) ==> reloading
exchanges")
+ Task { await reloadExchanges() } // runs on MainActor
+ }
.task {
symLog?.log(".task")
await reloadExchanges()
}
- }
-}
-// MARK: -
-extension ExchangeListCommonV {
- struct Content: View {
- let symLog: SymLogV?
- let stack: CallStack
- @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
- @Binding var balances: [Balance]
- @Binding var exchanges: [Exchange]
- @Binding var amountToTransfer: Amount // does still have the
wrong currency
- var reloadExchanges: () async -> Void
-
- func currenciesDict(_ exchanges: [Exchange]) -> [String : [Exchange]] {
- var currencies: [String : [Exchange]] = [:]
-
- for exchange in exchanges {
- let currency = exchange.scopeInfo?.currency
- ?? exchange.currency ?? "Unknown"
- if currencies[currency] != nil {
- currencies[currency]!.append(exchange)
- } else {
- currencies[currency] = [exchange]
- }
- }
- return currencies
- }
-
-// @State private var exchangeAmount: ExchangeAmount? = nil
-
- var body: some View {
- let dict = currenciesDict(exchanges)
- // TODO: Balances for amountAvailable for Deposit
- let sortedDict = dict.sorted{ $0.key < $1.key}
- Group { // necessary for .backslide transition (bug in SwiftUI)
- List(sortedDict, id: \.key) { key, value in
- ExchangeSectionView(stack: stack.push(),
- currency: key, exchanges: value,
- amountToTransfer: $amountToTransfer)
// does still have the wrong currency
- }
- .refreshable {
- symLog?.log("refreshing")
- await reloadExchanges()
- }
- .listStyle(myListStyle.style).anyView
- }
- .onAppear() {
- DebugViewC.shared.setViewID(VIEW_EXCHANGES, stack:
stack.push())
- }
- .onNotification(.ExchangeAdded) { notification in
- // doesn't need to be received on main thread because we just
reload in the background anyway
- symLog?.log(".onNotification(.ExchangeAdded) ==> reloading
exchanges")
- Task { await reloadExchanges() } // runs on MainActor
- }
- } // body
- }
+ } // body
}
diff --git a/TalerWallet1/Views/Banking/ExchangeRowView.swift
b/TalerWallet1/Views/Banking/ExchangeRowView.swift
index a16e6ad..ce09e40 100644
--- a/TalerWallet1/Views/Banking/ExchangeRowView.swift
+++ b/TalerWallet1/Views/Banking/ExchangeRowView.swift
@@ -16,7 +16,7 @@ struct ExchangeRowView: View {
@Environment(\.sizeCategory) var sizeCategory
@EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var buttonSelected: Int? = nil
func selectAndUpdate(_ button: Int) {
@@ -65,8 +65,8 @@ struct ExchangeRowView: View {
viewID: VIEW_WITHDRAW_TOS,
acceptAction: nil) // pop back to here
}
- let twoRowButtons = TwoRowButtons(sendTitle: iconOnly ? depositTitle0
: depositTitle1,
- recvTitle: iconOnly ? withdrawTitle0
: withdrawTitle1,
+ let twoRowButtons = TwoRowButtons(sendTitle: minimalistic ?
depositTitle0 : depositTitle1,
+ recvTitle: minimalistic ?
withdrawTitle0 : withdrawTitle1,
fitsSideBySide: false,
lineLimit: 5,
sendDisabled: true, //
TODO: availableAmount.isZero
@@ -77,7 +77,7 @@ struct ExchangeRowView: View {
VStack(alignment: .leading) {
Text(baseURL.trimURL())
.accessibilityFont(.headline)
- if !iconOnly {
+ if !minimalistic {
Text("Terms of Service") // VIEW_WITHDRAW_TOS
.accessibilityFont(.body)
}
diff --git a/TalerWallet1/Views/Banking/ExchangeSectionView.swift
b/TalerWallet1/Views/Banking/ExchangeSectionView.swift
index 09bfa7e..158e4c7 100644
--- a/TalerWallet1/Views/Banking/ExchangeSectionView.swift
+++ b/TalerWallet1/Views/Banking/ExchangeSectionView.swift
@@ -10,29 +10,35 @@ import taler_swift
/// [Deposit Coins] [Withdraw Coins]
struct ExchangeSectionView: View {
let stack: CallStack
- let currency: String // this is the currency to be
used
- let exchanges: [Exchange]
+ let exchange: Exchange
+// let exchanges: [Exchange]
@Binding var amountToTransfer: Amount // does still have the wrong
currency
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @EnvironmentObject private var controller: Controller
+ @AppStorage("minimalistic") var minimalistic: Bool = false
+ @State private var shouldReloadBalances: Int = 0
var body: some View {
#if PRINT_CHANGES
let _ = Self._printChanges()
// let _ = symLog.vlog() // just to get the # to compare it with
.onAppear & onDisappear
#endif
+ let scopeInfo = exchange.scopeInfo
+ let currency = scopeInfo?.currency ?? exchange.currency ?? "unknown"
+ let currencyInfo = controller.info(for: currency)
+ let currencyName = currencyInfo?.scope.currency ?? currency
Section {
- ForEach(exchanges) { exchange in
+// ForEach(exchanges) { exchange in
ExchangeRowView(stack: stack.push(),
exchange: exchange,
- currency: currency, // TODO:
(balance.available) amount.isZero to disable Deposit-button
+ currency: currencyName, // TODO:
(balance.available) amount.isZero to disable Deposit-button
amountToTransfer: $amountToTransfer) // does still have
the wrong currency
.listRowSeparator(.hidden)
- }
+// }
if "KUDOS" == currency {
let bankingHint = String(localized: "Since the demo bank
supports the Taler integration, you can start a withdrawal directly on the")
let linkTitle = String(localized: "LinkTitle_DEMOBANK",
defaultValue: "Demo Bank Website")
VStack {
- if !iconOnly {
+ if !minimalistic {
Text(bankingHint)
}
Link(linkTitle, destination: URL(string: DEMOBANK)!)
@@ -43,7 +49,8 @@ struct ExchangeSectionView: View {
.padding(.top)
}
} header: {
- BarGraphHeader(stack: stack.push(), currency: currency)
+ BarGraphHeader(stack: stack.push(), scopeInfo: scopeInfo,
currencyName: currencyName,
+ shouldReloadBalances: $shouldReloadBalances)
}
}
}
@@ -70,9 +77,11 @@ fileprivate struct ExchangeRow_Container : View {
exchangeEntryStatus: .ephemeral,
exchangeUpdateStatus: .ready,
ageRestrictionOptions: [])
- ExchangeSectionView(stack: CallStack("Preview"), currency:
LONGCURRENCY,
- exchanges: [exchange1, exchange2],
- amountToTransfer: $amountToPreview)
+ ExchangeSectionView(stack: CallStack("Preview"),
+// scopeInfo: scopeInfo,
+ exchange: exchange1,
+// exchanges: [exchange1, exchange2],
+ amountToTransfer: $amountToPreview)
}
}
diff --git a/TalerWallet1/Views/Banking/ManualWithdraw.swift
b/TalerWallet1/Views/Banking/ManualWithdraw.swift
index f63751e..76386b2 100644
--- a/TalerWallet1/Views/Banking/ManualWithdraw.swift
+++ b/TalerWallet1/Views/Banking/ManualWithdraw.swift
@@ -16,7 +16,7 @@ struct ManualWithdraw: View {
@EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var withdrawalAmountDetails: WithdrawalAmountDetails? = nil
@State private var exchange: Exchange? = nil
@@ -56,8 +56,8 @@ struct ManualWithdraw: View {
if tosAccepted {
CurrencyInputView(amount: $amountToTransfer,
available: nil,
- title: iconOnly ? String(localized:
"Amount:")
- : String(localized:
"Amount to withdraw:"),
+ title: minimalistic ? String(localized:
"Amount:")
+ : String(localized:
"Amount to withdraw:"),
shortcutAction: nil)
.padding(.top)
QuiteSomeCoins(someCoins: someCoins,
@@ -79,9 +79,9 @@ struct ManualWithdraw: View {
p2p: false)
.padding(.top)
}
- } } // ScrollVStack
+ }.padding(.horizontal) } // ScrollVStack
.frame(maxWidth: .infinity, alignment: .leading)
- .padding(.horizontal)
+// .scrollBounceBehavior(.basedOnSize) needs iOS 16.4
.background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all))
.navigationTitle(navTitle)
.onAppear {
@@ -100,7 +100,7 @@ struct ManualWithdraw: View {
if let exc = await model.getExchangeByUrl(url:
exchangeBaseUrl) {
exchange = exc
} else {
- // TODO: Error "Can't get Exchange Info"
+ // TODO: Error "Can't get Exchange / Payment Service
Provider Info"
}
}
if !amountToTransfer.isZero {
diff --git a/TalerWallet1/Views/Banking/ManualWithdrawDone.swift
b/TalerWallet1/Views/Banking/ManualWithdrawDone.swift
index d4fa7ec..ca312e6 100644
--- a/TalerWallet1/Views/Banking/ManualWithdrawDone.swift
+++ b/TalerWallet1/Views/Banking/ManualWithdrawDone.swift
@@ -34,7 +34,7 @@ struct ManualWithdrawDone: View {
#endif
Group {
if let transactionId {
- TransactionDetailView(stack: stack.push(),
+ TransactionSummaryV(stack: stack.push(),
transactionId: transactionId,
reloadAction: reloadOneAction,
navTitle: navTitle,
diff --git a/TalerWallet1/Views/HelperViews/BarGraph.swift
b/TalerWallet1/Views/HelperViews/BarGraph.swift
index e7b60ef..e2f4d99 100644
--- a/TalerWallet1/Views/HelperViews/BarGraph.swift
+++ b/TalerWallet1/Views/HelperViews/BarGraph.swift
@@ -10,7 +10,9 @@ let MAXBARS = 10
struct BarGraphHeader: View {
private let symLog = SymLogV(0)
let stack: CallStack
- let currency: String
+ let scopeInfo: ScopeInfo?
+ let currencyName: String
+ @Binding var shouldReloadBalances: Int
@EnvironmentObject private var model: WalletModel
@Environment(\.colorSchemeContrast) private var colorSchemeContrast
@@ -20,18 +22,22 @@ struct BarGraphHeader: View {
var body: some View {
HStack (alignment: .center, spacing: 10) {
- Text(currency)
+ Text(currencyName)
.accessibilityFont(.title2)
// .foregroundColor(colorSchemeContrast == .increased ?
.primary : .secondary)
- BarGraph(transactions: $completedTransactions,
- maxBars: MAXBARS, barHeight: barHeight)
+ if let scopeInfo {
+ BarGraph(transactions: $completedTransactions,
+ maxBars: MAXBARS, barHeight: barHeight)
+ }
}
- .task {
- symLog.log(".task for BarGraphHeader(\(currency)) - reload
Transactions")
- // TODO: only load the 10 most recent transactions
- let response = await model.transactionsT(stack.push(".task -
reload Transactions for \(currency)"),
- currency: currency)
- completedTransactions = WalletModel.completedTransactions(response)
+ .task(id: shouldReloadBalances + 2_000_000) {
+ if let scopeInfo {
+ symLog.log(".task for BarGraphHeader(\(scopeInfo.currency)) -
reload Transactions")
+ // TODO: only load the 10 most recent transactions
+ let response = await model.transactionsT(stack.push(".task -
reload Transactions for \(scopeInfo.currency)"),
+ scopeInfo: scopeInfo)
+ completedTransactions =
WalletModel.completedTransactions(response)
+ }
}
}
}
diff --git a/TalerWallet1/Views/HelperViews/Buttons.swift
b/TalerWallet1/Views/HelperViews/Buttons.swift
index 7d9a788..5ef89ab 100644
--- a/TalerWallet1/Views/HelperViews/Buttons.swift
+++ b/TalerWallet1/Views/HelperViews/Buttons.swift
@@ -108,31 +108,35 @@ struct TalerButtonStyle: ButtonStyle {
var badge: String = EMPTYSTRING
public func makeBody(configuration: ButtonStyle.Configuration) -> some
View {
-// configuration.role = type == .prominent ? .primary : .normal
Only on macOS
- MyBigButton(//type: type,
- foreColor: foreColor(type: type, pressed:
configuration.isPressed, disabled: disabled),
- backColor: backColor(type: type, pressed:
configuration.isPressed, disabled: disabled),
- dimmed: dimmed,
- configuration: configuration,
- disabled: disabled,
- narrow: narrow,
- aligned: aligned,
- badge: badge)
+ // configuration.role = type == .prominent ? .primary : .normal
Only on macOS
+ MyBigButton(//type: type,
+ foreColor: foreColor(type: type, pressed: configuration.isPressed,
disabled: disabled),
+ backColor: backColor(type: type, pressed: configuration.isPressed,
disabled: disabled),
+ dimmed: dimmed,
+ configuration: configuration,
+ disabled: disabled,
+ narrow: narrow,
+ aligned: aligned,
+ badge: badge)
}
func foreColor(type: TalerButtonStyleType, pressed: Bool, disabled: Bool)
-> Color {
- return type == .plain ? WalletColors().fieldForeground : //
primary text color
- WalletColors().buttonForeColor(pressed: pressed,
- disabled: disabled,
- prominent: type == .prominent,
- balance: type == .balance)
+ if type == .plain {
+ return WalletColors().fieldForeground // primary text color
+ }
+ return WalletColors().buttonForeColor(pressed: pressed,
+ disabled: disabled,
+ prominent: type == .prominent,
+ balance: type == .balance)
}
func backColor(type: TalerButtonStyleType, pressed: Bool, disabled: Bool)
-> Color {
- return type == .plain && !pressed ? Color.clear :
- WalletColors().buttonBackColor(pressed: pressed,
- disabled: disabled,
- prominent: type == .prominent,
- balance: type == .balance)
+ if type == .plain && !pressed {
+ return Color.clear
+ }
+ return WalletColors().buttonBackColor(pressed: pressed,
+ disabled: disabled,
+ prominent: type == .prominent,
+ balance: type == .balance)
}
struct BackgroundView: View {
diff --git a/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
b/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
index 0a2dcfc..a15b953 100644
--- a/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
+++ b/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
@@ -12,10 +12,23 @@ struct QRCodeDetailView: View {
let incoming: Bool
let amount: Amount
+ @EnvironmentObject private var controller: Controller
+
+ var amountStr: String {
+ if let currencyInfo = controller.info(for: amount.currencyStr) {
+ return amount.string(currencyInfo)
+ }
+ return amount.readableDescription
+ }
+
var body: some View {
if talerURI.count > 10 {
Section {
- Text("Either", comment: "Either (copy/share the payment link
to the ...)")
+ let either = incoming ? String(localized: "Either (payer)",
defaultValue: "Either",
+ comment: "Either (copy/share
the payment link to the payer)")
+ : String(localized: "Either (payee)",
defaultValue: "Either",
+ comment: "Either (copy/share
the payment link to the payee)")
+ Text(either)
.multilineTextAlignment(.leading)
.accessibilityFont(.title3)
// .padding(.vertical)
@@ -26,10 +39,9 @@ struct QRCodeDetailView: View {
// .padding(.bottom)
.listRowSeparator(.hidden)
- let otherParty = incoming ? String(localized: "payer",
comment: "the payment link to the (otherParty), or")
- : String(localized: "payee",
comment: "the payment link to the (otherParty), or")
- Text("the payment link to the \(otherParty), or",
- comment: "(Either copy/share the payment link) to the
(payer/payee), or")
+ let otherParty = incoming ? String(localized: "the payment
link to the payer, or")
+ : String(localized: "the payment
link to the payee, or")
+ Text(otherParty)
.multilineTextAlignment(.leading)
.accessibilityFont(.title3)
.listRowSeparator(.hidden)
@@ -42,7 +54,6 @@ struct QRCodeDetailView: View {
}
.listRowSeparator(.hidden)
- let amountStr = amount.readableDescription // TODO:
currency formatter?
let hintStr = incoming ? String(localized: "let the payer scan
this QR code to pay \(amountStr).",
comment: "e.g. '5,3 €'")
: String(localized: "let the payee scan
this QR code to receive \(amountStr).",
diff --git a/TalerWallet1/Views/HelperViews/ToSButtonView.swift
b/TalerWallet1/Views/HelperViews/ToSButtonView.swift
index 87ce635..c0cdcab 100644
--- a/TalerWallet1/Views/HelperViews/ToSButtonView.swift
+++ b/TalerWallet1/Views/HelperViews/ToSButtonView.swift
@@ -14,12 +14,12 @@ struct ToSButtonView: View {
let viewID: Int // either VIEW_WITHDRAW_TOS or SHEET_WITHDRAW_TOS
let p2p: Bool
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
var body: some View {
- let hint = iconOnly ? String(localized: "You must accept the
Exchange's Terms of Service first.")
- : p2p ? String(localized: "You must accept the
Exchange's Terms of Service first before you can receive electronic cash in
your wallet.", comment: "P2P Receive")
- : String(localized: "You must accept the
Exchange's Terms of Service first before you can use it to withdraw electronic
cash to your wallet.")
+ let hint = minimalistic ? String(localized: "You must accept the
Payment Service's Terms of Service first.")
+ : p2p ? String(localized: "You must accept the
Payment Service Provider's Terms of Service first before you can receive
electronic cash in your wallet.", comment: "P2P Receive")
+ : String(localized: "You must accept the
Payment Service Provider's Terms of Service first before you can use it to
withdraw electronic cash to your wallet.")
Text(hint)
.accessibilityFont(.body)
.multilineTextAlignment(.leading)
diff --git a/TalerWallet1/Views/Main/MainView.swift
b/TalerWallet1/Views/Main/MainView.swift
index ce54497..e4e13e9 100644
--- a/TalerWallet1/Views/Main/MainView.swift
+++ b/TalerWallet1/Views/Main/MainView.swift
@@ -85,7 +85,7 @@ extension MainView {
@State private var shouldReloadBalances = 0
@State private var balances: [Balance] = []
@Binding var talerFont: Int
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
@EnvironmentObject private var viewState: ViewState //
popToRootView()
@@ -145,7 +145,7 @@ extension MainView {
let delay: UInt = 0 // no delay for release builds
#endif
Group {
-// let labelStyle = iconOnly ? IconOnlyLabelStyle() :
TitleAndIconLabelStyle() // labelStyle doesn't work
+// let labelStyle = minimalistic ? IconOnlyLabelStyle() :
TitleAndIconLabelStyle() // labelStyle doesn't work
TabView(selection: tabSelection()) {
NavigationView {
BalancesListView(stack: stack.push(balancesTitle),
@@ -157,7 +157,7 @@ extension MainView {
.tabItem {
Image(systemName: "chart.bar.xaxis") // iOS
will automatically use filled variant
.accessibilityLabel(balancesTitle)
- if !iconOnly { Text(balancesTitle) }
+ if !minimalistic { Text(balancesTitle) }
}
.tag(Tab.balances)
.badge(0) // TODO: set badge if transaction finished
in background
@@ -170,7 +170,7 @@ extension MainView {
.tabItem {
Image(systemName: "building.columns") //
"arrow.triangle.2.circlepath")
.accessibilityLabel(exchangesTitle)
- if !iconOnly { Text(exchangesTitle) }
+ if !minimalistic { Text(exchangesTitle) }
}
.tag(Tab.exchanges)
@@ -180,7 +180,7 @@ extension MainView {
.tabItem {
Image(systemName: "gear") // system will
automatically use filled variant
.accessibilityLabel(settingsTitle)
- if !iconOnly { Text(settingsTitle) }
+ if !minimalistic { Text(settingsTitle) }
}
.tag(Tab.settings)
}
diff --git a/TalerWallet1/Views/Peer2peer/P2PReadyV.swift
b/TalerWallet1/Views/Peer2peer/P2PReadyV.swift
index e155bd8..ee26f83 100644
--- a/TalerWallet1/Views/Peer2peer/P2PReadyV.swift
+++ b/TalerWallet1/Views/Peer2peer/P2PReadyV.swift
@@ -38,7 +38,7 @@ struct P2PReadyV: View {
#endif
Group {
if let transactionId {
- TransactionDetailView(stack: stack.push(),
+ TransactionSummaryV(stack: stack.push(),
transactionId: transactionId,
reloadAction: reloadOneAction,
navTitle: navTitle,
@@ -51,7 +51,12 @@ struct P2PReadyV: View {
.navigationBarBackButtonHidden(true)
.interactiveDismissDisabled() // can only use "Done"
button to dismiss
} else {
- LoadingView(url: nil, message: "for
\(amountToTransfer.currencyStr)")
+#if DEBUG
+ let message = amountToTransfer.currencyStr
+#else
+ let message: String? = nil
+#endif
+ LoadingView(url: nil, message: message)
}
}
.navigationTitle(navTitle)
@@ -80,7 +85,7 @@ struct P2PReadyV: View {
purse_expiration: timestamp)
// TODO: let user choose baseURL
let response = try await model.initiatePeerPushDebitM(nil,
terms: terms)
- // will switch from WithdrawProgressView to
TransactionDetailView
+ // will switch from WithdrawProgressView to
TransactionSummaryV
transactionId = response.transactionId
} else {
let terms = PeerContractTerms(amount: amountToTransfer,
@@ -88,7 +93,7 @@ struct P2PReadyV: View {
purse_expiration: timestamp)
// TODO: let user choose baseURL
let response = try await
model.initiatePeerPullCreditM(nil, terms: terms)
- // will switch from WithdrawProgressView to
TransactionDetailView
+ // will switch from WithdrawProgressView to
TransactionSummaryV
transactionId = response.transactionId
}
} catch { // TODO: error
diff --git a/TalerWallet1/Views/Peer2peer/P2PSubjectV.swift
b/TalerWallet1/Views/Peer2peer/P2PSubjectV.swift
index 4ee9f03..57e2261 100644
--- a/TalerWallet1/Views/Peer2peer/P2PSubjectV.swift
+++ b/TalerWallet1/Views/Peer2peer/P2PSubjectV.swift
@@ -26,7 +26,7 @@ struct P2PSubjectV: View {
@Binding var expireDays: UInt
@EnvironmentObject private var model: WalletModel
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var myFeeLabel: String = EMPTYSTRING
@State private var transactionStarted: Bool = false
@@ -65,7 +65,7 @@ struct P2PSubjectV: View {
.accessibilityFont(.body)
}
}
- if !iconOnly {
+ if !minimalistic {
Text("Enter subject:") // Purpose
.accessibilityFont(.title3)
.accessibilityAddTraits(.isHeader)
@@ -73,7 +73,7 @@ struct P2PSubjectV: View {
.padding(.top)
}
Group { if #available(iOS 16.0, *) {
- TextField(iconOnly ? "Subject" : EMPTYSTRING, text:
$summary, axis: .vertical)
+ TextField(minimalistic ? "Subject" : EMPTYSTRING, text:
$summary, axis: .vertical)
.focused($isFocused)
.lineLimit(2...)
} else {
@@ -119,6 +119,7 @@ struct P2PSubjectV: View {
.disabled(disabled)
.accessibilityHint(disabled ? "enabled when subject and
expiration are set" : EMPTYSTRING)
}.padding(.horizontal) } // ScrollVStack
+// .scrollBounceBehavior(.basedOnSize) needs iOS 16.4
.navigationTitle(subjectTitle(amountToTransfer, currencyInfo))
.background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all))
.onAppear {
diff --git a/TalerWallet1/Views/Peer2peer/RequestPayment.swift
b/TalerWallet1/Views/Peer2peer/RequestPayment.swift
index 5de2e1d..a282f08 100644
--- a/TalerWallet1/Views/Peer2peer/RequestPayment.swift
+++ b/TalerWallet1/Views/Peer2peer/RequestPayment.swift
@@ -16,7 +16,7 @@ struct RequestPayment: View {
@EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var peerPullCheck: CheckPeerPullCreditResponse? = nil
@State private var expireDays: UInt = 0
@@ -63,7 +63,7 @@ struct RequestPayment: View {
ScrollView { VStack(alignment: .trailing) {
CurrencyInputView(amount: $amountToTransfer,
available: nil,
- title: iconOnly ? String(localized: "Amount:")
+ title: minimalistic ? String(localized:
"Amount:")
: String(localized: "Amount to
request:"),
shortcutAction: shortcutAction)
.padding(.top)
@@ -78,9 +78,9 @@ struct RequestPayment: View {
.background(NavigationLink(destination: shortcutDestination,
isActive: $buttonSelected)
{ EmptyView() }.frame(width: 0).opacity(0).hidden()
)
- } } // ScrollVStack
+ }.padding(.horizontal) } // ScrollVStack
.frame(maxWidth: .infinity, alignment: .leading)
- .padding(.horizontal) // Lists do this automatically, but this is a
VStack
+// .scrollBounceBehavior(.basedOnSize) needs iOS 16.4
.background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all))
.navigationTitle(navTitle)
.onAppear {
diff --git a/TalerWallet1/Views/Peer2peer/SendAmount.swift
b/TalerWallet1/Views/Peer2peer/SendAmount.swift
index b5c4f5c..8261ab2 100644
--- a/TalerWallet1/Views/Peer2peer/SendAmount.swift
+++ b/TalerWallet1/Views/Peer2peer/SendAmount.swift
@@ -17,7 +17,7 @@ struct SendAmount: View {
@EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State var peerPushCheck: CheckPeerPushDebitResponse? = nil
@State private var expireDays = SEVENDAYS
@@ -87,7 +87,7 @@ struct SendAmount: View {
.padding(.bottom, 2)
CurrencyInputView(amount: $amountToTransfer,
available: amountAvailable,
- title: iconOnly ? String(localized: "Amount:")
+ title: minimalistic ? String(localized:
"Amount:")
: String(localized: "Amount to
send:"),
shortcutAction: shortcutAction)
Text(insufficient ? insufficientLabel
@@ -101,9 +101,9 @@ struct SendAmount: View {
.background(NavigationLink(destination: shortcutDestination,
isActive: $buttonSelected)
{ EmptyView() }.frame(width: 0).opacity(0).hidden()
)
- } } // ScrollVStack
+ }.padding(.horizontal) } // ScrollVStack
.frame(maxWidth: .infinity, alignment: .leading)
- .padding(.horizontal)
+// .scrollBounceBehavior(.basedOnSize) needs iOS 16.4
.background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all))
.navigationTitle(navTitle)
.onAppear {
diff --git a/TalerWallet1/Views/Settings/AboutView.swift
b/TalerWallet1/Views/Settings/AboutView.swift
index a00230f..5997dff 100644
--- a/TalerWallet1/Views/Settings/AboutView.swift
+++ b/TalerWallet1/Views/Settings/AboutView.swift
@@ -18,9 +18,10 @@ struct AboutView: View {
@AppStorage("developerMode") var developerMode: Bool = false
#endif
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var rotationEnabled = false
+ @State private var showGitHash = false
@State private var listID = UUID()
var body: some View {
@@ -34,13 +35,11 @@ struct AboutView: View {
HStack {
Spacer()
RotatingTaler(size: 100, rotationEnabled: $rotationEnabled)
- .onTapGesture(count: 2) {
- rotationEnabled.toggle()
- }
+ .onTapGesture(count: 1) { rotationEnabled.toggle() }
Spacer()
}
SettingsItem(name: "Visit the taler.net website", id1: "web",
- description: iconOnly ? nil : String(localized:
"More info about Gnu Taler in general...")) { }
+ description: minimalistic ? nil :
String(localized: "More info about Gnu Taler in general...")) { }
.accessibilityAddTraits(.isLink)
.accessibilityRemoveTraits(.isStaticText)
.onTapGesture() {
@@ -50,9 +49,22 @@ struct AboutView: View {
SettingsItem(name: "App Version", id1: "app") {
Text(verbatim: "\(Bundle.main.releaseVersionNumberPretty)")
}
- SettingsItem(name: "Wallet Core Version", id1: "wallet-core") {
- Text(verbatim: "\(walletCore.versionInfo?.version ??
"unknown")")
- }
+ Group {
+ if showGitHash {
+ SettingsItem(name: "Wallet-Core Git", id1:
"wallet-coreG") {
+ if let gitHash =
walletCore.versionInfo?.implementationGitHash {
+ let index = gitHash.index(gitHash.startIndex,
offsetBy: 7)
+ Text(gitHash[..<index])
+ } else {
+ Text(verbatim: "unknown")
+ }
+ }
+ } else {
+ SettingsItem(name: "Wallet-Core Version", id1:
"wallet-coreV") {
+ Text(verbatim:
"\(walletCore.versionInfo?.implementationSemver ?? "unknown")")
+ }
+ }
+ }.onTapGesture(count: 1) { showGitHash.toggle() }
// SettingsItem(name: "Supported Exchange Versions", id1:
"exchange") {
// Text(verbatim: "\(walletCore.versionInfo?.exchange ??
"unknown")")
// }
@@ -72,21 +84,30 @@ struct AboutView: View {
}
.onDisappear() {
}
- .task {
- try? await Task.sleep(nanoseconds: 1_000_000_000 * UInt64(5))
- rotationEnabled.toggle()
- }
+// .task {
+// try? await Task.sleep(nanoseconds: 1_000_000_000 * UInt64(5))
+// rotationEnabled.toggle()
+// }
}
}
extension Bundle {
+ var bundleName: String? {
+ return infoDictionary?["CFBundleDisplayName"] as? String
+ }
var releaseVersionNumber: String? {
return infoDictionary?["CFBundleShortVersionString"] as? String
}
- var buildVersionNumber: String? {
- return infoDictionary?["CFBundleVersion"] as? String
+ var buildVersionNumber: String {
+ let build = infoDictionary?["CFBundleVersion"]
+ let zero = "0"
+ if let build {
+ return build as? String ?? zero
+ }
+ return zero
}
var releaseVersionNumberPretty: String {
- return "v\(releaseVersionNumber ?? "1.0.0")"
+ let release = releaseVersionNumber ?? "1.0.0"
+ return "v\(release) (\(buildVersionNumber))"
}
}
// MARK: -
diff --git a/TalerWallet1/Views/Settings/SettingsView.swift
b/TalerWallet1/Views/Settings/SettingsView.swift
index 06d552d..ccc3260 100644
--- a/TalerWallet1/Views/Settings/SettingsView.swift
+++ b/TalerWallet1/Views/Settings/SettingsView.swift
@@ -36,7 +36,7 @@ struct SettingsView: View {
@AppStorage("talerFont") var talerFont: Int = 0
@AppStorage("developDelay") var developDelay: Bool = false
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var checkDisabled = false
@State private var withDrawDisabled = false
@@ -85,7 +85,13 @@ struct SettingsView: View {
let walletCore = WalletCore.shared
Group {
List {
- let aboutStr = String(localized: "About GNU Taler")
+#if TALER_WALLET
+ let appName = "Taler Wallet"
+#else
+ let appName = "GNU Taler"
+#endif
+ let localizedAppName = Bundle.main.bundleName ?? appName
+ let aboutStr = String(localized: "About \(localizedAppName)")
NavigationLink { // whole row like in a tableView
LazyView { AboutView(stack: stack.push(), navTitle:
aboutStr) }
} label: {
@@ -129,14 +135,14 @@ struct SettingsView: View {
// .id("font")
SettingsStyle(title: String(localized: "Liststyle:"),
myListStyle: $myListStyle)
.id("liststyle")
- SettingsToggle(name: String(localized: "Minimalistic"), value:
$iconOnly, id1: "minimal",
+ SettingsToggle(name: String(localized: "Minimalistic"), value:
$minimalistic, id1: "minimal",
description: hideDescriptions ? nil :
String(localized: "Omit text where possible")) {
- hideDescriptions = iconOnly //withAnimation {
hideDescriptions = iconOnly }
+ hideDescriptions = minimalistic //withAnimation {
hideDescriptions = minimalistic }
}
if diagnosticModeEnabled {
SettingsToggle(name: String("Developer Mode"), value:
$developerMode, id1: "devMode",
description: hideDescriptions ? nil : String("More
information intended for debugging")) {
- withAnimation { showDevelopItems = developerMode }
+ withAnimation(Animation.linear.delay(0.8)) {
showDevelopItems = developerMode }
}
if showDevelopItems { // show or hide the following items
SettingsItem(name: String("Withdraw \(DEMOCURRENCY)"),
id1: "demo1with",
@@ -178,6 +184,21 @@ struct SettingsView: View {
walletCore.developDelay = delay}), id1: "delay",
description: hideDescriptions ? nil :
String("After each wallet-core action"))
.id("delay")
+ SettingsItem(name: String("Run Dev Experiment"), id1:
"applyDevExperiment",
+ description: hideDescriptions ? nil :
"dev-experiment/insert-pending-refresh") {
+ let title = "Refresh"
+ Button(title) {
+ Task { // runs on MainActor
+ symLog.log("running applyDevExperiment
Refresh")
+ do {
+ try await
model.devExperimentT(talerUri: "taler://dev-experiment/insert-pending-refresh")
+ } catch { // TODO: show error
+ symLog.log(error.localizedDescription)
+ }
+ }
+ }
+ .buttonStyle(.bordered)
+ }.id("Refresh")
SettingsItem(name: String("Run Integration Test"),
id1: "demo1test",
description: hideDescriptions ? nil :
String("Perform basic test transactions")) {
let title = "Demo 1"
@@ -289,7 +310,7 @@ struct SettingsView: View {
.navigationTitle(navTitle)
.onAppear() {
showDevelopItems = developerMode
- hideDescriptions = iconOnly
+ hideDescriptions = minimalistic
DebugViewC.shared.setViewID(VIEW_SETTINGS, stack: stack.push())
}
.onDisappear() {
diff --git a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift
b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift
index 51cd0d4..ede5272 100644
--- a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift
+++ b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift
@@ -17,15 +17,6 @@ struct P2pAcceptDone: View {
@EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
- @State private var finished: Bool = false
-
- func reloadOneAction(_ transactionId: String) async throws -> Transaction {
- return try await model.getTransactionByIdT(transactionId)
- }
- func dismissTopAnimated(_ stack: CallStack) {
- dismissTop()
- }
-
var body: some View {
#if PRINT_CHANGES
let _ = Self._printChanges()
@@ -33,18 +24,9 @@ struct P2pAcceptDone: View {
#endif
let navTitle = incoming ? String(localized: "Received P2P", comment:
"Title, short")
: String(localized: "Paid P2P", comment:
"Title, short")
- TransactionDetailView(stack: stack.push(),
- transactionId: transactionId,
- reloadAction: reloadOneAction,
- navTitle: navTitle,
- doneAction: dismissTopAnimated,
- abortAction: nil,
- deleteAction: nil,
- failAction: nil,
- suspendAction: nil,
- resumeAction: nil)
+ LoadingView(url: nil, message: "Accepting...")
.navigationBarBackButtonHidden(true)
- .interactiveDismissDisabled() // can only use "Done"
button to dismiss
+// .interactiveDismissDisabled() // can only use "Done"
button to dismiss
.navigationTitle(navTitle)
.onAppear() {
symLog.log("onAppear")
@@ -58,7 +40,7 @@ struct P2pAcceptDone: View {
} else {
_ = try await
model.confirmPeerPullDebitM(transactionId)
}
- finished = true
+ dismissTop()
} catch { // TODO: error
symLog.log(error.localizedDescription)
controller.playSound(0)
diff --git a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pPayURIView.swift
b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pPayURIView.swift
index 3b64c21..b27203f 100644
--- a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pPayURIView.swift
+++ b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pPayURIView.swift
@@ -29,16 +29,18 @@ struct P2pPayURIView: View {
let effective = peerPullDebitResponse.amountEffective
let currency = raw.currencyStr
let fee = try! Amount.diff(raw, effective)
- ThreeAmountsV(topTitle: String(localized: "Amount to
pay:"),
- topAbbrev: String(localized: "Pay:"),
+ ThreeAmountsV(stack: stack.push(),
+ topTitle: String(localized: "Amount to
pay:"),
+ topAbbrev: String(localized: "Pay:", comment:
"mini"),
topAmount: raw, fee: fee,
bottomTitle: String(localized: "Amount to be
spent:"),
- bottomAbbrev: String(localized: "Effective:"),
+ bottomAbbrev: String(localized: "Effective:",
comment: "mini"),
bottomAmount: effective,
large: false, pending: false, incoming:
false,
baseURL: nil,
status: nil,
- summary:
peerPullDebitResponse.contractTerms.summary)
+ summary:
peerPullDebitResponse.contractTerms.summary,
+ merchant: nil)
let expiration =
peerPullDebitResponse.contractTerms.purse_expiration
let (dateString, date) = TalerDater.dateString(from:
expiration)
let accessibilityDate = TalerDater.accessibilityDate(date)
?? dateString
@@ -61,7 +63,12 @@ struct P2pPayURIView: View {
.buttonStyle(TalerButtonStyle(type: .prominent))
.padding(.horizontal)
} else {
- LoadingView(url: url, message: nil)
+#if DEBUG
+ let message = url.host
+#else
+ let message: String? = nil
+#endif
+ LoadingView(url: nil, message: message)
.task { do {
symLog.log(".task")
let ppDebitResponse = try await
model.preparePeerPullDebitM(url.absoluteString)
diff --git a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift
b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift
index f810da7..dfb4295 100644
--- a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift
+++ b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift
@@ -37,16 +37,18 @@ struct P2pReceiveURIView: View {
let effective = peerPushCreditResponse.amountEffective
let currency = raw.currencyStr
let fee = try! Amount.diff(raw, effective)
- ThreeAmountsV(topTitle: String(localized: "Amount to
receive:"),
- topAbbrev: String(localized: "Receive:"),
+ ThreeAmountsV(stack: stack.push(),
+ topTitle: String(localized: "Gross Amount to
receive:"),
+ topAbbrev: String(localized: "Receive
gross:", comment: "mini"),
topAmount: raw, fee: fee,
- bottomTitle: String(localized: "Amount to
obtain:"),
- bottomAbbrev: String(localized: "Effective:"),
+ bottomTitle: String(localized: "Net Amount to
receive:"),
+ bottomAbbrev: String(localized: "Receive net:",
comment: "mini"),
bottomAmount: effective,
large: false, pending: false, incoming:
true,
baseURL: nil,
status: nil,
- summary:
peerPushCreditResponse.contractTerms.summary)
+ summary:
peerPushCreditResponse.contractTerms.summary,
+ merchant: nil)
let expiration =
peerPushCreditResponse.contractTerms.purse_expiration
let (dateString, date) = TalerDater.dateString(from:
expiration)
let accessibilityDate = TalerDater.accessibilityDate(date)
?? dateString
@@ -70,14 +72,19 @@ struct P2pReceiveURIView: View {
.padding(.horizontal)
}
} else {
- LoadingView(url: url, message: nil)
+#if DEBUG
+ let message = url.host
+#else
+ let message: String? = nil
+#endif
+ LoadingView(url: nil, message: message)
}
}
.onAppear() {
symLog.log("onAppear")
DebugViewC.shared.setSheetID(SHEET_RCV_P2P)
}
- .task {
+ .task { // must be here and not at LoadingView(), because this needs
to run a 2nd time after ToS was accepted
do { // TODO: cancelled
symLog.log(".task")
let ppResponse = try await
model.preparePeerPushCreditM(url.absoluteString)
diff --git a/TalerWallet1/Views/Sheets/Payment/PayTemplateView.swift
b/TalerWallet1/Views/Sheets/Payment/PayTemplateView.swift
index 019152b..4670af6 100644
--- a/TalerWallet1/Views/Sheets/Payment/PayTemplateView.swift
+++ b/TalerWallet1/Views/Sheets/Payment/PayTemplateView.swift
@@ -55,34 +55,38 @@ struct PayTemplateView: View {
let raw = preparePayResult.amountRaw
let currency = raw.currencyStr
let topTitle = String(localized: "Amount to pay:")
- let topAbbrev = String(localized: "Pay:")
+ let topAbbrev = String(localized: "Pay:", comment: "mini")
if let effective {
// TODO: already paid
let fee = try! Amount.diff(raw, effective) // TODO:
different currencies
- ThreeAmountsV(topTitle: topTitle,
+ ThreeAmountsV(stack: stack.push(),
+ topTitle: topTitle,
topAbbrev: topAbbrev,
topAmount: raw, fee: fee,
bottomTitle: String(localized: "Amount to
spend:"),
- bottomAbbrev: String(localized: "Effective:"),
+ bottomAbbrev: String(localized: "Effective:",
comment: "mini"),
bottomAmount: effective,
large: false, pending: false, incoming:
false,
baseURL: baseURL,
status: nil,
- summary: nil)
+ summary: nil,
+ merchant: nil)
// TODO: payment: popup with all possible exchanges, check
fees
} else if let balanceDetails = preparePayResult.balanceDetails
{ // Insufficient
Text("You don't have enough \(currency)")
.accessibilityFont(.body)
- ThreeAmountsV(topTitle: topTitle,
+ ThreeAmountsV(stack: stack.push(),
+ topTitle: topTitle,
topAbbrev: topAbbrev,
topAmount: raw, fee: nil,
bottomTitle: String(localized: "Amount
available:"),
- bottomAbbrev: String(localized: "Available:"),
+ bottomAbbrev: String(localized: "Available:",
comment: "mini"),
bottomAmount: balanceDetails.balanceAvailable,
large: false, pending: false, incoming:
false,
baseURL: baseURL,
status: nil,
- summary: nil)
+ summary: nil,
+ merchant: nil)
} else {
// TODO: Error - neither effective nor balanceDetails
Text("Error")
diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentDone.swift
b/TalerWallet1/Views/Sheets/Payment/PaymentDone.swift
new file mode 100644
index 0000000..2b7f449
--- /dev/null
+++ b/TalerWallet1/Views/Sheets/Payment/PaymentDone.swift
@@ -0,0 +1,77 @@
+/*
+ * This file is part of GNU Taler, ©2022-23 Taler Systems S.A.
+ * See LICENSE.md
+ */
+import SwiftUI
+import SymLog
+
+struct PaymentDone: View {
+ private let symLog = SymLogV(0)
+ let stack: CallStack
+ let transactionId: String
+
+ @EnvironmentObject private var controller: Controller
+ @EnvironmentObject private var model: WalletModel
+
+ @State var paymentDone: Bool = false
+
+ func reloadOneAction(_ transactionId: String) async throws -> Transaction {
+ return try await model.getTransactionByIdT(transactionId)
+ }
+ func dismissTopAnimated(_ stack: CallStack) {
+ dismissTop()
+ }
+
+ var body: some View {
+#if PRINT_CHANGES
+ let _ = Self._printChanges()
+ let _ = symLog.vlog() // just to get the # to compare it with
.onAppear & onDisappear
+#endif
+ Group {
+ if paymentDone {
+ let navTitle = String(localized: "Paid", comment: "Title,
short")
+ TransactionSummaryV(stack: stack.push(),
+ transactionId: transactionId,
+ reloadAction: reloadOneAction,
+ navTitle: navTitle,
+ doneAction: dismissTopAnimated,
+ abortAction: nil,
+ deleteAction: nil,
+ failAction: nil,
+ suspendAction: nil,
+ resumeAction: nil)
+ .navigationBarBackButtonHidden(true)
+ .interactiveDismissDisabled() // can only use "Done"
button to dismiss
+ .navigationTitle(navTitle)
+ } else {
+ LoadingView(url: nil, message: "Paying...")
+ .task {
+ do {
+ let confirmPayResult = try await
model.confirmPayM(transactionId)
+// symLog.log(confirmPayResult as Any)
+ if confirmPayResult.type == "done" {
+ paymentDone = true
+ } else {
+ controller.playSound(0)
+ // TODO: show error
+ dismissTop()
+ }
+ } catch {
+ controller.playSound(0)
+ // TODO: error
+ symLog.log(error.localizedDescription)
+ dismissTop()
+ }
+ }
+ }
+ }.onAppear() {
+ symLog.log("onAppear")
+ DebugViewC.shared.setSheetID(SHEET_PAY_ACCEPT)
+ }
+ }
+}
+
+// MARK: -
+//#Preview {
+// PaymentDone(stack: CallStack("Preview"))
+//}
diff --git a/TalerWallet1/Views/Sheets/Payment/PaymentView.swift
b/TalerWallet1/Views/Sheets/Payment/PaymentView.swift
index 1124006..3776129 100644
--- a/TalerWallet1/Views/Sheets/Payment/PaymentView.swift
+++ b/TalerWallet1/Views/Sheets/Payment/PaymentView.swift
@@ -16,31 +16,13 @@ struct PaymentView: View {
// the scanned URL
let url: URL
- @EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
- func acceptAction(preparePayResult: PreparePayResult) {
- Task { // runs on MainActor
- 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
var body: some View {
+ Group {
if let preparePayResult {
let effective = preparePayResult.amountEffective
let terms = preparePayResult.contractTerms
@@ -50,34 +32,38 @@ struct PaymentView: View {
let raw = preparePayResult.amountRaw
let currency = raw.currencyStr
let topTitle = String(localized: "Amount to pay:")
- let topAbbrev = String(localized: "Pay:")
+ let topAbbrev = String(localized: "Pay:", comment: "mini")
if let effective {
// TODO: already paid
let fee = try! Amount.diff(raw, effective) // TODO:
different currencies
- ThreeAmountsV(topTitle: topTitle,
+ ThreeAmountsV(stack: stack.push(),
+ topTitle: topTitle,
topAbbrev: topAbbrev,
topAmount: raw, fee: fee,
bottomTitle: String(localized: "Amount to
spend:"),
- bottomAbbrev: String(localized: "Effective:"),
+ bottomAbbrev: String(localized: "Effective:",
comment: "mini"),
bottomAmount: effective,
large: false, pending: false, incoming:
false,
baseURL: baseURL,
status: nil,
- summary: terms.summary)
+ summary: terms.summary,
+ merchant: terms.merchant.name)
// TODO: payment: popup with all possible exchanges, check
fees
} else if let balanceDetails = preparePayResult.balanceDetails
{ // Insufficient
Text("You don't have enough \(currency)")
.accessibilityFont(.headline)
- ThreeAmountsV(topTitle: topTitle,
+ ThreeAmountsV(stack: stack.push(),
+ topTitle: topTitle,
topAbbrev: topAbbrev,
topAmount: raw, fee: nil,
bottomTitle: String(localized: "Amount
available:"),
- bottomAbbrev: String(localized: "Available:"),
+ bottomAbbrev: String(localized: "Available:",
comment: "mini"),
bottomAmount: balanceDetails.balanceAvailable,
large: false, pending: false, incoming:
false,
baseURL: baseURL,
status: nil,
- summary: terms.summary)
+ summary: terms.summary,
+ merchant: terms.merchant.name)
} else {
// TODO: Error - neither effective nor balanceDetails
Text("Error")
@@ -87,9 +73,14 @@ struct PaymentView: View {
.listStyle(myListStyle.style).anyView
.safeAreaInset(edge: .bottom) {
if let effective {
- Button(navTitle, action: { acceptAction(preparePayResult:
preparePayResult) })
- .buttonStyle(TalerButtonStyle(type: .prominent))
- .padding(.horizontal)
+ NavigationLink(destination: LazyView {
+ PaymentDone(stack: stack.push(),
+ transactionId: preparePayResult.transactionId)
+ }) {
+ Text(navTitle) // Confirm Payment
+ }
+ .buttonStyle(TalerButtonStyle(type: .prominent))
+ .padding(.horizontal)
} else {
Button("Cancel", action: { dismissTop() })
.buttonStyle(TalerButtonStyle(type: .bordered))
@@ -97,22 +88,22 @@ struct PaymentView: View {
}
}
.navigationTitle(navTitle)
- .onAppear() {
- symLog.log("onAppear")
- DebugViewC.shared.setSheetID(SHEET_PAYMENT)
- }
} else {
LoadingView(url: url, message: nil)
- .task {
- do {
- symLog.log(".task")
- let result = try await
model.preparePayForUriM(url.absoluteString)
- preparePayResult = result
- } catch { // TODO: error
- symLog.log(error.localizedDescription)
- }
+ .task { // this runs only once
+ do { // TODO: cancelled
+ symLog.log(".task")
+ let result = try await
model.preparePayForUriM(url.absoluteString)
+ preparePayResult = result
+ } catch { // TODO: error
+ symLog.log(error.localizedDescription)
}
+ }
}
+ }.onAppear() {
+ symLog.log("onAppear")
+ DebugViewC.shared.setSheetID(SHEET_PAYMENT)
+ }
}
}
// MARK: -
diff --git a/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift
b/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift
index 66d1870..593b8c2 100644
--- a/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift
+++ b/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift
@@ -23,7 +23,7 @@ struct RefundURIView: View {
var body: some View {
if let refundTransactionId {
- TransactionDetailView(stack: stack.push(),
+ TransactionSummaryV(stack: stack.push(),
transactionId: refundTransactionId,
reloadAction: reloadOneAction,
navTitle: nil, // navTitle,
@@ -52,7 +52,7 @@ struct RefundURIView: View {
struct RefundURIView_Previews: PreviewProvider {
static var previews: some View {
let transactionId = "txn:refund:12345"
- let url = URL(string: "taler://reward/survey")!
+ let url = URL(string: "taler://refund/txId")!
RefundURIView(stack: CallStack("Preview"), url: url,
refundTransactionId: transactionId)
}
}
diff --git a/TalerWallet1/Views/Sheets/URLSheet.swift
b/TalerWallet1/Views/Sheets/URLSheet.swift
index 09a0fc2..61b61af 100644
--- a/TalerWallet1/Views/Sheets/URLSheet.swift
+++ b/TalerWallet1/Views/Sheets/URLSheet.swift
@@ -38,8 +38,6 @@ struct URLSheet: View {
PayTemplateView(stack: stack.push(), url: urlToOpen)
case .refund:
RefundURIView(stack: stack.push(), url: urlToOpen)
-// case .reward:
-// RewardURIView(url: urlToOpen)
default: // Error view
VStack {
Text("unknown command")
diff --git
a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift
b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift
index a15ebd3..b10d0c0 100644
--- a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift
+++ b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawAcceptDone.swift
@@ -33,7 +33,7 @@ struct WithdrawAcceptDone: View {
#endif
Group {
if let transactionId {
- TransactionDetailView(stack: stack.push(),
+ TransactionSummaryV(stack: stack.push(),
transactionId: transactionId,
reloadAction: reloadOneAction,
navTitle: navTitle,
diff --git
a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift
b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift
index 284d94d..43b04c3 100644
--- a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift
+++ b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift
@@ -43,16 +43,18 @@ struct WithdrawURIView: View {
let outColor = WalletColors().transactionColor(false)
let inColor = WalletColors().transactionColor(true)
- ThreeAmountsV(topTitle: String(localized: "Chosen amount
to withdraw:"),
- topAbbrev: String(localized: "Chosen:"),
+ ThreeAmountsV(stack: stack.push(),
+ topTitle: String(localized: "Chosen amount
to withdraw:"),
+ topAbbrev: String(localized: "Chosen:",
comment: "mini"),
topAmount: raw, fee: fee,
bottomTitle: String(localized: "Amount to be
withdrawn:"),
- bottomAbbrev: String(localized: "Effective:"),
+ bottomAbbrev: String(localized: "Effective:",
comment: "mini"),
bottomAmount: effective,
large: false, pending: false, incoming:
true,
baseURL: exchange.exchangeBaseUrl,
status: nil, //
common.txState.major.localizedState
- summary: nil)
+ summary: nil,
+ merchant: nil)
let someCoins = SomeCoins(details: withdrawalAmountDetails)
QuiteSomeCoins(someCoins: someCoins,
shouldShowFee: true, // TODO: set to
false if we never charge withdrawal fees
@@ -74,7 +76,12 @@ struct WithdrawURIView: View {
.padding(.horizontal)
}
} else { // no details or no exchange
- LoadingView(url: url, message: nil)
+#if DEBUG
+ let message = url.host
+#else
+ let message: String? = nil
+#endif
+ LoadingView(url: nil, message: message)
}
}
.onAppear() {
diff --git a/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift
b/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift
index dc32e73..8859513 100644
--- a/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift
+++ b/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift
@@ -28,6 +28,7 @@ struct WithdrawExchangeV: View {
exchangeBaseUrl: exchangeBaseUrl,
amountToTransfer: $amountToTransfer)
} else {
+ // TODO: Error
LoadingView(url: url, message: "No exchangeBaseUrl!")
}
}
diff --git a/TalerWallet1/Views/Transactions/ManualDetailsV.swift
b/TalerWallet1/Views/Transactions/ManualDetailsV.swift
index 9099f45..a6c4771 100644
--- a/TalerWallet1/Views/Transactions/ManualDetailsV.swift
+++ b/TalerWallet1/Views/Transactions/ManualDetailsV.swift
@@ -40,14 +40,14 @@ struct TransferRestrictionsV: View {
let obtainStr: String
let restrictions: [AccountRestriction]?
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var selectedLanguage = Locale.preferredLanguageCode
var body: some View {
VStack(alignment: .leading) {
- Text(iconOnly ? "Transfer \(amountStr) to the Exchange."
- : "You need to transfer \(amountStr) from your
regular bank account to the Exchange to receive \(obtainStr) as electronic cash
in this wallet.")
+ Text(minimalistic ? "Transfer \(amountStr) to the Payment Service."
+ : "You need to transfer \(amountStr) from your
regular bank account to the Payment Service Provider to receive \(obtainStr) as
electronic cash in this wallet.")
.multilineTextAlignment(.leading)
if let restrictions {
ForEach(restrictions) { restriction in
@@ -73,7 +73,7 @@ struct ManualDetailsV: View {
var common : TransactionCommon
var details : WithdrawalDetails
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
@State private var accountID = 0
@State private var listID = UUID()
@@ -86,8 +86,9 @@ struct ManualDetailsV: View {
var body: some View {
if let accountDetails = details.exchangeCreditAccountDetails {
- if !iconOnly {
- Text("The Exchange is waiting for your wire-transfer.")
+ if !minimalistic {
+ Text("The Payment Service Provider is waiting for your
wire-transfer.")
+ .bold()
.multilineTextAlignment(.leading)
.listRowSeparator(.hidden)
}
@@ -120,19 +121,19 @@ struct ManualDetailsV: View {
} .padding(.leading)
.padding(.top, -8)
- let step1 = Text(iconOnly ? "**Step 1:** Copy+Paste this subject:"
- : "**Step 1:** Copy this code and paste
it into the subject/purpose field in your banking app or bank website:")
+ let step1 = Text(minimalistic ? "**Step 1:** Copy+Paste this
subject:"
+ : "**Step 1:** Copy this code and paste it into the
subject/purpose field in your banking app or bank website:")
.multilineTextAlignment(.leading)
let mandatory = Text("This is mandatory, otherwise your money will
not arrive in this wallet.")
.bold()
.multilineTextAlignment(.leading)
.listRowSeparator(.hidden)
- let step2 = Text(iconOnly ? "**Step 2:** Copy+Paste this IBAN:"
- : "**Step 2:** If you don't 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 (and save it as favourite
for the next time):")
+ let step2 = Text(minimalistic ? "**Step 2:** Copy+Paste this IBAN:"
+ : "**Step 2:** If you don't 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 (and save it as favourite for the next
time):")
.multilineTextAlignment(.leading)
.padding(.top)
- let step3 = Text(iconOnly ? "**Step 3:** Transfer \(amountStr)."
- : "**Step 3:** Finish the wire transfer
of \(amountStr) in your banking app or website, then this withdrawal will
proceed automatically.")
+ let step3 = Text(minimalistic ? "**Step 3:** Transfer
\(amountStr)."
+ : "**Step 3:** Finish the wire transfer of \(amountStr)
in your banking app or website, then this withdrawal will proceed
automatically.")
.multilineTextAlignment(.leading)
.padding(.top)
Group {
@@ -141,15 +142,15 @@ struct ManualDetailsV: View {
restrictions: account.creditRestrictions)
.listRowSeparator(.visible)
step1.listRowSeparator(.hidden)
- if !iconOnly {
+ if !minimalistic {
mandatory
}
cryptocode.listRowSeparator(.hidden)
step2.listRowSeparator(.hidden)
ibanCode.listRowSeparator(.hidden)
step3.listRowSeparator(.visible)
- Text(iconOnly ? "**Alternative:** Use this PayTo-Link:"
- : "**Alternative:** If your bank already
supports PayTo, you can use this PayTo-Link instead:")
+ Text(minimalistic ? "**Alternative:** Use this PayTo-Link:"
+ : "**Alternative:** If your bank already
supports PayTo, you can use this PayTo-Link instead:")
.multilineTextAlignment(.leading)
.padding(.top)
.listRowSeparator(.hidden)
diff --git a/TalerWallet1/Views/Transactions/ThreeAmountsV.swift
b/TalerWallet1/Views/Transactions/ThreeAmountsV.swift
index 7442714..76af34a 100644
--- a/TalerWallet1/Views/Transactions/ThreeAmountsV.swift
+++ b/TalerWallet1/Views/Transactions/ThreeAmountsV.swift
@@ -6,6 +6,7 @@ import SwiftUI
import taler_swift
struct ThreeAmountsSheet: View {
+ let stack: CallStack
var common: TransactionCommon
var topAbbrev: String
var topTitle: String
@@ -14,6 +15,7 @@ struct ThreeAmountsSheet: View {
let baseURL: String?
let large: Bool // set to false for QR or IBAN
let summary: String?
+ let merchant: String?
var body: some View {
let raw = common.amountRaw
@@ -24,24 +26,30 @@ struct ThreeAmountsSheet: View {
let isDone = (common.txState.major == .done)
let incomplete = !(isDone || pending)
- let defaultBottomTitle = incoming ? (pending ? String(localized:
"Pending amount to obtain:")
- : String(localized:
"Obtained amount:") )
- : String(localized: "Paid
amount:")
- let defaultBottomAbbre = incoming ? (pending ? String(localized:
"Pending:")
- : String(localized:
"Obtained:") )
- : String(localized:
"Paid:")
- ThreeAmountsV(topTitle: topTitle, topAbbrev: topAbbrev, topAmount:
raw, fee: fee,
- bottomTitle: bottomTitle ?? defaultBottomTitle,
- bottomAbbrev: bottomAbbrev ?? defaultBottomAbbre,
- bottomAmount: incomplete ? nil : effective,
- large: large, pending: pending, incoming: incoming,
- baseURL: baseURL,
- status: common.txState.major.localizedState,
- summary: summary)
+ let defaultBottomTitle = incoming ? (pending ? String(localized:
"Pending amount to obtain:")
+ : String(localized:
"Obtained amount:") )
+ : (pending ? String(localized:
"Amount to pay:")
+ : String(localized:
"Paid amount:") )
+ let defaultBottomAbbrev = incoming ? (pending ? String(localized:
"Pending:", comment: "mini")
+ : String(localized:
"Obtained:", comment: "mini") )
+ : (pending ? String(localized:
"Pay:", comment: "mini")
+ : String(localized:
"Paid:", comment: "mini") )
+ ThreeAmountsV(stack: stack.push(),
+ topTitle: topTitle, topAbbrev: topAbbrev,
+ topAmount: raw, fee: fee,
+ bottomTitle: bottomTitle ?? defaultBottomTitle,
+ bottomAbbrev: bottomAbbrev ?? defaultBottomAbbrev,
+ bottomAmount: incomplete ? nil : effective,
+ large: large, pending: pending, incoming: incoming,
+ baseURL: baseURL,
+ status: common.txState.major.localizedState,
+ summary: summary,
+ merchant: merchant)
}
}
// MARK: -
struct ThreeAmountsV: View {
+ let stack: CallStack
var topTitle: String
var topAbbrev: String
var topAmount: Amount
@@ -55,9 +63,10 @@ struct ThreeAmountsV: View {
let baseURL: String?
let status: String?
let summary: String?
+ let merchant: String?
+
+ @AppStorage("minimalistic") var minimalistic: Bool = false
- @AppStorage("iconOnly") var iconOnly: Bool = false
-
var body: some View {
let labelColor = Color(UIColor.label)
let foreColor = pending ? WalletColors().pendingColor(incoming)
@@ -65,19 +74,25 @@ struct ThreeAmountsV: View {
Section {
if let summary {
Text(summary)
- .accessibilityFont(.title2)
+ .accessibilityFont(.title3)
+ .lineLimit(4)
+ .padding(.bottom)
+ }
+ if let merchant {
+ Text(merchant)
+ .accessibilityFont(.title3)
.lineLimit(4)
.padding(.bottom)
}
- AmountRowV(title: iconOnly ? topAbbrev : topTitle,
+ AmountRowV(title: minimalistic ? topAbbrev : topTitle,
amount: topAmount,
color: labelColor,
- large: large)
+ large: false)
.padding(.bottom, 4)
.accessibilityElement(children: .combine)
if let fee {
- AmountRowV(title: iconOnly ? String(localized: "Fee:")
- : String(localized: "Exchange
fee:"),
+ AmountRowV(title: minimalistic ? String(localized: "Fee
(short):", defaultValue:"Fee:", comment:"short version")
+ : String(localized: "Fee
(long):", defaultValue:"Fee:", comment:"long version"),
amount: fee,
color: labelColor,
large: false)
@@ -85,7 +100,7 @@ struct ThreeAmountsV: View {
.accessibilityElement(children: .combine)
}
if let bottomAmount {
- AmountRowV(title: iconOnly ? bottomAbbrev : bottomTitle,
+ AmountRowV(title: minimalistic ? bottomAbbrev : bottomTitle,
amount: bottomAmount,
color: foreColor,
large: large)
@@ -93,7 +108,7 @@ struct ThreeAmountsV: View {
}
if let baseURL {
VStack(alignment: .leading) {
- Text(iconOnly ? "Exchange:" : "Using Exchange:")
+ Text(minimalistic ? "Payment provider:" : "Using payment
service provider:")
.multilineTextAlignment(.leading)
.accessibilityFont(.body)
HStack {
@@ -111,7 +126,7 @@ struct ThreeAmountsV: View {
.accessibilityElement(children: .combine)
}
} header: {
- if !iconOnly {
+ if !minimalistic {
Text("Summary")
.accessibilityFont(.title3)
}
@@ -130,9 +145,10 @@ struct ThreeAmounts_Previews: PreviewProvider {
txActions: [])
Group {
List {
- ThreeAmountsSheet(common: common, topAbbrev: "Withdrawal",
- topTitle: "Withdrawal", baseURL: DEMOEXCHANGE,
- large: 1==0, summary: nil)
+ ThreeAmountsSheet(stack: CallStack("Preview"),
+ common: common, topAbbrev: "Withdrawal",
+ topTitle: "Withdrawal", baseURL: DEMOEXCHANGE,
+ large: 1==0, summary: nil, merchant: nil)
.safeAreaInset(edge: .bottom) {
Button(String(localized: "Accept"), action: {})
.buttonStyle(TalerButtonStyle(type: .prominent))
diff --git a/TalerWallet1/Views/Transactions/TransactionDetailV.swift
b/TalerWallet1/Views/Transactions/TransactionDetailV.swift
new file mode 100644
index 0000000..0e4feb0
--- /dev/null
+++ b/TalerWallet1/Views/Transactions/TransactionDetailV.swift
@@ -0,0 +1,52 @@
+//
+// TransactionDetailV.swift
+// TalerWallet
+//
+// Created by Marc Stibane on 2024-01-28.
+// Copyright © 2024 Taler. All rights reserved.
+//
+
+import SwiftUI
+
+struct TransactionDetailV: View {
+ let paymentTx: PaymentTransaction
+
+ var body: some View {
+ let common = paymentTx.common
+ let details = paymentTx.details
+ let info = details.info
+ Section {
+ if let posConfirmation = details.posConfirmation {
+ Text(posConfirmation)
+ }
+// Text(info.summary)
+ Text(info.orderId)
+// Text(info.merchant.name)
+
+ if let fulfillmentUrl = info.fulfillmentUrl {
+ if let destination = URL(string: fulfillmentUrl) {
+ let buttonTitle = info.fulfillmentMessage ?? "Open
merchant website"
+ Link(buttonTitle, destination: destination)
+ .buttonStyle(TalerButtonStyle(type: .bordered))
+ .accessibilityHint("Will go to the merchant website.")
+ }
+ } else if let fulfillmentMessage = info.fulfillmentMessage {
+ Text(fulfillmentMessage)
+ }
+ if let products = info.products {
+ ForEach(products) {product in
+ Section {
+ if let product_id = product.product_id {
+ Text(product_id)
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// MARK: -
+//#Preview {
+// TransactionDetailV()
+//}
diff --git a/TalerWallet1/Views/Transactions/TransactionRowView.swift
b/TalerWallet1/Views/Transactions/TransactionRowView.swift
index 1b80bc2..d3b6f65 100644
--- a/TalerWallet1/Views/Transactions/TransactionRowView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionRowView.swift
@@ -38,7 +38,6 @@ struct IconBadge: View {
struct TransactionRowView: View {
let transaction : Transaction
- let currency: String
@Environment(\.sizeCategory) var sizeCategory
@Environment(\.colorSchemeContrast) private var colorSchemeContrast
@@ -47,6 +46,16 @@ struct TransactionRowView: View {
available < (contentWidth + valueWidth + 40)
}
+ func topString() -> String {
+ switch transaction {
+ case .payment(let paymentTransaction):
+ return paymentTransaction.details.info.merchant.name
+ default:
+ return transaction.isDone ? transaction.localizedTypePast
+ : transaction.localizedType
+ }
+ }
+
var body: some View {
let common = transaction.common
let pending = transaction.isPending
@@ -71,7 +80,7 @@ struct TransactionRowView: View {
let amountV = AmountV(common.amountEffective)
.foregroundColor(foreColor)
- let topString = transaction.localizedType
+ let topString = topString()
let centerTop = Text(topString)
.foregroundColor(textColor)
.strikethrough(!doneOrPending, color: .red)
@@ -162,8 +171,8 @@ struct TransactionRow_Previews: PreviewProvider {
time: Timestamp(from:
1_666_666_000_000))
static var previews: some View {
List {
- TransactionRowView(transaction: withdrawal, currency: TESTCURRENCY)
- TransactionRowView(transaction: payment, currency: DEMOCURRENCY)
+ TransactionRowView(transaction: withdrawal)
+ TransactionRowView(transaction: payment)
}
}
}
@@ -199,7 +208,9 @@ extension Transaction { // for PreViews
let pDetails = PaymentTransactionDetails(info: info,
proposalId: "some proposal ID",
totalRefundRaw: Amount(currency:
LONGCURRENCY, cent: 300),
- totalRefundEffective: Amount(currency:
LONGCURRENCY, cent: 280))
+ totalRefundEffective: Amount(currency:
LONGCURRENCY, cent: 280),
+ refunds: [],
+ refundQueryActive: false)
self = .payment(PaymentTransaction(common: common, details:
pDetails))
}
}
diff --git a/TalerWallet1/Views/Transactions/TransactionDetailView.swift
b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
similarity index 79%
rename from TalerWallet1/Views/Transactions/TransactionDetailView.swift
rename to TalerWallet1/Views/Transactions/TransactionSummaryV.swift
index 162cfb7..3b77b5d 100644
--- a/TalerWallet1/Views/Transactions/TransactionDetailView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
@@ -21,7 +21,7 @@ extension Transaction { // for Dummys
}
}
// MARK: -
-struct TransactionDetailView: View {
+struct TransactionSummaryV: View {
private let symLog = SymLogV(0)
let stack: CallStack
let transactionId: String
@@ -99,7 +99,8 @@ struct TransactionDetailView: View {
let locale = TalerDater.shared.locale
let (dateString, date) = TalerDater.dateString(from: common.timestamp)
let accessibilityDate = TalerDater.accessibilityDate(date) ??
dateString
- let navTitle2 = transaction.localizedType
+ let navTitle2 = transaction.isDone ? transaction.localizedTypePast
+ : transaction.localizedType
VStack {
List {
if developerMode {
@@ -119,9 +120,13 @@ struct TransactionDetailView: View {
.listRowSeparator(.hidden)
VStack(alignment: .trailing) {
let majorState = common.txState.major.localizedState
+#if DEBUG
let minorState = common.txState.minor?.localizedState ??
nil
let state = transaction.isPending ? minorState ??
majorState
: majorState
+#else
+ let state = majorState
+#endif
HStack {
Text(verbatim: "|") // only reason for this
leading-aligned text is to get a nice full length listRowSeparator
.accessibilityHidden(true)
@@ -132,8 +137,10 @@ struct TransactionDetailView: View {
}
} .listRowSeparator(.automatic)
.accessibilityFont(.title)
- TypeDetail(transaction: $transaction, hasDone: doneAction !=
nil)
+ TypeDetail(stack: stack.push(),
+ transaction: $transaction, hasDone: doneAction !=
nil)
+ // TODO: Retry Countdown, Retry Now button
// if transaction.isRetryable { if let retryAction {
// TransactionButton(transactionId: common.transactionId,
command: .retry,
// warning: nil, action: abortAction)
@@ -185,7 +192,7 @@ struct TransactionDetailView: View {
}
.onAppear {
symLog.log("onAppear")
- DebugViewC.shared.setViewID(VIEW_TRANSACTIONDETAIL, stack:
stack.push())
+ DebugViewC.shared.setViewID(VIEW_TRANSACTIONSUMMARY, stack:
stack.push())
}
.onDisappear {
symLog.log("onDisappear")
@@ -193,14 +200,14 @@ struct TransactionDetailView: View {
}
//}
//
-//extension TransactionDetail {
+//extension TransactionSummaryV {
struct KycButton: View {
let destination: URL
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
var body: some View {
VStack(alignment: .leading) { // Show Hint that User must pass
KYC on website
- if !iconOnly {
+ if !minimalistic {
Text("You need to pass a KYC procedure")
.fixedSize(horizontal: false, vertical: true) //
wrap in scrollview
.multilineTextAlignment(.leading) //
otherwise
@@ -215,11 +222,11 @@ struct TransactionDetailView: View {
struct ConfirmationButton: View {
let destination: URL
- @AppStorage("iconOnly") var iconOnly: Bool = false
+ @AppStorage("minimalistic") var minimalistic: Bool = false
var body: some View {
VStack(alignment: .leading) { // Show Hint that User should
Confirm on bank website
- if !iconOnly {
+ if !minimalistic {
Text("The bank is waiting for your confirmation.")
// .fixedSize(horizontal: false, vertical: true)
// wrap in scrollview
.multilineTextAlignment(.leading) //
otherwise
@@ -233,8 +240,10 @@ struct TransactionDetailView: View {
}
struct TypeDetail: View {
+ let stack: CallStack
@Binding var transaction: Transaction
let hasDone: Bool
+ @State private var rotationEnabled = true
var body: some View {
let common = transaction.common
@@ -245,6 +254,11 @@ struct TransactionDetailView: View {
let title = EMPTYSTRING
Text(title)
.accessibilityFont(.body)
+ HStack {
+ Spacer()
+ RotatingTaler(size: 100, rotationEnabled:
$rotationEnabled)
+ Spacer()
+ }
case .withdrawal(let withdrawalTransaction): Group {
let details = withdrawalTransaction.details
if pending {
@@ -270,47 +284,60 @@ struct TransactionDetailView: View {
} } } }
} // switch
} // ManualDetails or Confirm now (with bank)
- ThreeAmountsSheet(common: common, topAbbrev:
String(localized: "Chosen:"),
+ ThreeAmountsSheet(stack: stack.push(),
+ common: common, topAbbrev:
String(localized: "Chosen:", comment: "mini"),
topTitle: String(localized: "Chosen
amount to withdraw:"),
- baseURL: details.exchangeBaseUrl,
large: false, summary: nil)
+ baseURL: details.exchangeBaseUrl,
large: false,
+ summary: nil, merchant: nil)
+ }
+ case .deposit(let depositTransaction): Group {
+ let details = depositTransaction.details
+ ThreeAmountsSheet(stack: stack.push(),
+ common: common, topAbbrev:
String(localized: "Deposit:", comment: "mini"),
+ topTitle: String(localized: "Amount
to deposit:"),
+ baseURL: nil, large: true,
// TODO: baseURL
+ summary: nil, merchant: nil)
}
case .payment(let paymentTransaction): Group {
let details = paymentTransaction.details
- Text(details.info.summary)
- .accessibilityFont(.title3)
- ThreeAmountsSheet(common: common, topAbbrev:
String(localized: "Pay:"),
- topTitle: String(localized: "Sum to be
paid:"),
- baseURL: nil, large: true, summary:
details.info.summary) // TODO: baseURL
+ TransactionDetailV(paymentTx: paymentTransaction)
+ ThreeAmountsSheet(stack: stack.push(),
+ common: common, topAbbrev:
String(localized: "Price:", comment: "mini"),
+ topTitle: String(localized: "Price
(net):"),
+ baseURL: nil, large: true,
// TODO: baseURL
+ summary: details.info.summary,
+ merchant: details.info.merchant.name)
}
case .refund(let refundTransaction): Group {
let details = refundTransaction.details
// TODO: more details
- ThreeAmountsSheet(common: common, topAbbrev:
String(localized: "Refunded:"),
+ ThreeAmountsSheet(stack: stack.push(),
+ common: common, topAbbrev:
String(localized: "Refunded:", comment: "mini"),
topTitle: String(localized: "Refunded
amount:"),
- baseURL: nil, large: true, summary:
nil) // TODO: baseURL, summary
- }
- case .reward(let rewardTransaction): Group {
- let details = rewardTransaction.details
- ThreeAmountsSheet(common: common, topAbbrev:
String(localized: "Reward:"),
- topTitle: String(localized: "Received
Reward:"),
- baseURL: details.exchangeBaseUrl,
large: true, summary: nil) // TODO: summary
+ baseURL: nil, large: true,
// TODO: baseURL
+ summary: details.info?.summary,
+ merchant: details.info?.merchant.name)
}
case .refresh(let refreshTransaction): Group {
let details = refreshTransaction.details
// TODO: details
Text(details.refreshReason.rawValue)
- ThreeAmountsSheet(common: common, topAbbrev:
String(localized: "Refreshed:"),
+ ThreeAmountsSheet(stack: stack.push(),
+ common: common, topAbbrev:
String(localized: "Refreshed:", comment: "mini"),
topTitle: String(localized: "Refreshed
amount:"),
- baseURL: nil, large: true, summary:
nil) // TODO: baseURL
+ baseURL: nil, large: true,
// TODO: baseURL
+ summary: nil, merchant: nil)
}
case .peer2peer(let p2pTransaction): Group {
let details = p2pTransaction.details
- let expiration = details.info.expiration
- let (dateString, date) = TalerDater.dateString(from:
expiration)
- let accessibilityDate =
TalerDater.accessibilityDate(date) ?? dateString
- let accessibilityLabel = String(localized: "Expires:
\(accessibilityDate)")
- Text("Expires: \(dateString)")
- .accessibilityFont(.body)
- .accessibilityLabel(accessibilityLabel)
-// .foregroundColor(colorSchemeContrast == .increased ?
.primary : .secondary)
+ if !transaction.isDone {
+ let expiration = details.info.expiration
+ let (dateString, date) =
TalerDater.dateString(from: expiration)
+ let accessibilityDate =
TalerDater.accessibilityDate(date) ?? dateString
+ let accessibilityLabel = String(localized:
"Expires: \(accessibilityDate)")
+ Text("Expires: \(dateString)")
+ .accessibilityFont(.body)
+ .accessibilityLabel(accessibilityLabel)
+ //
.foregroundColor(colorSchemeContrast == .increased ? .primary : .secondary)
+ }
// TODO: isSendCoins should show QR only while not yet
expired - either set timer or wallet-core should do so and send a
state-changed notification
if pending {
if transaction.isPendingReady {
@@ -328,10 +355,15 @@ struct TransactionDetailView: View {
}
}
let colon = ":"
- ThreeAmountsSheet(common: common, topAbbrev:
transaction.localizedType + colon,
- topTitle: transaction.localizedType +
colon,
+ let localizedType = transaction.isDone ?
transaction.localizedTypePast
+ :
transaction.localizedType
+ ThreeAmountsSheet(stack: stack.push(),
+ common: common,
+ topAbbrev: localizedType + colon,
+ topTitle: localizedType + colon,
baseURL: details.exchangeBaseUrl,
large: false,
- summary: details.info.summary)
+ summary: details.info.summary,
+ merchant: nil)
} // p2p
} // switch
} // Group
@@ -360,21 +392,10 @@ struct TransactionDetailView: View {
}
}
}
- struct DoneButton: View {
- var doneAction: () -> Void
-
- var body: some View {
- Button("Done") {
- doneAction()
- }
- .buttonStyle(TalerButtonStyle(type: .prominent))
- .padding(.horizontal)
- }
- }
}
// MARK: -
#if DEBUG
-//struct TransactionDetail_Previews: PreviewProvider {
+//struct TransactionSummary_Previews: PreviewProvider {
// static func deleteTransactionDummy(transactionId: String) async throws {}
// static func doneActionDummy() {}
// static var withdrawal = Transaction(incoming: true,
@@ -388,8 +409,8 @@ struct TransactionDetailView: View {
// static func reloadActionDummy(transactionId: String) async ->
Transaction { return withdrawal }
// static var previews: some View {
// Group {
-// TransactionDetailView(transaction: withdrawal, reloadAction:
reloadActionDummy, doneAction: doneActionDummy)
-// TransactionDetailView(transaction: payment, reloadAction:
reloadActionDummy, deleteAction: deleteTransactionDummy)
+// TransactionSummaryV(transaction: withdrawal, reloadAction:
reloadActionDummy, doneAction: doneActionDummy)
+// TransactionSummaryV(transaction: payment, reloadAction:
reloadActionDummy, deleteAction: deleteTransactionDummy)
// }
// }
//}
diff --git a/TalerWallet1/Views/Transactions/TransactionsEmptyView.swift
b/TalerWallet1/Views/Transactions/TransactionsEmptyView.swift
index 1e44551..94e66cb 100644
--- a/TalerWallet1/Views/Transactions/TransactionsEmptyView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionsEmptyView.swift
@@ -11,10 +11,10 @@ import SymLog
struct TransactionsEmptyView: View {
private let symLog = SymLogV(0)
let stack: CallStack
- @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
-
let currency: String
+ @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
+
var body: some View {
List {
Section {
diff --git a/TalerWallet1/Views/Transactions/TransactionsListView.swift
b/TalerWallet1/Views/Transactions/TransactionsListView.swift
index 7614fe5..9944327 100644
--- a/TalerWallet1/Views/Transactions/TransactionsListView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionsListView.swift
@@ -11,7 +11,7 @@ struct TransactionsListView: View {
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
let navTitle: String
- let currency: String
+ let scopeInfo: ScopeInfo
let transactions: [Transaction]
let showUpDown: Bool
let reloadAllAction: (_ stack: CallStack) async -> ()
@@ -30,9 +30,10 @@ struct TransactionsListView: View {
List {
TransactionsArraySliceV(symLog: symLog,
stack: stack.push(),
- currency: currency,
+ scopeInfo: scopeInfo,
transactions: transactions,
reloadOneAction: reloadOneAction)
+ .padding(.leading, ICONLEADING)
}
.id(viewId)
.listStyle(myListStyle.style).anyView
@@ -68,7 +69,7 @@ struct TransactionsListView: View {
}
.overlay {
if transactions.isEmpty {
- TransactionsEmptyView(stack: stack.push(), currency: currency)
+ TransactionsEmptyView(stack: stack.push(), currency:
scopeInfo.currency)
}
}
.onAppear {
@@ -81,7 +82,7 @@ struct TransactionsListView: View {
struct TransactionsArraySliceV: View {
let symLog: SymLogV?
let stack: CallStack
- let currency: String
+ let scopeInfo: ScopeInfo
let transactions: [Transaction]
let reloadOneAction: ((_ transactionId: String) async throws ->
Transaction)
@@ -99,7 +100,7 @@ struct TransactionsArraySliceV: View {
ForEach(Array(zip(transactions.indices, transactions)), id: \.1) {
index, transaction in
NavigationLink {
LazyView {
- TransactionDetailView(stack: stack.push(),
+ TransactionSummaryV(stack: stack.push(),
transactionId: transaction.id,
reloadAction: reloadOneAction,
navTitle: nil,
@@ -111,8 +112,7 @@ struct TransactionsArraySliceV: View {
resumeAction: resumeAction)
}
} label: {
- TransactionRowView(transaction: transaction,
- currency: currency)
+ TransactionRowView(transaction: transaction)
}
.id(Int(index))
}
diff --git a/TestFlight/WhatToTest.en-US.txt b/TestFlight/WhatToTest.en-US.txt
index 1b2e711..57c0567 100644
--- a/TestFlight/WhatToTest.en-US.txt
+++ b/TestFlight/WhatToTest.en-US.txt
@@ -1,3 +1,19 @@
+Version 0.9.4 (3)
+
+- Payment shows the fulfillment link
+- P2P directly dismisses the sheet on success
+- the git version hash now only shows the first 7 letters
+
+
+Version 0.9.4 (2)
+
+• New feature: curl with c-ares improves networking
+- bug fix: currency names default to the long version if a currency symbol is
not available
+- bug fix: version info in About dialog is now also showing the build number
(in parentheses)
+
+A/B Test: Taler Wallet uses c-ares, GNU Taler doesn't. You can install both
apps to test this feature, but then you cannot use bank-integrated withdrawals
for both apps with Safari running the bank website on the same iPhone anymore
since iOS doesn't let you choose which wallet app to withdraw to. Instead you
can open the bank website https://bank.demo.taler.net on your computer or
tablet, start the withdrawal there, and scan the QR code with the app (Taler
Wallet or GNU Taler) you want [...]
+
+
Version 0.9.4 (1)
- now accepts uppercase TALER://PAY URIs
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-ios] branch master updated (4167b6d -> 4e7f6ff),
gnunet <=
- [taler-taler-ios] 05/32: Bump version to 0.9.4 (2), gnunet, 2024/02/10
- [taler-taler-ios] 09/32: Deposit, gnunet, 2024/02/10
- [taler-taler-ios] 01/32: remove Mac support, gnunet, 2024/02/10
- [taler-taler-ios] 08/32: Past Tense, gnunet, 2024/02/10
- [taler-taler-ios] 03/32: Settings, About, gnunet, 2024/02/10
- [taler-taler-ios] 07/32: PaymentDone, gnunet, 2024/02/10
- [taler-taler-ios] 02/32: TransactionSummaryV, gnunet, 2024/02/10
- [taler-taler-ios] 16/32: wording, gnunet, 2024/02/10
- [taler-taler-ios] 06/32: Cleanup, logging, gnunet, 2024/02/10
- [taler-taler-ios] 20/32: wording, gnunet, 2024/02/10