[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-ios] 14/54: Made Model a Singleton
From: |
gnunet |
Subject: |
[taler-taler-ios] 14/54: Made Model a Singleton |
Date: |
Fri, 30 Jun 2023 22:33:46 +0200 |
This is an automated email from the git hooks/post-receive script.
marc-stibane pushed a commit to branch master
in repository taler-ios.
commit 6d1028c0b4fceeafd3a890850ed4ebc20dde19cf
Author: Marc Stibane <marc@taler.net>
AuthorDate: Wed Jun 21 09:29:57 2023 +0200
Made Model a Singleton
---
TalerWallet.xcodeproj/project.pbxproj | 104 ++++++++++--------
TalerWallet1/Backend/Transaction.swift | 21 ++--
TalerWallet1/Backend/WalletCore.swift | 17 ++-
TalerWallet1/Controllers/Controller.swift | 15 ++-
TalerWallet1/Controllers/DebugViewC.swift | 2 +
TalerWallet1/Controllers/TalerWallet1App.swift | 4 +-
.../Helper/{URL+iban.swift => URL+id+iban.swift} | 0
...ew+dismissTop.swift => View+Notification.swift} | 34 +-----
TalerWallet1/Helper/View+dismissTop.swift | 57 ----------
.../{BalancesModel.swift => Model+Balances.swift} | 75 +++++--------
.../{ExchangeModel.swift => Model+Exchange.swift} | 29 ++---
.../{Peer2peerModel.swift => Model+P2P.swift} | 90 +++++++++++-----
.../{PaymentURIModel.swift => Model+Payment.swift} | 28 +----
.../{PendingModel.swift => Model+Pending.swift} | 25 +----
.../{SettingsModel.swift => Model+Settings.swift} | 8 +-
...actionsModel.swift => Model+Transactions.swift} | 27 +----
.../{WithdrawModel.swift => Model+Withdraw.swift} | 27 +----
TalerWallet1/Model/WalletInitModel.swift | 72 -------------
TalerWallet1/Model/WalletModel.swift | 73 ++++++++++++-
TalerWallet1/Views/Balances/BalancesListView.swift | 20 ++--
.../Views/Balances/BalancesSectionView.swift | 119 +++++++++++----------
TalerWallet1/Views/Exchange/ExchangeListView.swift | 24 ++---
.../Views/Exchange/ExchangeSectionView.swift | 2 -
TalerWallet1/Views/Exchange/ManualWithdraw.swift | 13 +--
.../Views/Exchange/ManualWithdrawDone.swift | 22 ++--
.../Views/HelperViews/QRCodeDetailView.swift | 20 ++--
TalerWallet1/Views/Main/MainView.swift | 2 -
TalerWallet1/Views/Payment/PaymentURIView.swift | 30 +++---
.../{ReceivePurpose.swift => PaymentPurpose.swift} | 70 +++++-------
TalerWallet1/Views/Peer2peer/RequestPayment.swift | 33 +++---
TalerWallet1/Views/Peer2peer/SendAmount.swift | 41 ++++---
TalerWallet1/Views/Peer2peer/SendNow.swift | 61 ++++++-----
TalerWallet1/Views/Peer2peer/SendPurpose.swift | 47 ++++----
.../Settings/Pending/PendingOpsListView.swift | 6 +-
TalerWallet1/Views/Settings/SettingsView.swift | 7 +-
.../P2P_Sheets/P2pAcceptDone.swift} | 24 ++---
.../Sheets/P2P_Sheets/P2pReceiveURIView.swift | 80 ++++++++++++++
TalerWallet1/Views/Sheets/URLSheet.swift | 18 +++-
TalerWallet1/Views/Transactions/ThreeAmounts.swift | 3 +-
.../Views/Transactions/TransactionDetailView.swift | 5 +-
.../WithdrawAcceptDone.swift | 12 +--
.../WithdrawBankIntegrated/WithdrawTOSView.swift | 19 ++--
.../WithdrawBankIntegrated/WithdrawURIView.swift | 5 +-
43 files changed, 635 insertions(+), 756 deletions(-)
diff --git a/TalerWallet.xcodeproj/project.pbxproj
b/TalerWallet.xcodeproj/project.pbxproj
index 4d3cbfe..1000193 100644
--- a/TalerWallet.xcodeproj/project.pbxproj
+++ b/TalerWallet.xcodeproj/project.pbxproj
@@ -8,10 +8,15 @@
/* Begin PBXBuildFile section */
4E16E12329F3BB99008B9C86 /* CurrencyFormatter.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4E16E12229F3BB99008B9C86 /*
CurrencyFormatter.swift */; };
- 4E363CBC2A237E0900D7E98C /* URL+iban.swift in Sources */ = {isa
= PBXBuildFile; fileRef = 4E363CBB2A237E0900D7E98C /* URL+iban.swift */; };
+ 4E363CBC2A237E0900D7E98C /* URL+id+iban.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E363CBB2A237E0900D7E98C /* URL+id+iban.swift
*/; };
4E363CBE2A23CB2100D7E98C /* AnyTransition+backslide.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4E363CBD2A23CB2100D7E98C /*
AnyTransition+backslide.swift */; };
4E363CC02A24754200D7E98C /* Settings.bundle in Resources */ =
{isa = PBXBuildFile; fileRef = 4E363CBF2A24754200D7E98C /* Settings.bundle */;
};
4E363CC22A2621C200D7E98C /* LocalizedAlertError.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4E363CC12A2621C200D7E98C /*
LocalizedAlertError.swift */; };
+ 4E3B4BC12A41E6C200CC88B8 /* P2pReceiveURIView.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4E3B4BC02A41E6C200CC88B8 /*
P2pReceiveURIView.swift */; };
+ 4E3B4BC32A42252300CC88B8 /* P2pAcceptDone.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E3B4BC22A42252300CC88B8 /* P2pAcceptDone.swift
*/; };
+ 4E3B4BC52A428AF700CC88B8 /* Model+Balances.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4E3B4BC42A428AF700CC88B8 /*
Model+Balances.swift */; };
+ 4E3B4BC72A429F2A00CC88B8 /* View+Notification.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4E3B4BC62A429F2A00CC88B8 /*
View+Notification.swift */; };
+ 4E3B4BC92A42BC4800CC88B8 /* Model+Exchange.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4E3B4BC82A42BC4800CC88B8 /*
Model+Exchange.swift */; };
4E40E0BE29F25ABB00B85369 /* SendAmount.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E40E0BD29F25ABB00B85369 /* SendAmount.swift */;
};
4E50B3502A1BEE8000F9F01C /* ManualWithdraw.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4E50B34F2A1BEE8000F9F01C /*
ManualWithdraw.swift */; };
4E53A33729F50B7B00830EC2 /* CurrencyField.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E53A33629F50B7B00830EC2 /* CurrencyField.swift
*/; };
@@ -27,7 +32,7 @@
4E8E25332A1CD39700A27BFA /* EqualIconWidthDomain.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4E8E25322A1CD39700A27BFA /*
EqualIconWidthDomain.swift */; };
4E9320432A14F6EA00A87B0E /* WalletColors.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E9320422A14F6EA00A87B0E /* WalletColors.swift
*/; };
4E9320452A1645B600A87B0E /* RequestPayment.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4E9320442A1645B600A87B0E /*
RequestPayment.swift */; };
- 4E9320472A164BC700A87B0E /* ReceivePurpose.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4E9320462A164BC700A87B0E /*
ReceivePurpose.swift */; };
+ 4E9320472A164BC700A87B0E /* PaymentPurpose.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4E9320462A164BC700A87B0E /*
PaymentPurpose.swift */; };
4E9796902A3765ED006F73BC /* AgePicker.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4E97968F2A3765ED006F73BC /* AgePicker.swift */;
};
4EA1ABBE29A3833A008821EA /* PublicConstants.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EA1ABBD29A3833A008821EA /*
PublicConstants.swift */; };
4EA551252A2C923600FEC9A8 /* CurrencyInputView.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EA551242A2C923600FEC9A8 /*
CurrencyInputView.swift */; };
@@ -47,33 +52,30 @@
4EB0950A2989CB7C0043A8A1 /* TalerStrings.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095072989CB7C0043A8A1 /* TalerStrings.swift
*/; };
4EB0950B2989CB7C0043A8A1 /* View+dismissTop.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095082989CB7C0043A8A1 /*
View+dismissTop.swift */; };
4EB0950E2989CB9A0043A8A1 /* quickjs.swift in Sources */ = {isa
= PBXBuildFile; fileRef = 4EB0950D2989CB9A0043A8A1 /* quickjs.swift */; };
- 4EB095152989CBB00043A8A1 /* SettingsModel.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095102989CBB00043A8A1 /* SettingsModel.swift
*/; };
+ 4EB095152989CBB00043A8A1 /* Model+Settings.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095102989CBB00043A8A1 /*
Model+Settings.swift */; };
4EB095162989CBB00043A8A1 /* WalletModel.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095112989CBB00043A8A1 /* WalletModel.swift
*/; };
- 4EB095192989CBB00043A8A1 /* WalletInitModel.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095142989CBB00043A8A1 /*
WalletInitModel.swift */; };
4EB0951F2989CBCB0043A8A1 /* WalletBackendRequest.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EB0951B2989CBCB0043A8A1 /*
WalletBackendRequest.swift */; };
4EB095202989CBCB0043A8A1 /* WalletCore.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0951C2989CBCB0043A8A1 /* WalletCore.swift */;
};
4EB095212989CBCB0043A8A1 /* WalletBackendError.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB0951D2989CBCB0043A8A1 /*
WalletBackendError.swift */; };
4EB095222989CBCB0043A8A1 /* Transaction.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0951E2989CBCB0043A8A1 /* Transaction.swift
*/; };
4EB0954F2989CBFE0043A8A1 /* SettingsView.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095252989CBFE0043A8A1 /* SettingsView.swift
*/; };
4EB095502989CBFE0043A8A1 /* SettingsItem.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095262989CBFE0043A8A1 /* SettingsItem.swift
*/; };
- 4EB095512989CBFE0043A8A1 /* ExchangeModel.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095282989CBFE0043A8A1 /* ExchangeModel.swift
*/; };
4EB095522989CBFE0043A8A1 /* ExchangeListView.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB095292989CBFE0043A8A1 /*
ExchangeListView.swift */; };
4EB095532989CBFE0043A8A1 /* PaymentAcceptView.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB0952B2989CBFE0043A8A1 /*
PaymentAcceptView.swift */; };
- 4EB095542989CBFE0043A8A1 /* PaymentURIModel.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB0952C2989CBFE0043A8A1 /*
PaymentURIModel.swift */; };
+ 4EB095542989CBFE0043A8A1 /* Model+Payment.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0952C2989CBFE0043A8A1 /* Model+Payment.swift
*/; };
4EB095552989CBFE0043A8A1 /* PaymentURIView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB0952D2989CBFE0043A8A1 /*
PaymentURIView.swift */; };
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 */; };
- 4EB095592989CBFE0043A8A1 /* TransactionsModel.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB095322989CBFE0043A8A1 /*
TransactionsModel.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 */; };
- 4EB0955B2989CBFE0043A8A1 /* BalancesModel.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095352989CBFE0043A8A1 /* BalancesModel.swift
*/; };
4EB0955C2989CBFE0043A8A1 /* BalanceRowView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095362989CBFE0043A8A1 /*
BalanceRowView.swift */; };
4EB0955D2989CBFE0043A8A1 /* BalancesListView.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB095372989CBFE0043A8A1 /*
BalancesListView.swift */; };
4EB0955E2989CBFE0043A8A1 /* PendingRowView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095382989CBFE0043A8A1 /*
PendingRowView.swift */; };
4EB0955F2989CBFE0043A8A1 /* WalletEmptyView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095392989CBFE0043A8A1 /*
WalletEmptyView.swift */; };
4EB095602989CBFE0043A8A1 /* BalancesSectionView.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EB0953A2989CBFE0043A8A1 /*
BalancesSectionView.swift */; };
4EB095612989CBFE0043A8A1 /* WithdrawURIView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB0953C2989CBFE0043A8A1 /*
WithdrawURIView.swift */; };
- 4EB095622989CBFE0043A8A1 /* WithdrawModel.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0953D2989CBFE0043A8A1 /* WithdrawModel.swift
*/; };
+ 4EB095622989CBFE0043A8A1 /* Model+Withdraw.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB0953D2989CBFE0043A8A1 /*
Model+Withdraw.swift */; };
4EB095642989CBFE0043A8A1 /* WithdrawProgressView.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EB0953F2989CBFE0043A8A1 /*
WithdrawProgressView.swift */; };
4EB095652989CBFE0043A8A1 /* WithdrawTOSView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095402989CBFE0043A8A1 /*
WithdrawTOSView.swift */; };
4EB095662989CBFE0043A8A1 /* SideBarView.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095422989CBFE0043A8A1 /* SideBarView.swift
*/; };
@@ -84,7 +86,7 @@
4EB0956B2989CBFE0043A8A1 /* TextFieldAlert.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EB095482989CBFE0043A8A1 /*
TextFieldAlert.swift */; };
4EB0956C2989CBFE0043A8A1 /* AmountView.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB095492989CBFE0043A8A1 /* AmountView.swift */;
};
4EB0956D2989CBFE0043A8A1 /* LoadingView.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0954A2989CBFE0043A8A1 /* LoadingView.swift
*/; };
- 4EB0956E2989CBFE0043A8A1 /* PendingModel.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0954C2989CBFE0043A8A1 /* PendingModel.swift
*/; };
+ 4EB0956E2989CBFE0043A8A1 /* Model+Pending.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0954C2989CBFE0043A8A1 /* Model+Pending.swift
*/; };
4EB0956F2989CBFE0043A8A1 /* PendingOpView.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EB0954D2989CBFE0043A8A1 /* PendingOpView.swift
*/; };
4EB095702989CBFE0043A8A1 /* PendingOpsListView.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EB0954E2989CBFE0043A8A1 /*
PendingOpsListView.swift */; };
4EB3136129FEE79B007D68BC /* SendNow.swift in Sources */ = {isa
= PBXBuildFile; fileRef = 4EB3136029FEE79B007D68BC /* SendNow.swift */; };
@@ -92,7 +94,7 @@
4EBA82AB2A3EB2CA00E5F39A /* TransactionButton.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EBA82AA2A3EB2CA00E5F39A /*
TransactionButton.swift */; };
4EBA82AD2A3F580500E5F39A /* QuiteSomeCoins.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EBA82AC2A3F580500E5F39A /*
QuiteSomeCoins.swift */; };
4EC90C782A1B528B0071DC58 /* ExchangeSectionView.swift in
Sources */ = {isa = PBXBuildFile; fileRef = 4EC90C772A1B528B0071DC58 /*
ExchangeSectionView.swift */; };
- 4ECB62802A0BA6DF004ABBB7 /* Peer2peerModel.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4ECB627F2A0BA6DF004ABBB7 /*
Peer2peerModel.swift */; };
+ 4ECB62802A0BA6DF004ABBB7 /* Model+P2P.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4ECB627F2A0BA6DF004ABBB7 /* Model+P2P.swift */;
};
4ECB62822A0BB01D004ABBB7 /* SelectDays.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4ECB62812A0BB01D004ABBB7 /* SelectDays.swift */;
};
4ED2F94B2A278F5100453B40 /* ThreeAmounts.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4ED2F94A2A278F5100453B40 /* ThreeAmounts.swift
*/; };
4EEC157329F8242800D46A03 /* QRGeneratorView.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EEC157229F8242800D46A03 /*
QRGeneratorView.swift */; };
@@ -135,11 +137,16 @@
/* Begin PBXFileReference section */
4E16E12229F3BB99008B9C86 /* CurrencyFormatter.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= CurrencyFormatter.swift; sourceTree = "<group>"; };
- 4E363CBB2A237E0900D7E98C /* URL+iban.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "URL+iban.swift"; sourceTree = "<group>"; };
+ 4E363CBB2A237E0900D7E98C /* URL+id+iban.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "URL+id+iban.swift"; sourceTree = "<group>"; };
4E363CBD2A23CB2100D7E98C /* AnyTransition+backslide.swift */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.swift; path = "AnyTransition+backslide.swift"; sourceTree =
"<group>"; };
4E363CBF2A24754200D7E98C /* Settings.bundle */ = {isa =
PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path =
Settings.bundle; sourceTree = "<group>"; };
4E363CC12A2621C200D7E98C /* LocalizedAlertError.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = LocalizedAlertError.swift; sourceTree = "<group>"; };
4E3AE7EF29A7E8F40070BEC4 /* Taler Wallet.entitlements */ = {isa
= PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "Taler
Wallet.entitlements"; sourceTree = "<group>"; };
+ 4E3B4BC02A41E6C200CC88B8 /* P2pReceiveURIView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= P2pReceiveURIView.swift; sourceTree = "<group>"; };
+ 4E3B4BC22A42252300CC88B8 /* P2pAcceptDone.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= P2pAcceptDone.swift; sourceTree = "<group>"; };
+ 4E3B4BC42A428AF700CC88B8 /* Model+Balances.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "Model+Balances.swift"; sourceTree = "<group>"; };
+ 4E3B4BC62A429F2A00CC88B8 /* View+Notification.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "View+Notification.swift"; sourceTree = "<group>"; };
+ 4E3B4BC82A42BC4800CC88B8 /* Model+Exchange.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "Model+Exchange.swift"; sourceTree = "<group>"; };
4E40E0BD29F25ABB00B85369 /* SendAmount.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name
= SendAmount.swift; path = TalerWallet1/Views/Peer2peer/SendAmount.swift;
sourceTree = SOURCE_ROOT; };
4E50B34F2A1BEE8000F9F01C /* ManualWithdraw.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= ManualWithdraw.swift; sourceTree = "<group>"; };
4E53A33629F50B7B00830EC2 /* CurrencyField.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= CurrencyField.swift; sourceTree = "<group>"; };
@@ -156,7 +163,7 @@
4E8E25322A1CD39700A27BFA /* EqualIconWidthDomain.swift */ =
{isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path =
EqualIconWidthDomain.swift; sourceTree = "<group>"; };
4E9320422A14F6EA00A87B0E /* WalletColors.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WalletColors.swift; sourceTree = "<group>"; };
4E9320442A1645B600A87B0E /* RequestPayment.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= RequestPayment.swift; sourceTree = "<group>"; };
- 4E9320462A164BC700A87B0E /* ReceivePurpose.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= ReceivePurpose.swift; sourceTree = "<group>"; };
+ 4E9320462A164BC700A87B0E /* PaymentPurpose.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= PaymentPurpose.swift; sourceTree = "<group>"; };
4E97968F2A3765ED006F73BC /* AgePicker.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= AgePicker.swift; sourceTree = "<group>"; };
4EA1ABBD29A3833A008821EA /* PublicConstants.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path =
PublicConstants.swift; sourceTree = "<group>"; };
4EA551242A2C923600FEC9A8 /* CurrencyInputView.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path =
CurrencyInputView.swift; sourceTree = "<group>"; };
@@ -176,33 +183,30 @@
4EB095072989CB7C0043A8A1 /* TalerStrings.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= TalerStrings.swift; sourceTree = "<group>"; };
4EB095082989CB7C0043A8A1 /* View+dismissTop.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "View+dismissTop.swift"; sourceTree = "<group>"; };
4EB0950D2989CB9A0043A8A1 /* quickjs.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= quickjs.swift; sourceTree = "<group>"; };
- 4EB095102989CBB00043A8A1 /* SettingsModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= SettingsModel.swift; sourceTree = "<group>"; };
+ 4EB095102989CBB00043A8A1 /* Model+Settings.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "Model+Settings.swift"; sourceTree = "<group>"; };
4EB095112989CBB00043A8A1 /* WalletModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WalletModel.swift; sourceTree = "<group>"; };
- 4EB095142989CBB00043A8A1 /* WalletInitModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WalletInitModel.swift; sourceTree = "<group>"; };
4EB0951B2989CBCB0043A8A1 /* WalletBackendRequest.swift */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.swift; path = WalletBackendRequest.swift; sourceTree = "<group>"; };
4EB0951C2989CBCB0043A8A1 /* WalletCore.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WalletCore.swift; sourceTree = "<group>"; };
4EB0951D2989CBCB0043A8A1 /* WalletBackendError.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = WalletBackendError.swift; sourceTree = "<group>"; };
4EB0951E2989CBCB0043A8A1 /* Transaction.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= Transaction.swift; sourceTree = "<group>"; };
4EB095252989CBFE0043A8A1 /* SettingsView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= SettingsView.swift; sourceTree = "<group>"; };
4EB095262989CBFE0043A8A1 /* SettingsItem.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= SettingsItem.swift; sourceTree = "<group>"; };
- 4EB095282989CBFE0043A8A1 /* ExchangeModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= ExchangeModel.swift; sourceTree = "<group>"; };
4EB095292989CBFE0043A8A1 /* ExchangeListView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= ExchangeListView.swift; sourceTree = "<group>"; };
4EB0952B2989CBFE0043A8A1 /* PaymentAcceptView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= PaymentAcceptView.swift; sourceTree = "<group>"; };
- 4EB0952C2989CBFE0043A8A1 /* PaymentURIModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= PaymentURIModel.swift; sourceTree = "<group>"; };
+ 4EB0952C2989CBFE0043A8A1 /* Model+Payment.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "Model+Payment.swift"; sourceTree = "<group>"; };
4EB0952D2989CBFE0043A8A1 /* PaymentURIView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= PaymentURIView.swift; sourceTree = "<group>"; };
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>"; };
- 4EB095322989CBFE0043A8A1 /* TransactionsModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= TransactionsModel.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>"; };
- 4EB095352989CBFE0043A8A1 /* BalancesModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= BalancesModel.swift; sourceTree = "<group>"; };
4EB095362989CBFE0043A8A1 /* BalanceRowView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= BalanceRowView.swift; sourceTree = "<group>"; };
4EB095372989CBFE0043A8A1 /* BalancesListView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= BalancesListView.swift; sourceTree = "<group>"; };
4EB095382989CBFE0043A8A1 /* PendingRowView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= PendingRowView.swift; sourceTree = "<group>"; };
4EB095392989CBFE0043A8A1 /* WalletEmptyView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WalletEmptyView.swift; sourceTree = "<group>"; };
4EB0953A2989CBFE0043A8A1 /* BalancesSectionView.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = BalancesSectionView.swift; sourceTree = "<group>"; };
4EB0953C2989CBFE0043A8A1 /* WithdrawURIView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WithdrawURIView.swift; sourceTree = "<group>"; };
- 4EB0953D2989CBFE0043A8A1 /* WithdrawModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WithdrawModel.swift; sourceTree = "<group>"; };
+ 4EB0953D2989CBFE0043A8A1 /* Model+Withdraw.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "Model+Withdraw.swift"; sourceTree = "<group>"; };
4EB0953F2989CBFE0043A8A1 /* WithdrawProgressView.swift */ =
{isa = PBXFileReference; fileEncoding = 4; lastKnownFileType =
sourcecode.swift; path = WithdrawProgressView.swift; sourceTree = "<group>"; };
4EB095402989CBFE0043A8A1 /* WithdrawTOSView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WithdrawTOSView.swift; sourceTree = "<group>"; };
4EB095422989CBFE0043A8A1 /* SideBarView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= SideBarView.swift; sourceTree = "<group>"; };
@@ -213,7 +217,7 @@
4EB095482989CBFE0043A8A1 /* TextFieldAlert.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= TextFieldAlert.swift; sourceTree = "<group>"; };
4EB095492989CBFE0043A8A1 /* AmountView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= AmountView.swift; sourceTree = "<group>"; };
4EB0954A2989CBFE0043A8A1 /* LoadingView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= LoadingView.swift; sourceTree = "<group>"; };
- 4EB0954C2989CBFE0043A8A1 /* PendingModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= PendingModel.swift; sourceTree = "<group>"; };
+ 4EB0954C2989CBFE0043A8A1 /* Model+Pending.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "Model+Pending.swift"; sourceTree = "<group>"; };
4EB0954D2989CBFE0043A8A1 /* PendingOpView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= PendingOpView.swift; sourceTree = "<group>"; };
4EB0954E2989CBFE0043A8A1 /* PendingOpsListView.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = PendingOpsListView.swift; sourceTree = "<group>"; };
4EB3136029FEE79B007D68BC /* SendNow.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= SendNow.swift; sourceTree = "<group>"; };
@@ -221,7 +225,7 @@
4EBA82AA2A3EB2CA00E5F39A /* TransactionButton.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= TransactionButton.swift; sourceTree = "<group>"; };
4EBA82AC2A3F580500E5F39A /* QuiteSomeCoins.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path =
QuiteSomeCoins.swift; sourceTree = "<group>"; };
4EC90C772A1B528B0071DC58 /* ExchangeSectionView.swift */ = {isa
= PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift;
path = ExchangeSectionView.swift; sourceTree = "<group>"; };
- 4ECB627F2A0BA6DF004ABBB7 /* Peer2peerModel.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= Peer2peerModel.swift; sourceTree = "<group>"; };
+ 4ECB627F2A0BA6DF004ABBB7 /* Model+P2P.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= "Model+P2P.swift"; sourceTree = "<group>"; };
4ECB62812A0BB01D004ABBB7 /* SelectDays.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= SelectDays.swift; sourceTree = "<group>"; };
4ED2F94A2A278F5100453B40 /* ThreeAmounts.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= ThreeAmounts.swift; sourceTree = "<group>"; };
4EEC157229F8242800D46A03 /* QRGeneratorView.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= QRGeneratorView.swift; sourceTree = "<group>"; };
@@ -264,6 +268,15 @@
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
+ 4E3B4BBF2A41E64000CC88B8 /* P2P_Sheets */ = {
+ isa = PBXGroup;
+ children = (
+ 4E3B4BC02A41E6C200CC88B8 /*
P2pReceiveURIView.swift */,
+ 4E3B4BC22A42252300CC88B8 /* P2pAcceptDone.swift
*/,
+ );
+ path = P2P_Sheets;
+ sourceTree = "<group>";
+ };
4EB094EE298979840043A8A1 /* TalerWallet1 */ = {
isa = PBXGroup;
children = (
@@ -319,7 +332,8 @@
4EB095062989CB7C0043A8A1 /* TalerDater.swift */,
4EB095072989CB7C0043A8A1 /* TalerStrings.swift
*/,
4EB095082989CB7C0043A8A1 /*
View+dismissTop.swift */,
- 4E363CBB2A237E0900D7E98C /* URL+iban.swift */,
+ 4E3B4BC62A429F2A00CC88B8 /*
View+Notification.swift */,
+ 4E363CBB2A237E0900D7E98C /* URL+id+iban.swift
*/,
4E9320422A14F6EA00A87B0E /* WalletColors.swift
*/,
4E8E25322A1CD39700A27BFA /*
EqualIconWidthDomain.swift */,
);
@@ -338,15 +352,14 @@
isa = PBXGroup;
children = (
4EB095112989CBB00043A8A1 /* WalletModel.swift
*/,
- 4EB095142989CBB00043A8A1 /*
WalletInitModel.swift */,
- 4EB095352989CBFE0043A8A1 /* BalancesModel.swift
*/,
- 4EB095282989CBFE0043A8A1 /* ExchangeModel.swift
*/,
- 4ECB627F2A0BA6DF004ABBB7 /*
Peer2peerModel.swift */,
- 4EB0954C2989CBFE0043A8A1 /* PendingModel.swift
*/,
- 4EB0952C2989CBFE0043A8A1 /*
PaymentURIModel.swift */,
- 4EB095102989CBB00043A8A1 /* SettingsModel.swift
*/,
- 4EB095322989CBFE0043A8A1 /*
TransactionsModel.swift */,
- 4EB0953D2989CBFE0043A8A1 /* WithdrawModel.swift
*/,
+ 4E3B4BC42A428AF700CC88B8 /*
Model+Balances.swift */,
+ 4E3B4BC82A42BC4800CC88B8 /*
Model+Exchange.swift */,
+ 4ECB627F2A0BA6DF004ABBB7 /* Model+P2P.swift */,
+ 4EB0954C2989CBFE0043A8A1 /* Model+Pending.swift
*/,
+ 4EB0952C2989CBFE0043A8A1 /* Model+Payment.swift
*/,
+ 4EB095102989CBB00043A8A1 /*
Model+Settings.swift */,
+ 4EB095322989CBFE0043A8A1 /*
Model+Transactions.swift */,
+ 4EB0953D2989CBFE0043A8A1 /*
Model+Withdraw.swift */,
);
path = Model;
sourceTree = "<group>";
@@ -493,7 +506,7 @@
4E7940DD29FC307C00A9AEA1 /* SendPurpose.swift
*/,
4EB3136029FEE79B007D68BC /* SendNow.swift */,
4E9320442A1645B600A87B0E /*
RequestPayment.swift */,
- 4E9320462A164BC700A87B0E /*
ReceivePurpose.swift */,
+ 4E9320462A164BC700A87B0E /*
PaymentPurpose.swift */,
);
path = Peer2peer;
sourceTree = "<group>";
@@ -505,6 +518,7 @@
4EEC157929F9427F00D46A03 /* QRSheet.swift */,
4E753A072A0B6A5F002D9328 /* ShareSheet.swift */,
4EB095332989CBFE0043A8A1 /* URLSheet.swift */,
+ 4E3B4BBF2A41E64000CC88B8 /* P2P_Sheets */,
);
path = Sheets;
sourceTree = "<group>";
@@ -699,7 +713,6 @@
buildActionMask = 2147483647;
files = (
4ECB62822A0BB01D004ABBB7 /* SelectDays.swift in
Sources */,
- 4EB095512989CBFE0043A8A1 /* ExchangeModel.swift
in Sources */,
4E9796902A3765ED006F73BC /* AgePicker.swift in
Sources */,
4EB095032989C9BC0043A8A1 /* Controller.swift in
Sources */,
4EB095682989CBFE0043A8A1 /* MainView.swift in
Sources */,
@@ -714,15 +727,15 @@
4EB095532989CBFE0043A8A1 /*
PaymentAcceptView.swift in Sources */,
4EB095212989CBCB0043A8A1 /*
WalletBackendError.swift in Sources */,
4EB0955E2989CBFE0043A8A1 /*
PendingRowView.swift in Sources */,
- 4EB0955B2989CBFE0043A8A1 /* BalancesModel.swift
in Sources */,
4EB0956D2989CBFE0043A8A1 /* LoadingView.swift
in Sources */,
4E50B3502A1BEE8000F9F01C /*
ManualWithdraw.swift in Sources */,
+ 4E3B4BC92A42BC4800CC88B8 /*
Model+Exchange.swift in Sources */,
4E5A88F52A38A4FD00072618 /*
QRCodeDetailView.swift in Sources */,
4E87C8732A31CB7F001C6406 /*
TransactionsEmptyView.swift in Sources */,
4E87C8752A34B411001C6406 /*
UncompletedRowView.swift in Sources */,
4E40E0BE29F25ABB00B85369 /* SendAmount.swift in
Sources */,
4E8E25332A1CD39700A27BFA /*
EqualIconWidthDomain.swift in Sources */,
- 4EB095542989CBFE0043A8A1 /*
PaymentURIModel.swift in Sources */,
+ 4EB095542989CBFE0043A8A1 /* Model+Payment.swift
in Sources */,
4EB0954F2989CBFE0043A8A1 /* SettingsView.swift
in Sources */,
4EB095552989CBFE0043A8A1 /*
PaymentURIView.swift in Sources */,
4EB095612989CBFE0043A8A1 /*
WithdrawURIView.swift in Sources */,
@@ -741,24 +754,27 @@
4EB0956B2989CBFE0043A8A1 /*
TextFieldAlert.swift in Sources */,
4EBA82AD2A3F580500E5F39A /*
QuiteSomeCoins.swift in Sources */,
4EB431672A1E55C700C5690E /*
ManualWithdrawDone.swift in Sources */,
- 4E9320472A164BC700A87B0E /*
ReceivePurpose.swift in Sources */,
+ 4E9320472A164BC700A87B0E /*
PaymentPurpose.swift in Sources */,
4E753A082A0B6A5F002D9328 /* ShareSheet.swift in
Sources */,
4EB0956C2989CBFE0043A8A1 /* AmountView.swift in
Sources */,
+ 4E3B4BC32A42252300CC88B8 /* P2pAcceptDone.swift
in Sources */,
4E363CBE2A23CB2100D7E98C /*
AnyTransition+backslide.swift in Sources */,
- 4EB095592989CBFE0043A8A1 /*
TransactionsModel.swift in Sources */,
+ 4EB095592989CBFE0043A8A1 /*
Model+Transactions.swift in Sources */,
4EB0955F2989CBFE0043A8A1 /*
WalletEmptyView.swift in Sources */,
4E16E12329F3BB99008B9C86 /*
CurrencyFormatter.swift in Sources */,
- 4EB095192989CBB00043A8A1 /*
WalletInitModel.swift in Sources */,
4EB095092989CB7C0043A8A1 /* TalerDater.swift in
Sources */,
+ 4E3B4BC52A428AF700CC88B8 /*
Model+Balances.swift in Sources */,
4E363CC22A2621C200D7E98C /*
LocalizedAlertError.swift in Sources */,
4EB0950E2989CB9A0043A8A1 /* quickjs.swift in
Sources */,
4E53A33729F50B7B00830EC2 /* CurrencyField.swift
in Sources */,
- 4EB095152989CBB00043A8A1 /* SettingsModel.swift
in Sources */,
+ 4EB095152989CBB00043A8A1 /*
Model+Settings.swift in Sources */,
4EB095692989CBFE0043A8A1 /* ErrorView.swift in
Sources */,
- 4EB0956E2989CBFE0043A8A1 /* PendingModel.swift
in Sources */,
+ 4E3B4BC72A429F2A00CC88B8 /*
View+Notification.swift in Sources */,
+ 4EB0956E2989CBFE0043A8A1 /* Model+Pending.swift
in Sources */,
4EB095522989CBFE0043A8A1 /*
ExchangeListView.swift in Sources */,
4EB095642989CBFE0043A8A1 /*
WithdrawProgressView.swift in Sources */,
4EEC157A29F9427F00D46A03 /* QRSheet.swift in
Sources */,
+ 4E3B4BC12A41E6C200CC88B8 /*
P2pReceiveURIView.swift in Sources */,
4E6EDD872A363D8D0031D520 /* ListStyle.swift in
Sources */,
4EB095582989CBFE0043A8A1 /*
TransactionDetailView.swift in Sources */,
4EB095202989CBCB0043A8A1 /* WalletCore.swift in
Sources */,
@@ -769,13 +785,13 @@
4EB095162989CBB00043A8A1 /* WalletModel.swift
in Sources */,
4EB0955A2989CBFE0043A8A1 /* URLSheet.swift in
Sources */,
4ED2F94B2A278F5100453B40 /* ThreeAmounts.swift
in Sources */,
- 4EB095622989CBFE0043A8A1 /* WithdrawModel.swift
in Sources */,
+ 4EB095622989CBFE0043A8A1 /*
Model+Withdraw.swift in Sources */,
4EC90C782A1B528B0071DC58 /*
ExchangeSectionView.swift in Sources */,
4E7940DE29FC307C00A9AEA1 /* SendPurpose.swift
in Sources */,
- 4ECB62802A0BA6DF004ABBB7 /*
Peer2peerModel.swift in Sources */,
+ 4ECB62802A0BA6DF004ABBB7 /* Model+P2P.swift in
Sources */,
4EB0950A2989CB7C0043A8A1 /* TalerStrings.swift
in Sources */,
4EA551252A2C923600FEC9A8 /*
CurrencyInputView.swift in Sources */,
- 4E363CBC2A237E0900D7E98C /* URL+iban.swift in
Sources */,
+ 4E363CBC2A237E0900D7E98C /* URL+id+iban.swift
in Sources */,
4E9320452A1645B600A87B0E /*
RequestPayment.swift in Sources */,
4EB095502989CBFE0043A8A1 /* SettingsItem.swift
in Sources */,
4EB0955C2989CBFE0043A8A1 /*
BalanceRowView.swift in Sources */,
diff --git a/TalerWallet1/Backend/Transaction.swift
b/TalerWallet1/Backend/Transaction.swift
index fc77b17..0ca3188 100644
--- a/TalerWallet1/Backend/Transaction.swift
+++ b/TalerWallet1/Backend/Transaction.swift
@@ -102,8 +102,8 @@ struct TransactionCommon: Decodable {
case payment
case refund
case refresh
- case reward
-// case tip
+ 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
case peerPullCredit = "peer-pull-credit" // request payment
from peer, show QR
@@ -329,13 +329,13 @@ enum Transaction: Decodable, Hashable, Identifiable {
case .refund: return String(localized: "Refund")
case .refresh: return String(localized: "Refresh")
case .reward: return String(localized: "Reward")
- case .peerPushDebit: return String(localized: "P2P Send")
- case .scanPushCredit: return String(localized: "P2P Receive")
- case .peerPullCredit: return String(localized: "P2P Invoice")
- case .scanPullDebit: return String(localized: "P2P Payment")
+ case .peerPushDebit: return String(localized: "P2P Send",
comment: "send coins to another wallet")
+ case .scanPushCredit: return String(localized: "P2P Receive",
comment: "scan to receive coins sent from another wallet")
+ case .peerPullCredit: return String(localized: "P2P Invoice",
comment: "send invoice to another wallet")
+ case .scanPullDebit: return String(localized: "P2P Payment",
comment: "scan invoice to pay to another wallet")
}
}
-
+
static func == (lhs: Transaction, rhs: Transaction) -> Bool {
return lhs.id == rhs.id
}
@@ -360,13 +360,16 @@ enum Transaction: Decodable, Hashable, Identifiable {
var isP2pOutgoing: Bool { isSendCoins || isPayInvoice}
var isP2pIncoming: Bool { isSendInvoice || isRcvCoins}
- var isDone : Bool { common.txState.major == .done }
var isPending : Bool { common.txState.major == .pending }
+ var isDone : Bool { common.txState.major == .done }
var isAborting : Bool { common.txState.major == .aborting }
var isAborted : Bool { common.txState.major == .aborted }
+ var isSuspended : Bool { common.txState.major == .suspended }
+ var isDialog : Bool { common.txState.major == .dialog }
+ var isAbSuspended: Bool { common.txState.major == .suspendedAborting }
var isFailed : Bool { common.txState.major == .failed }
var isExpired : Bool { common.txState.major == .expired }
- var isSpecial : Bool { isPending || isAborting || isAborted || isFailed
|| isExpired }
+ var isSpecial : Bool { !(isDone || isPending) }
var isAbortable : Bool { common.txActions.contains(.abort) }
var isFailable : Bool { common.txActions.contains(.fail) }
diff --git a/TalerWallet1/Backend/WalletCore.swift
b/TalerWallet1/Backend/WalletCore.swift
index 684aaa7..ba43541 100644
--- a/TalerWallet1/Backend/WalletCore.swift
+++ b/TalerWallet1/Backend/WalletCore.swift
@@ -6,6 +6,7 @@ import SwiftUI // FOUNDATION has no AppStorage
import AnyCodable
import FTalerWalletcore
import SymLog
+import os
/// Delegate for the wallet backend.
protocol WalletBackendDelegate {
@@ -22,13 +23,14 @@ class WalletCore: QuickjsMessageHandler {
private var queue: DispatchQueue
private var semaphore: DispatchSemaphore
- private var quickjs: Quickjs
+ private let quickjs: Quickjs
private var requestsMade: UInt // counter for array of completion
closures
private var completions: [UInt : (Date, (UInt, Date, Data?,
WalletBackendResponseError?) -> Void)] = [:]
var delegate: WalletBackendDelegate?
var versionInfo: VersionInfo? // shown in SettingsView
var developDelay: Bool? // if set in SettingsView will
delay wallet-core after each action
+ let logger = Logger (subsystem: "net.taler.gnu", category: "wallet-core")
private struct FullRequest: Encodable {
let operation: String
@@ -163,6 +165,9 @@ extension WalletCore {
// symLog.log("\(pendingOp): \(id)")
} else if id.hasPrefix("withdraw:") {
// TODO: handle withdraw
+// symLog.log("\(pendingOp): \(id)")
+ } else if id.hasPrefix("peer-pull-credit:") {
+ // TODO: handle peer-pull-credit
// symLog.log("\(pendingOp): \(id)")
} else if id.hasPrefix("peer-push-debit:") {
// TODO: handle peer-push-debit
@@ -176,8 +181,10 @@ print("\n❗️ \(pendingOp): \(id)\n") // this is a
new pendingOp I have
private func handleStateTransition(_ jsonData: Data) throws {
do {
let decoded = try JSONDecoder().decode(TransactionTransition.self,
from: jsonData)
- postNotification(.TransactionStateTransition,
- userInfo: [TRANSACTIONTRANSITION: decoded])
+ if decoded.newTxState != decoded.oldTxState {
+ postNotification(.TransactionStateTransition,
+ userInfo: [TRANSACTIONTRANSITION: decoded])
+ }
} catch { // rethrows
symLog.log(jsonData) // TODO: .error
throw WalletBackendError.deserializationError
@@ -315,7 +322,7 @@ extension WalletCore {
sendRequest(request: reqData) { requestId, timeSent, result, error
in
let timeUsed = Date.now - timeSent
let millisecs = timeUsed.milliseconds
-print("Request \(requestId) took \(millisecs) ms")
+ self.logger.log("Request \(requestId) took \(millisecs) ms")
var err: Error? = nil
if let json = result {
do {
@@ -339,7 +346,7 @@ print("Request \(requestId) took \(millisecs) ms")
} else {
self.symLog.log(json) // TODO: .error
}
- err = error // this will be thrown, otherwise keep
nil
+ err = error // this will be thrown in
continuation.resume(throwing:), otherwise keep nil
}
} else {
if let error = error {
diff --git a/TalerWallet1/Controllers/Controller.swift
b/TalerWallet1/Controllers/Controller.swift
index 9e93489..3dc051f 100644
--- a/TalerWallet1/Controllers/Controller.swift
+++ b/TalerWallet1/Controllers/Controller.swift
@@ -14,10 +14,12 @@ enum BackendState {
case error
}
-enum UrlCommand {
+enum UrlCommand: String {
case unknown
case withdraw
case pay
+ case payPull = "pay-pull"
+ case payPush = "pay-push"
}
// MARK: -
@@ -33,13 +35,12 @@ class Controller: ObservableObject {
backendState = .instantiated
}
- @MainActor func initWalletCoreM()
+ @MainActor func initWalletCoreM(_ model: WalletModel)
async throws { // M for MainActor
if backendState == .instantiated {
backendState = .initing
do {
- let walletInitModel = WalletInitModel()
- let versionInfo = try await walletInitModel.initWalletT()
+ let versionInfo = try await model.initWalletCoreT()
WalletCore.shared.versionInfo = versionInfo
backendState = .ready // dismiss the
launch animation
} catch { // rethrows
@@ -48,7 +49,7 @@ class Controller: ObservableObject {
throw error
}
} else {
- symLog.log("Yikes❗️ wallet-core already initialized") // TODO:
.warning
+ symLog.log("Yikes❗️ wallet-core already initialized") // TODO:
.fault
}
}
}
@@ -93,6 +94,10 @@ extension Controller {
return UrlCommand.withdraw
case "pay":
return UrlCommand.pay
+ case "pay-pull":
+ return UrlCommand.payPull
+ case "pay-push":
+ return UrlCommand.payPush
default:
symLog.log("unknown command taler://\(command)")
}
diff --git a/TalerWallet1/Controllers/DebugViewC.swift
b/TalerWallet1/Controllers/DebugViewC.swift
index ec5b3db..ff0fe47 100644
--- a/TalerWallet1/Controllers/DebugViewC.swift
+++ b/TalerWallet1/Controllers/DebugViewC.swift
@@ -84,6 +84,8 @@ public let SHEET_PAY_P2P = SHEET_RCV_REWARD + 10
// 160 Pay P
// MARK: P2P Receive Coins
// p2p push credit - openURL (Link or scan QR)
public let SHEET_RCV_P2P = SHEET_PAY_P2P + 10 // 170
Receive P2P Coins
+public let SHEET_RCV_P2P_TOS = SHEET_RCV_P2P + 1 // 171
Receive P2P TOSView
+public let SHEET_RCV_P2P_ACCEPT = SHEET_RCV_P2P_TOS + 1 // 172
Receive P2P AcceptView
//public let SHEET_REFUND =
diff --git a/TalerWallet1/Controllers/TalerWallet1App.swift
b/TalerWallet1/Controllers/TalerWallet1App.swift
index da2a626..8bd6783 100644
--- a/TalerWallet1/Controllers/TalerWallet1App.swift
+++ b/TalerWallet1/Controllers/TalerWallet1App.swift
@@ -22,6 +22,7 @@ struct TalerWallet1App: App {
private let walletCore = WalletCore.shared
// our main controller
private let controller = Controller.shared
+ private let model = WalletModel.shared
private let debugViewC = DebugViewC.shared
func scheduleAppRefresh() {
@@ -36,12 +37,13 @@ struct TalerWallet1App: App {
.environmentObject(debugViewC) // change viewID / sheetID
.environmentObject(viewState) // popToRoot
.environmentObject(controller)
+ .environmentObject(model)
/// external events are taler:// or payto:// URLs passed
to this app
/// we handle them in .onOpenURL in MainView.swift
.handlesExternalEvents(preferring: ["*"], allowing: ["*"])
.task {
symLog.log("task -> initWalletCore")
- try! await controller.initWalletCoreM() // will (and
should) crash on failure
+ try! await controller.initWalletCoreM(model) // will
(and should) crash on failure
symLog.log("task -> initWalletCore done")
}
.onReceive(NotificationCenter.default.publisher(for:
UIApplication.didBecomeActiveNotification, object: nil)) { _ in
diff --git a/TalerWallet1/Helper/URL+iban.swift
b/TalerWallet1/Helper/URL+id+iban.swift
similarity index 100%
rename from TalerWallet1/Helper/URL+iban.swift
rename to TalerWallet1/Helper/URL+id+iban.swift
diff --git a/TalerWallet1/Helper/View+dismissTop.swift
b/TalerWallet1/Helper/View+Notification.swift
similarity index 66%
copy from TalerWallet1/Helper/View+dismissTop.swift
copy to TalerWallet1/Helper/View+Notification.swift
index ffd9c31..00760bf 100644
--- a/TalerWallet1/Helper/View+dismissTop.swift
+++ b/TalerWallet1/Helper/View+Notification.swift
@@ -1,5 +1,5 @@
// MIT License
-// Copyright © Nicolai Harbo
+// Copyright © John Sundell
//
// Permission is hereby granted, free of charge, to any person obtaining a
copy of this software
// and associated documentation files (the "Software"), to deal in the
Software without restriction,
@@ -18,14 +18,13 @@
//
import SwiftUI
-// John Sundell
extension View {
func onNotification(
_ notificationName: Notification.Name,
perform action: @escaping () -> Void
) -> some View {
onReceive(NotificationCenter.default
- .publisher(for: notificationName)
+ .publisher(for: notificationName)
) { _ in
action()
}
@@ -46,8 +45,8 @@ extension View {
perform action: @escaping () -> Void
) -> some View {
onReceive(NotificationCenter.default
- .publisher(for: notificationName)
- .receive(on: RunLoop.main)
+ .publisher(for: notificationName)
+ .receive(on: RunLoop.main)
) { _ in
action()
}
@@ -74,28 +73,3 @@ extension View {
)
}
}
-
-/// This is just a workaround for a SwiftUI bug
-/// A presented sheet (SwiftUI view) doesn't always close when calling
"dismiss()" provided by @Environment(\.dismiss),
-/// so we are walking the view stack to find the top presentedViewController
(UIKit) and dismiss it.
-extension View {
- public func dismissTop(animated: Bool = true) {
- let windows = UIApplication.shared.connectedScenes.compactMap {
- ($0 as? UIWindowScene)?.keyWindow // TODO: iPad might have
more than 1 window
- }
- if var topController = windows.first?.rootViewController {
- var gotPresented = false
- while let presentedViewController =
topController.presentedViewController {
- topController = presentedViewController
- gotPresented = true
- }
- if gotPresented {
- topController.dismiss(animated: animated)
- } else {
- print("Yikes❗️ Trying to dismiss the rootViewController!")
- }
- } else {
- print("Yikes❗️ There is no window/rootViewController!")
- }
- }
-}
diff --git a/TalerWallet1/Helper/View+dismissTop.swift
b/TalerWallet1/Helper/View+dismissTop.swift
index ffd9c31..40f0084 100644
--- a/TalerWallet1/Helper/View+dismissTop.swift
+++ b/TalerWallet1/Helper/View+dismissTop.swift
@@ -18,63 +18,6 @@
//
import SwiftUI
-// John Sundell
-extension View {
- func onNotification(
- _ notificationName: Notification.Name,
- perform action: @escaping () -> Void
- ) -> some View {
- onReceive(NotificationCenter.default
- .publisher(for: notificationName)
- ) { _ in
- action()
- }
- }
- func onNotification(
- _ notificationName: Notification.Name,
- perform action: @escaping (_ notification: Notification) -> Void
- ) -> some View {
- onReceive(NotificationCenter.default
- .publisher(for: notificationName)
- ) { notification in
- action(notification)
- }
- }
-
- func onNotificationM( // M for main thread
- _ notificationName: Notification.Name,
- perform action: @escaping () -> Void
- ) -> some View {
- onReceive(NotificationCenter.default
- .publisher(for: notificationName)
- .receive(on: RunLoop.main)
- ) { _ in
- action()
- }
- }
-
- func onNotificationM( // M for main thread
- _ notificationName: Notification.Name,
- perform action: @escaping (_ notification: Notification) -> Void
- ) -> some View {
- onReceive(NotificationCenter.default
- .publisher(for: notificationName)
- .receive(on: RunLoop.main)
- ) { notification in
- action(notification)
- }
- }
-
- func onAppEnteredBackground(
- perform action: @escaping () -> Void
- ) -> some View {
- onNotification(
- UIApplication.didEnterBackgroundNotification,
- perform: action
- )
- }
-}
-
/// This is just a workaround for a SwiftUI bug
/// A presented sheet (SwiftUI view) doesn't always close when calling
"dismiss()" provided by @Environment(\.dismiss),
/// so we are walking the view stack to find the top presentedViewController
(UIKit) and dismiss it.
diff --git a/TalerWallet1/Model/BalancesModel.swift
b/TalerWallet1/Model/Model+Balances.swift
similarity index 50%
rename from TalerWallet1/Model/BalancesModel.swift
rename to TalerWallet1/Model/Model+Balances.swift
index 0940c4e..7b81539 100644
--- a/TalerWallet1/Model/BalancesModel.swift
+++ b/TalerWallet1/Model/Model+Balances.swift
@@ -6,80 +6,53 @@ import Foundation
import taler_swift
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for
debugging
-// MARK: -
-class BalancesModel: WalletModel {
-
- override init(_ symbol: Int = -1) { // init with 0 to disable logging
for this class
- super.init(0)//symbol)
- }
-}
-// MARK: -
-/// A request to get the balances held in the wallet.
-fileprivate struct GetBalances: WalletBackendFormattedRequest {
- func operation() -> String { return "getBalances" }
- func args() -> Args { return Args() }
-
- struct Args: Encodable {} // no arguments needed
-
- struct Response: Decodable { // list of balances
- var balances: [Balance]
- }
-}
// MARK: -
/// A currency balance
struct Balance: Decodable, Hashable {
var available: Amount
- var pendingIncoming: Amount
- var pendingOutgoing: Amount
- var hasPendingTransactions: Bool
- var requiresUserInput: Bool
var scopeInfo: ScopeInfo
+ var requiresUserInput: Bool
+ var hasPendingTransactions: Bool
public static func == (lhs: Balance, rhs: Balance) -> Bool {
return lhs.available == rhs.available &&
- lhs.pendingIncoming == rhs.pendingIncoming &&
- lhs.pendingOutgoing == rhs.pendingOutgoing &&
- lhs.hasPendingTransactions == rhs.hasPendingTransactions &&
- lhs.requiresUserInput == rhs.requiresUserInput
+ lhs.scopeInfo == rhs.scopeInfo &&
+ lhs.requiresUserInput == rhs.requiresUserInput &&
+ lhs.hasPendingTransactions == rhs.hasPendingTransactions
}
public func hash(into hasher: inout Hasher) {
hasher.combine(available)
- hasher.combine(pendingIncoming)
- hasher.combine(pendingOutgoing)
- hasher.combine(hasPendingTransactions)
+ hasher.combine(scopeInfo)
hasher.combine(requiresUserInput)
+ hasher.combine(hasPendingTransactions)
}
}
// MARK: -
-extension BalancesModel {
+/// A request to get the balances held in the wallet.
+fileprivate struct Balances: WalletBackendFormattedRequest {
+ func operation() -> String { return "getBalances" }
+ func args() -> Args { return Args() }
+
+ struct Args: Encodable {} // no arguments needed
+
+ struct Response: Decodable { // list of balances
+ var balances: [Balance]
+ }
+}
+// MARK: -
+extension WalletModel {
/// fetch Balances from Wallet-Core. No networking involved
- @MainActor func fetchBalancesM()
+ @MainActor func balancesM()
async -> [Balance] { // M for MainActor
do {
- let request = GetBalances()
+ let request = Balances()
+ logger.info("balancesM")
let response = try await sendRequest(request, ASYNCDELAY)
return response.balances // trigger view update in
BalancesListView
} catch {
+ logger.error("balancesM failed: \(error)")
return []
}
}
}
-
-// MARK: -
-extension BalancesModel {
- private static var currencies: [String] = [] // names of
currencies
- private static var models: [BalancesModel] = [] // one model per
currency
-
- static func model(currency: String) -> BalancesModel {
- if let index = BalancesModel.currencies.firstIndex(of:currency) {
- let model = BalancesModel.models[index]
- return model
- } else { // new currency
- let model = BalancesModel()
- BalancesModel.models.append(model)
- BalancesModel.currencies.append(currency)
- return model
- }
- }
-}
diff --git a/TalerWallet1/Model/ExchangeModel.swift
b/TalerWallet1/Model/Model+Exchange.swift
similarity index 80%
rename from TalerWallet1/Model/ExchangeModel.swift
rename to TalerWallet1/Model/Model+Exchange.swift
index 58bf12a..fac7dae 100644
--- a/TalerWallet1/Model/ExchangeModel.swift
+++ b/TalerWallet1/Model/Model+Exchange.swift
@@ -7,11 +7,6 @@ import taler_swift
import SymLog
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for
debugging
-class ExchangeModel: WalletModel {
- override init(_ symbol: Int = -1) {
- super.init(0)//symbol)
- }
-}
// MARK: -
/// The result from wallet-core's ListExchanges
struct Exchange: Codable, Hashable, Identifiable {
@@ -83,39 +78,27 @@ fileprivate struct AddExchange:
WalletBackendFormattedRequest {
struct Response: Decodable {}
}
// MARK: -
-extension ExchangeModel {
+extension WalletModel {
/// ask wallet-core for its list of known exchanges
@MainActor func listExchangesM()
async -> [Exchange] { // M for MainActor
do {
let request = ListExchanges()
+ logger.info("ListExchanges")
let response = try await sendRequest(request, ASYNCDELAY)
return response.exchanges
} catch {
+ logger.error("listExchangesM failed: \(error)")
return [] // empty, but not nil
}
}
/// add a new exchange with URL to the wallet's list of known exchanges
- func addExchange(url: String) async throws {
+ func addExchange(url: String)
+ async throws {
symLog?.log("adding exchange: \(url)") // TODO: .notice
let request = AddExchange(exchangeBaseUrl: url)
+ logger.info("adding exchange: \(url)")
_ = try await sendRequest(request)
}
}
-
-// MARK: -
-extension ExchangeModel {
- private static var models: [ExchangeModel] = [] // a list of models
even though I currently need only one
-
- static func model() -> ExchangeModel {
- if ExchangeModel.models.count > 0 {
- let model = ExchangeModel.models[0]
- return model
- } else { // new model
- let model = ExchangeModel()
- ExchangeModel.models.append(model)
- return model
- }
- }
-}
diff --git a/TalerWallet1/Model/Peer2peerModel.swift
b/TalerWallet1/Model/Model+P2P.swift
similarity index 63%
rename from TalerWallet1/Model/Peer2peerModel.swift
rename to TalerWallet1/Model/Model+P2P.swift
index 9074ec1..4e1760d 100644
--- a/TalerWallet1/Model/Peer2peerModel.swift
+++ b/TalerWallet1/Model/Model+P2P.swift
@@ -8,11 +8,6 @@ import AnyCodable
//import SymLog
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for
debugging
-class Peer2peerModel: WalletModel {
- override init(_ symbol: Int = -1) { // init with 0 to disable logging
for this class
- super.init(0)//symbol)
- }
-}
// MARK: - PeerContractTerms
struct PeerContractTerms: Codable {
let amount: Amount
@@ -77,7 +72,45 @@ fileprivate struct InitiatePeerPushDebit:
WalletBackendFormattedRequest {
typealias Response = PeerPushResponse
func operation() -> String { return "initiatePeerPushDebit" }
func args() -> Args { return Args(exchangeBaseUrl: exchangeBaseUrl,
- partialContractTerms: partialContractTerms) }
+ partialContractTerms:
partialContractTerms) }
+
+ var exchangeBaseUrl: String?
+ var partialContractTerms: PeerContractTerms
+ struct Args: Encodable {
+ var exchangeBaseUrl: String?
+ var partialContractTerms: PeerContractTerms
+ }
+}
+
+struct PreparePeerPushCreditResponse: Codable {
+ let contractTerms: PeerContractTerms
+ let amountRaw: Amount
+ let amountEffective: Amount
+ let peerPushPaymentIncomingId: String
+}
+/// A request to receive coins from another wallet.
+fileprivate struct PreparePeerPushCredit: WalletBackendFormattedRequest {
+ typealias Response = PreparePeerPushCreditResponse
+ func operation() -> String { return "preparePeerPushCredit" }
+ func args() -> Args { return Args(talerUri: talerUri) }
+
+ var talerUri: String
+ struct Args: Encodable {
+ var talerUri: String
+ }
+}
+// MARK: -
+/// The result from InitiatePeerPullCredit
+struct PeerPullResponse: Codable {
+ let talerUri: String
+ let transactionId: String
+}
+/// A request to send a payment request to another wallet.
+fileprivate struct InitiatePeerPullCredit: WalletBackendFormattedRequest {
+ typealias Response = PeerPullResponse
+ func operation() -> String { return "initiatePeerPullCredit" }
+ func args() -> Args { return Args(exchangeBaseUrl: exchangeBaseUrl,
+ partialContractTerms:
partialContractTerms) }
var exchangeBaseUrl: String?
var partialContractTerms: PeerContractTerms
@@ -87,7 +120,7 @@ fileprivate struct InitiatePeerPushDebit:
WalletBackendFormattedRequest {
}
}
// MARK: -
-extension Peer2peerModel {
+extension WalletModel {
/// query exchange for fees (sending coins). Networking involved
@MainActor
func checkPeerPushDebitM(_ amount: Amount) // M for MainActor
@@ -96,6 +129,16 @@ extension Peer2peerModel {
let response = try await sendRequest(request, ASYNCDELAY)
return response
}
+ /// generate peer-push. Networking involved
+ @MainActor
+ func initiatePeerPushDebitM(_ baseURL: String?, terms: PeerContractTerms)
// M for MainActor
+ async throws -> PeerPushResponse {
+ let request = InitiatePeerPushDebit(exchangeBaseUrl: baseURL,
+ partialContractTerms: terms)
+ let response = try await sendRequest(request, ASYNCDELAY)
+ return response
+ }
+
/// query exchange for fees (invoice coins). Networking involved
@MainActor
func checkPeerPullCreditM(_ amount: Amount, exchangeBaseUrl: String?)
// M for MainActor
@@ -104,31 +147,22 @@ extension Peer2peerModel {
let response = try await sendRequest(request, ASYNCDELAY)
return response
}
- /// generate peer-push. Networking involved
+ /// generate peer-pull. Networking involved
@MainActor
- func initiatePeerPushDebitM(_ baseURL: String?, terms: PeerContractTerms)
// M for MainActor
- async throws -> PeerPushResponse {
- let request = InitiatePeerPushDebit(exchangeBaseUrl: baseURL,
- partialContractTerms: terms)
+ func initiatePeerPullCreditM(_ baseURL: String?, terms: PeerContractTerms)
// M for MainActor
+ async throws -> PeerPullResponse {
+ let request = InitiatePeerPullCredit(exchangeBaseUrl: baseURL,
+ partialContractTerms: terms)
let response = try await sendRequest(request, ASYNCDELAY)
return response
}
-}
-// MARK: -
-extension Peer2peerModel {
- private static var exchanges: [String] = [] // names of exchanges
- private static var models: [Peer2peerModel] = [] // one model per
exchange
-
- static func model(baseURL: String) -> Peer2peerModel {
- if let index = Peer2peerModel.exchanges.firstIndex(of:baseURL) {
- let model = Peer2peerModel.models[index]
- return model
- } else { // new model
- let model = Peer2peerModel()
- Peer2peerModel.models.append(model)
- Peer2peerModel.exchanges.append(baseURL)
- return model
- }
+ /// prepare peer-pull. Networking involved
+ @MainActor
+ func preparePeerPushCreditM(_ talerUri: String) // M for MainActor
+ async throws -> PreparePeerPushCreditResponse {
+ let request = PreparePeerPushCredit(talerUri: talerUri)
+ let response = try await sendRequest(request, ASYNCDELAY)
+ return response
}
}
diff --git a/TalerWallet1/Model/PaymentURIModel.swift
b/TalerWallet1/Model/Model+Payment.swift
similarity index 85%
rename from TalerWallet1/Model/PaymentURIModel.swift
rename to TalerWallet1/Model/Model+Payment.swift
index 8f758d6..940b126 100644
--- a/TalerWallet1/Model/PaymentURIModel.swift
+++ b/TalerWallet1/Model/Model+Payment.swift
@@ -8,12 +8,6 @@ import AnyCodable
//import SymLog
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for
debugging
-class PaymentURIModel: WalletModel {
-
- override init(_ symbol: Int = -1) { // init with 0 to disable logging
for this class
- super.init(0)//symbol)
- }
-}
// MARK: - ContractTerms
struct ContractTerms: Codable {
let amount: Amount
@@ -59,7 +53,6 @@ struct ContractTerms: Codable {
case wireFeeAmortization = "wire_fee_amortization"
}
}
-
// MARK: - Auditor
struct Auditor: Codable {
let name: String
@@ -72,7 +65,6 @@ struct Auditor: Codable {
case url
}
}
-
// MARK: - Exchange
struct ExchangeForPay: Codable {
let url: String
@@ -83,7 +75,6 @@ struct ExchangeForPay: Codable {
case masterPub = "master_pub"
}
}
-
// MARK: - Extra
struct Extra: Codable {
let articleName: String
@@ -92,7 +83,6 @@ struct Extra: Codable {
case articleName = "article_name"
}
}
-
// MARK: -
/// The result from PreparePayForUri
struct PaymentDetailsForUri: Codable {
@@ -134,7 +124,7 @@ fileprivate struct confirmPayForUri:
WalletBackendFormattedRequest {
}
}
// MARK: -
-extension PaymentURIModel {
+extension WalletModel {
/// load payment details. Networking involved
@MainActor
func preparePayForUriM(_ talerPayUri: String) // M for MainActor
@@ -151,19 +141,3 @@ extension PaymentURIModel {
return response
}
}
-
-// MARK: -
-extension PaymentURIModel {
- private static var models: [PaymentURIModel] = [] // a list of models
even though I currently need only one
-
- static func model() -> PaymentURIModel {
- if PaymentURIModel.models.count > 0 {
- let model = PaymentURIModel.models[0]
- return model
- } else { // new model
- let model = PaymentURIModel()
- PaymentURIModel.models.append(model)
- return model
- }
- }
-}
diff --git a/TalerWallet1/Model/PendingModel.swift
b/TalerWallet1/Model/Model+Pending.swift
similarity index 70%
rename from TalerWallet1/Model/PendingModel.swift
rename to TalerWallet1/Model/Model+Pending.swift
index 9021301..eb9f447 100644
--- a/TalerWallet1/Model/PendingModel.swift
+++ b/TalerWallet1/Model/Model+Pending.swift
@@ -8,12 +8,6 @@ import taler_swift
import SymLog
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for
debugging
-class PendingModel: WalletModel {
-
- override init(_ symbol: Int = -1) {
- super.init(0)//symbol)
- }
-}
// MARK: -
/// A request to list the backend's currently pending operations.
fileprivate struct GetPendingOperations: WalletBackendFormattedRequest {
@@ -45,10 +39,9 @@ struct PendingOperation: Codable, Hashable {
hasher.combine(isDue)
hasher.combine(timestampDue)
}
-
}
// MARK: -
-extension PendingModel {
+extension WalletModel {
@MainActor func getPendingOperationsM()
async -> [PendingOperation] { // M for MainActor
do {
@@ -60,19 +53,3 @@ extension PendingModel {
}
}
}
-
-// MARK: -
-extension PendingModel {
- private static var models: [PendingModel] = [] // a list of models
even though I currently need only one
-
- static func model() -> PendingModel {
- if PendingModel.models.count > 0 {
- let model = PendingModel.models[0]
- return model
- } else { // new model
- let model = PendingModel()
- PendingModel.models.append(model)
- return model
- }
- }
-}
diff --git a/TalerWallet1/Model/SettingsModel.swift
b/TalerWallet1/Model/Model+Settings.swift
similarity index 95%
rename from TalerWallet1/Model/SettingsModel.swift
rename to TalerWallet1/Model/Model+Settings.swift
index 0ca0d8a..188d4a0 100644
--- a/TalerWallet1/Model/SettingsModel.swift
+++ b/TalerWallet1/Model/Model+Settings.swift
@@ -14,13 +14,7 @@ fileprivate let DEMO_MERCHANTBASEURL = DEMOBACKEND
fileprivate let DEMO_MERCHANTAUTHTOKEN = "secret-token:sandbox"
// MARK: -
-class SettingsModel: WalletModel {
- override init(_ symbol: Int = -1) { // init with 0 to disable logging
for this class
- super.init(0)//symbol)
- }
-}
-// MARK: -
-extension SettingsModel {
+extension WalletModel {
@MainActor func loadTestKudosM()
async throws { // M for MainActor
let amount = Amount(currency: DEMOCURRENCY, integer: 11, fraction: 0)
diff --git a/TalerWallet1/Model/TransactionsModel.swift
b/TalerWallet1/Model/Model+Transactions.swift
similarity index 84%
rename from TalerWallet1/Model/TransactionsModel.swift
rename to TalerWallet1/Model/Model+Transactions.swift
index 0f4917a..4c4fd92 100644
--- a/TalerWallet1/Model/TransactionsModel.swift
+++ b/TalerWallet1/Model/Model+Transactions.swift
@@ -8,8 +8,7 @@ import SymLog
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for
debugging
// MARK: -
-class TransactionsModel: WalletModel {
-
+extension WalletModel {
static func specialTransactions(_ transactions: [Transaction]) ->
[Transaction] {
transactions.filter { transaction in
transaction.isSpecial
@@ -31,10 +30,6 @@ class TransactionsModel: WalletModel {
!transaction.isDone && !transaction.isPending
}
}
-
- override init(_ symbol: Int = -1) {
- super.init(0)//symbol)
- }
}
// MARK: -
@@ -83,7 +78,7 @@ struct DeleteTransaction: WalletBackendFormattedRequest {
}
// MARK: -
-extension TransactionsModel {
+extension WalletModel {
/// ask wallet-core for its list of transactions filtered by searchString
func fetchTransactionsT(currency: String? = nil, searchString: String? =
nil)
async -> [Transaction] { //
might be called from a background thread itself
@@ -123,21 +118,3 @@ extension TransactionsModel {
try await deleteTransactionT(transactionId: transactionId) //
call deleteTransaction on main thread
}
}
-
-// MARK: -
-extension TransactionsModel {
- private static var currencies: [String] = [] // names of
currencies
- private static var models: [TransactionsModel] = [] // one model per
currency
-
- static func model(currency: String) -> TransactionsModel {
- if let index = TransactionsModel.currencies.firstIndex(of:currency) {
- let model = TransactionsModel.models[index]
- return model
- } else { // new currency
- let model = TransactionsModel()
- TransactionsModel.models.append(model)
- TransactionsModel.currencies.append(currency)
- return model
- }
- }
-}
diff --git a/TalerWallet1/Model/WithdrawModel.swift
b/TalerWallet1/Model/Model+Withdraw.swift
similarity index 90%
rename from TalerWallet1/Model/WithdrawModel.swift
rename to TalerWallet1/Model/Model+Withdraw.swift
index 6198915..a420b58 100644
--- a/TalerWallet1/Model/WithdrawModel.swift
+++ b/TalerWallet1/Model/Model+Withdraw.swift
@@ -7,13 +7,6 @@ import taler_swift
import SymLog
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for
debugging
-class WithdrawModel: WalletModel {
-
- override init(_ symbol: Int = -1) { // init with 0 to disable logging
for this class
- super.init(0)//symbol)
- }
-}
-
// MARK: -
/// The result from getWithdrawalDetailsForUri
struct WithdrawUriInfoResponse: Decodable {
@@ -147,7 +140,7 @@ fileprivate struct AcceptManualWithdrawal:
WalletBackendFormattedRequest {
}
}
// MARK: -
-extension WithdrawModel {
+extension WalletModel {
/// load withdrawal details. Networking involved
@MainActor
func loadWithdrawalDetailsForUriM(_ talerWithdrawUri: String)
// M for MainActor
@@ -193,21 +186,3 @@ extension WithdrawModel {
return response
}
}
-
-// MARK: -
-extension WithdrawModel {
- private static var exchanges: [String] = [] // names of exchanges
- private static var models: [WithdrawModel] = [] // one model per
exchange
-
- static func model(baseURL: String) -> WithdrawModel {
- if let index = WithdrawModel.exchanges.firstIndex(of:baseURL) {
- let model = WithdrawModel.models[index]
- return model
- } else { // new model
- let model = WithdrawModel()
- WithdrawModel.models.append(model)
- WithdrawModel.exchanges.append(baseURL)
- return model
- }
- }
-}
diff --git a/TalerWallet1/Model/WalletInitModel.swift
b/TalerWallet1/Model/WalletInitModel.swift
deleted file mode 100644
index 28393bd..0000000
--- a/TalerWallet1/Model/WalletInitModel.swift
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * This file is part of GNU Taler, ©2022-23 Taler Systems S.A.
- * See LICENSE.md
- */
-import Foundation
-import SymLog
-
-private let DATABASE = "talerwalletdb-v30"
-
-class WalletInitModel: WalletModel {
- override init(_ symbol: Int = -1) { // init with 0 to disable logging
for this class
- super.init(0)//symbol)
- }
-}
-// MARK: -
-/// A request to initialize Wallet-core
-fileprivate struct WalletBackendInitRequest: WalletBackendFormattedRequest {
- func operation() -> String { return "init" }
- func args() -> Args {
- return Args(persistentStoragePath: persistentStoragePath,
-// cryptoWorkerType: "sync",
- logLevel: "info") // "trace", "info", "warn",
"error", "none"
- }
-
- struct Args: Encodable {
- var persistentStoragePath: String
-// var cryptoWorkerType: String
- var logLevel: String
- }
-
- var persistentStoragePath: String
-
- struct Response: Decodable {
- var versionInfo: VersionInfo
- }
-}
-// MARK: -
-/// The info returned from Wallet-core init
-struct VersionInfo: Decodable {
- var hash: String
- var version: String
- var exchange: String
- var merchant: String
- var bank: String
- var devMode: Bool
-}
-// MARK: -
-extension WalletInitModel {
- /// initalize Wallet-Core. Will do networking
- func initWalletT() // T for any Thread
- async throws -> VersionInfo? {
- let docPath = try docPath()
- let request = WalletBackendInitRequest(persistentStoragePath:
docPath)
- symLog?.log("info: not main thread")
- let response = try await sendRequest(request, 0) // no Delay
- return response.versionInfo
- }
-
- private func docPath () throws -> String {
- let documentUrls = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask)
- if (documentUrls.count > 0) {
- var storageDir = documentUrls[0]
- storageDir.appendPathComponent(DATABASE, isDirectory: false)
- storageDir.appendPathExtension("json")
- return storageDir.path
- } else { // should never happen
- symLog?.log("Yikes❗️ documentURLs empty") // TODO: symLog.error
- throw WalletBackendError.initializationError
- }
- }
-}
-
diff --git a/TalerWallet1/Model/WalletModel.swift
b/TalerWallet1/Model/WalletModel.swift
index 34626ca..6a912d6 100644
--- a/TalerWallet1/Model/WalletModel.swift
+++ b/TalerWallet1/Model/WalletModel.swift
@@ -4,25 +4,29 @@
*/
import Foundation
import SymLog
+import os
+fileprivate let DATABASE = "talerwalletdb-v30"
fileprivate let ASYNCDELAY: UInt = 0 //set e.g to 6 or 9 seconds for
debugging
// MARK: -
/// The "virtual" base class for all models
-class WalletModel {
+class WalletModel: ObservableObject {
+ public static let shared = WalletModel(-1)
static func className() -> String {"\(self)"}
var symLog: SymLogC?
+ let logger = Logger (subsystem: "net.taler.gnu", category: "wallet-core")
init(_ symbol: Int) { // init with 0 to
disable logging for this class
self.symLog = SymLogC(symbol == 0 ? 0 : -1, funcName: Self.className())
}
func sendRequest<T: WalletBackendFormattedRequest> (_ request: T, _ delay:
UInt = 0)
- async throws -> T.Response { // T for any Thread
+ async throws -> T.Response { // T for any Thread
+ symLog?.log("sending: \(request)")
let sendTime = Date.now
do {
- symLog?.log("sending: \(request)")
let (response, id) = try await
WalletCore.shared.sendFormattedRequest(request: request)
let timeUsed = Date.now - sendTime
let asyncDelay: UInt = delay > 0 ? delay : UInt(ASYNCDELAY)
@@ -66,4 +70,67 @@ fileprivate struct GetTransactionById:
WalletBackendFormattedRequest {
var transactionId: String
}
}
+// MARK: -
+/// The info returned from Wallet-core init
+struct VersionInfo: Decodable {
+ var hash: String
+ var version: String
+ var exchange: String
+ var merchant: String
+ var bank: String
+ var devMode: Bool
+}
+// MARK: -
+/// A request to initialize Wallet-core
+fileprivate struct InitRequest: WalletBackendFormattedRequest {
+ func operation() -> String { return "init" }
+ func args() -> Args {
+ return Args(persistentStoragePath: persistentStoragePath,
+// cryptoWorkerType: "sync",
+ logLevel: "info") // trace, info, warn,
error, none
+ }
+
+ struct Args: Encodable {
+ var persistentStoragePath: String
+// var cryptoWorkerType: String
+ var logLevel: String
+ }
+
+ var persistentStoragePath: String
+
+ struct Response: Decodable {
+ var versionInfo: VersionInfo
+ }
+}
+// MARK: -
+extension WalletModel {
+ /// initalize Wallet-Core. Will do networking
+ func initWalletCoreT() async throws -> VersionInfo {
+ do { // T for any Thread
+ let docPath = try docPath()
+ let request = InitRequest(persistentStoragePath: docPath)
+ logger.info("initWalletCoreT")
+ let response = try await sendRequest(request, 0) // no Delay
+ return response.versionInfo
+ } catch {
+ logger.error("initWalletCoreT failed: \(error)")
+ throw error
+ }
+ }
+ private func docPath () throws -> String {
+ let documentUrls = FileManager.default.urls(for: .documentDirectory,
in: .userDomainMask)
+ if (documentUrls.count > 0) {
+ var storageDir = documentUrls[0]
+ storageDir.appendPathComponent(DATABASE, isDirectory: false)
+ storageDir.appendPathExtension("json")
+ let docPath = storageDir.path
+ logger.debug("\(docPath)")
+ return docPath
+ } else { // should never happen
+ symLog?.log("Yikes❗️ documentURLs empty")
+ logger.error("documentURLs empty")
+ throw WalletBackendError.initializationError
+ }
+ }
+}
diff --git a/TalerWallet1/Views/Balances/BalancesListView.swift
b/TalerWallet1/Views/Balances/BalancesListView.swift
index 43398ce..09a0119 100644
--- a/TalerWallet1/Views/Balances/BalancesListView.swift
+++ b/TalerWallet1/Views/Balances/BalancesListView.swift
@@ -12,13 +12,13 @@ import AVFoundation
struct BalancesListView: View {
private let symLog = SymLogV(0)
let navTitle: String
+ let hamburgerAction: () -> Void
@State var balances: [Balance] = []
- let model: BalancesModel?
- let hamburgerAction: () -> Void
+ @EnvironmentObject private var model: WalletModel
@State private var centsToTransfer: UInt64 = 0
- @State private var purpose: String = ""
+ @State private var summary: String = ""
@State private var showQRScanner: Bool = false
@State private var showCameraAlert: Bool = false
@@ -62,11 +62,7 @@ struct BalancesListView: View {
}
private func reloadAction() async {
- if let model {
- balances = await model.fetchBalancesM()
- } else {
- balances = []
- }
+ balances = await model.balancesM()
}
var body: some View {
@@ -75,7 +71,7 @@ struct BalancesListView: View {
let _ = symLog.vlog() // just to get the # to compare it with
.onAppear & onDisappear
#endif
Content(symLog: symLog, balances: $balances,
- centsToTransfer: $centsToTransfer, purpose: $purpose,
+ centsToTransfer: $centsToTransfer, summary: $summary,
reloadAction: reloadAction)
.navigationTitle(navTitle)
.navigationBarTitleDisplayMode(.automatic)
@@ -111,7 +107,7 @@ extension BalancesListView {
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
@Binding var balances: [Balance]
@Binding var centsToTransfer: UInt64
- @Binding var purpose: String
+ @Binding var summary: String
var reloadAction: () async -> Void
var body: some View {
@@ -121,11 +117,9 @@ extension BalancesListView {
#endif
Group { // necessary for .backslide transition (bug in SwiftUI)
List(balances, id: \.self) { balance in
- let model = TransactionsModel.model(currency:
balance.available.currencyStr)
BalancesSectionView(balance: balance,
centsToTransfer: $centsToTransfer,
- purpose: $purpose,
- model: model)
+ summary: $summary)
}
.refreshable {
symLog?.log("refreshing")
diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift
b/TalerWallet1/Views/Balances/BalancesSectionView.swift
index 813e614..fef89da 100644
--- a/TalerWallet1/Views/Balances/BalancesSectionView.swift
+++ b/TalerWallet1/Views/Balances/BalancesSectionView.swift
@@ -18,8 +18,9 @@ struct BalancesSectionView: View {
private let symLog = SymLogV()
var balance:Balance
@Binding var centsToTransfer: UInt64
- @Binding var purpose: String
- var model: TransactionsModel?
+ @Binding var summary: String
+
+ @EnvironmentObject private var model: WalletModel
@State private var isShowingDetailView = false
@State private var buttonSelected: Int? = nil
@@ -29,15 +30,33 @@ struct BalancesSectionView: View {
@State private var pendingTransactions: [Transaction] = []
@State private var uncompletedTransactions: [Transaction] = []
- func dummyTransaction (_ transactionId: String) async throws {}
+// func dummyTransaction (_ transactionId: String) async throws {}
func reloadOneAction(_ transactionId: String) async throws -> Transaction {
- if let model {
- return try await model.getTransactionByIdT(transactionId)
- } else {
- throw WalletBackendError.walletCoreError
+ return try await model.getTransactionByIdT(transactionId)
+ }
+
+ func computePending(currency: String) -> (Amount, Amount) {
+ var incoming = Amount(currency: currency, value: 0)
+ var outgoing = Amount(currency: currency, value: 0)
+ for transaction in pendingTransactions {
+ let effective = transaction.common.amountEffective
+ if currency == effective.currencyStr {
+ do {
+ if transaction.common.incoming() {
+ incoming = try incoming + effective
+ } else {
+ outgoing = try outgoing + effective
+ }
+ } catch {
+ // TODO: log error
+ symLog.log(error.localizedDescription)
+ }
+ }
}
+ return (incoming, outgoing)
}
+
var body: some View {
#if DEBUG
let _ = Self._printChanges()
@@ -45,27 +64,19 @@ struct BalancesSectionView: View {
#endif
let currency = balance.available.currencyStr
let reloadCompleted = {
- if let model {
- transactions = await model.fetchTransactionsT(currency:
currency)
- completedTransactions =
TransactionsModel.completedTransactions(transactions)
- }
+ transactions = await model.fetchTransactionsT(currency: currency)
+ completedTransactions =
WalletModel.completedTransactions(transactions)
}
let reloadPending = {
- if let model {
- transactions = await model.fetchTransactionsT(currency:
currency)
- pendingTransactions =
TransactionsModel.pendingTransactions(transactions)
- }
+ transactions = await model.fetchTransactionsT(currency: currency)
+ pendingTransactions = WalletModel.pendingTransactions(transactions)
}
let reloadUncompleted = {
- if let model {
- transactions = await model.fetchTransactionsT(currency:
currency)
- uncompletedTransactions =
TransactionsModel.uncompletedTransactions(transactions)
- }
+ transactions = await model.fetchTransactionsT(currency: currency)
+ uncompletedTransactions =
WalletModel.uncompletedTransactions(transactions)
}
- let deleteAction = model?.deleteTransactionT ?? dummyTransaction
- let abortAction = model?.abortTransactionT ?? dummyTransaction
-
- let p2pModel = Peer2peerModel.model(baseURL: currency)
+ let deleteAction = model.deleteTransactionT // dummyTransaction
+ let abortAction = model.abortTransactionT
Section {
// if "KUDOS" == currency && !balance.available.isZero {
@@ -74,18 +85,16 @@ struct BalancesSectionView: View {
// }
HStack(spacing: 0) {
NavigationLink(destination: LazyView {
- SendAmount(model: p2pModel,
- amountAvailable: balance.available,
- centsToTransfer: $centsToTransfer,
- purpose: $purpose)
+ SendAmount(amountAvailable: balance.available,
+ centsToTransfer: $centsToTransfer,
+ summary: $summary)
}, tag: 1, selection: $buttonSelected
) { EmptyView() }.frame(width: 0).opacity(0).hidden()
NavigationLink(destination: LazyView {
- RequestPayment(model: p2pModel,
- scopeInfo: balance.scopeInfo,
- centsToTransfer: $centsToTransfer,
- purpose: $purpose)
+ RequestPayment(scopeInfo: balance.scopeInfo,
+ centsToTransfer: $centsToTransfer,
+ summary: $summary)
}, tag: 2, selection: $buttonSelected
) { EmptyView() }.frame(width: 0).opacity(0).hidden()
@@ -100,22 +109,22 @@ struct BalancesSectionView: View {
) { EmptyView() }.frame(width: 0).opacity(0).hidden()
BalanceRowView(amount: balance.available, sendAction: {
-print("button: Send \(currency)")
+//print("button: Send \(currency)")
buttonSelected = 1 // will trigger SendAmount
NavigationLink
}, recvAction: {
-print("button: Request Payment: \(currency)")
+//print("button: Request Payment: \(currency)")
buttonSelected = 2 // will trigger RequestPayment
NavigationLink
}, rowAction: {
-print("button: Transactions: \(currency)")
+//print("button: Transactions: \(currency)")
buttonSelected = 3 // will trigger
TransactionList NavigationLink
})
}
let hasPending = pendingTransactions.count > 0
if hasPending {
- let hasPendingIn = !balance.pendingIncoming.isZero
- let hasPendingOut = !balance.pendingOutgoing.isZero
+ let (pendingIncoming, pendingOutgoing) =
computePending(currency: currency)
+
NavigationLink {
-let _ = print("button: Pending Transactions: \(currency)")
+//let _ = print("button: Pending Transactions: \(currency)")
LazyView {
TransactionsListView(navTitle: String(localized:
"Pending"), currency: currency,
transactions: pendingTransactions,
@@ -126,11 +135,17 @@ let _ = print("button: Pending Transactions: \(currency)")
}
} label: {
VStack(spacing: 6) {
- if hasPendingIn {
- PendingRowView(amount: balance.pendingIncoming,
incoming: true)
+ var rows = 0
+ if !pendingIncoming.isZero {
+ PendingRowView(amount: pendingIncoming, incoming:
true)
+ let _ = (rows+=1)
+ }
+ if !pendingOutgoing.isZero {
+ PendingRowView(amount: pendingOutgoing, incoming:
false)
+ let _ = (rows+=1)
}
- if hasPendingOut {
- PendingRowView(amount: balance.pendingOutgoing,
incoming: false)
+ if rows == 0 {
+ Text("Some pending transactions")
}
}
}
@@ -138,7 +153,7 @@ let _ = print("button: Pending Transactions: \(currency)")
let hasUncompleted = uncompletedTransactions.count > 0
if hasUncompleted {
NavigationLink {
-let _ = print("button: Uncompleted Transactions: \(currency)")
+//let _ = print("button: Uncompleted Transactions: \(currency)")
LazyView {
TransactionsListView(navTitle: String(localized:
"Uncompleted"), currency: currency,
transactions:
uncompletedTransactions,
@@ -156,11 +171,10 @@ let _ = print("button: Uncompleted Transactions:
\(currency)")
Text(currency)
.font(.title)
} .task {
- if let model {
- transactions = await model.fetchTransactionsT(currency:
currency)
- pendingTransactions =
TransactionsModel.pendingTransactions(transactions)
- uncompletedTransactions =
TransactionsModel.uncompletedTransactions(transactions)
- }
+ let response = await model.fetchTransactionsT(currency: currency)
+ transactions = response
+ pendingTransactions = WalletModel.pendingTransactions(response)
+ uncompletedTransactions =
WalletModel.uncompletedTransactions(response)
}
} // body
}
@@ -168,21 +182,18 @@ let _ = print("button: Uncompleted Transactions:
\(currency)")
#if DEBUG
fileprivate struct BindingViewContainer : View {
@State var centsToTransfer: UInt64 = 333
- @State private var purpose: String = "bla-bla"
+ @State private var summary: String = "bla-bla"
var body: some View {
let scopeInfo = ScopeInfo(type: ScopeInfo.ScopeInfoType.exchange,
exchangeBaseUrl: DEMOEXCHANGE, currency: LONGCURRENCY)
let balance = Balance(available: try! Amount(fromString: LONGCURRENCY
+ ":0.1"),
- pendingIncoming: try! Amount(fromString: LONGCURRENCY
+ ":4.8"),
- pendingOutgoing: try! Amount(fromString: LONGCURRENCY
+ ":3.25"),
- hasPendingTransactions: true,
+ scopeInfo: scopeInfo,
requiresUserInput: false,
- scopeInfo: scopeInfo)
+ hasPendingTransactions: true)
List {
BalancesSectionView(balance: balance,
centsToTransfer: $centsToTransfer,
- purpose: $purpose,
- model: nil)
+ summary: $summary)
}
}
}
diff --git a/TalerWallet1/Views/Exchange/ExchangeListView.swift
b/TalerWallet1/Views/Exchange/ExchangeListView.swift
index 46644bd..83ba3b3 100644
--- a/TalerWallet1/Views/Exchange/ExchangeListView.swift
+++ b/TalerWallet1/Views/Exchange/ExchangeListView.swift
@@ -10,35 +10,27 @@ import SymLog
struct ExchangeListView: View {
private let symLog = SymLogV(0)
let navTitle: String
-
- var model: ExchangeModel?
var hamburgerAction: () -> Void
+ @EnvironmentObject private var model: WalletModel
+
@State private var exchanges: [Exchange] = []
// source of truth for the value the user enters in currencyField for
exchange withdrawals
@State private var centsToTransfer: UInt64 = 0 // TODO: different
values for different currencies?
func reloadAction() async -> Void {
- if let model {
exchanges = await model.listExchangesM()
- } else {
- exchanges = []
- }
}
func addExchange(_ exUrl: String) -> Void {
Task {
- if let model {
- symLog.log("adding: \(exUrl)")
- do {
- try await model.addExchange(url: exUrl)
- symLog.log("added: \(exUrl)")
- } catch { // TODO: error handling - couldn't add exchangeURL
- symLog.log("error: \(error)")
- }
- } else {
- symLog.log("no model, cannot add \(exUrl)")
+ symLog.log("adding: \(exUrl)")
+ do {
+ try await model.addExchange(url: exUrl)
+ symLog.log("added: \(exUrl)")
+ } catch { // TODO: error handling - couldn't add exchangeURL
+ symLog.log("error: \(error)")
}
}
}
diff --git a/TalerWallet1/Views/Exchange/ExchangeSectionView.swift
b/TalerWallet1/Views/Exchange/ExchangeSectionView.swift
index a7c9fad..4b6b635 100644
--- a/TalerWallet1/Views/Exchange/ExchangeSectionView.swift
+++ b/TalerWallet1/Views/Exchange/ExchangeSectionView.swift
@@ -13,7 +13,6 @@ struct ExchangeRowView: View {
@State private var buttonSelected: Int? = nil
var body: some View {
let baseURL = exchange.exchangeBaseUrl
- let model = WithdrawModel.model(baseURL: baseURL)
HStack(spacing: 0) { // can't use the built in Label because it
adds the accessory arrow
Text(baseURL.trimURL())
@@ -24,7 +23,6 @@ struct ExchangeRowView: View {
) { EmptyView() }.frame(width: 0).opacity(0)
NavigationLink(destination: LazyView {
ManualWithdraw(exchange: exchange,
- model: model,
centsToTransfer: $centsToTransfer)
}, tag: 2, selection: $buttonSelected
) { EmptyView() }.frame(width: 0).opacity(0)
diff --git a/TalerWallet1/Views/Exchange/ManualWithdraw.swift
b/TalerWallet1/Views/Exchange/ManualWithdraw.swift
index ab849a0..77034c2 100644
--- a/TalerWallet1/Views/Exchange/ManualWithdraw.swift
+++ b/TalerWallet1/Views/Exchange/ManualWithdraw.swift
@@ -11,9 +11,10 @@ struct ManualWithdraw: View {
private let symLog = SymLogV()
let exchange: Exchange
- let model: WithdrawModel?
@Binding var centsToTransfer: UInt64
+ @EnvironmentObject private var model: WalletModel
+
@State var manualWithdrawalDetails: ManualWithdrawalDetails? = nil
// @State var ageMenuList: [Int] = []
@@ -50,7 +51,6 @@ struct ManualWithdraw: View {
//let _ = print(selectedAge, restrictAge)
NavigationLink(destination: LazyView {
ManualWithdrawDone(exchange: exchange,
- model: model,
centsToTransfer: centsToTransfer)
// restrictAge: restrictAge)
}) {
@@ -59,7 +59,6 @@ struct ManualWithdraw: View {
} else {
NavigationLink(destination: LazyView {
WithdrawTOSView(exchangeBaseUrl:
exchange.exchangeBaseUrl,
- model: model,
viewID:
VIEW_WITHDRAW_TOS,
acceptAction: nil)
// pop back to here
}) {
@@ -69,7 +68,6 @@ struct ManualWithdraw: View {
}
} // tooMany
} // invalid
- Spacer()
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
@@ -82,10 +80,8 @@ struct ManualWithdraw: View {
.task(id: centsToTransfer) {
let amount = Amount.amountFromCents(currency, centsToTransfer)
do {
- if let model {
- manualWithdrawalDetails = try await
model.loadWithdrawalDetailsForAmountM(exchange.exchangeBaseUrl, amount: amount)
-// agePicker.setAges(ages:
manualWithdrawalDetails?.ageRestrictionOptions)
- }
+ manualWithdrawalDetails = try await
model.loadWithdrawalDetailsForAmountM(exchange.exchangeBaseUrl, amount: amount)
+// agePicker.setAges(ages:
manualWithdrawalDetails?.ageRestrictionOptions)
} catch { // TODO: error
symLog.log(error.localizedDescription)
manualWithdrawalDetails = nil
@@ -112,7 +108,6 @@ struct ManualWithdraw_Container : View {
ageRestrictionOptions: [],
permanent: false)
ManualWithdraw(exchange: exchange,
- model: nil,
centsToTransfer: $centsToTransfer,
manualWithdrawalDetails: details)
}
diff --git a/TalerWallet1/Views/Exchange/ManualWithdrawDone.swift
b/TalerWallet1/Views/Exchange/ManualWithdrawDone.swift
index 27c4213..0afd531 100644
--- a/TalerWallet1/Views/Exchange/ManualWithdrawDone.swift
+++ b/TalerWallet1/Views/Exchange/ManualWithdrawDone.swift
@@ -11,19 +11,16 @@ struct ManualWithdrawDone: View {
let navTitle = String(localized: "Wire Transfer")
let exchange: Exchange
- let model: WithdrawModel?
let centsToTransfer: UInt64
// let restrictAge: Int?
+ @EnvironmentObject private var model: WalletModel
+
@State var acceptManualWithdrawalResult: AcceptManualWithdrawalResult?
@State var withdrawalTransaction: Transaction?
func reloadOneAction(_ transactionId: String) async throws -> Transaction {
- if let model {
- return try await model.getTransactionByIdT(transactionId)
- } else {
- throw WalletBackendError.walletCoreError
- }
+ return try await model.getTransactionByIdT(transactionId)
}
var body: some View {
@@ -47,14 +44,12 @@ struct ManualWithdrawDone: View {
DebugViewC.shared.setViewID(VIEW_WITHDRAW_ACCEPT)
}.task {
do {
- if let model {
- let amount = Amount.amountFromCents(exchange.currency!,
centsToTransfer)
- let result = try await
model.sendAcceptManualWithdrawalM(exchange.exchangeBaseUrl,
-
amount: amount, restrictAge: 0)
+ let amount = Amount.amountFromCents(exchange.currency!,
centsToTransfer)
+ let result = try await
model.sendAcceptManualWithdrawalM(exchange.exchangeBaseUrl,
+
amount: amount, restrictAge: 0)
print(result as Any)
- let transaction = try await
model.getTransactionByIdT(result!.transactionId)
- withdrawalTransaction = transaction
- }
+ let transaction = try await
model.getTransactionByIdT(result!.transactionId)
+ withdrawalTransaction = transaction
} catch { // TODO: error
symLog.log(error.localizedDescription)
}
@@ -76,7 +71,6 @@ struct ManualWithdrawDone_Container : View {
ageRestrictionOptions: [],
permanent: false)
ManualWithdrawDone(exchange: exchange,
- model: nil,
centsToTransfer: centsToTransfer)
}
}
diff --git a/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
b/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
index 0d5366b..eaa5dea 100644
--- a/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
+++ b/TalerWallet1/Views/HelperViews/QRCodeDetailView.swift
@@ -8,12 +8,14 @@ import AVFoundation
struct QRCodeDetailView: View {
- var talerURI: String
+ @Binding var talerURI: String
+ let incoming: Bool
var body: some View {
if talerURI.count > 10 {
VStack {
- Text("Let the payee scan this QR code to receive:")
+ Text(incoming ? "Let the payer scan this QR code to pay:"
+ : "Let the payee scan this QR code to receive:")
.fixedSize(horizontal: false, vertical: true)
.padding(.top, 30)
.font(.title3)
@@ -35,25 +37,21 @@ struct QRCodeDetailView: View {
}
}
}
-
-
+// MARK: -
#if DEBUG
fileprivate struct ContentView: View {
- @State var isOn = false
+ @State var talerURI: String =
"taler://pay-push/exchange.demo.taler.net/95ZG4D1AGFGZQ7CNQ1V49D3FT18HXKA6HQT4X3XME9YSJQVFQ520"
var body: some View {
- VStack {
-
+ List {
+ QRCodeDetailView(talerURI: $talerURI, incoming: false)
}
}
}
struct QRCodeDetailView_Previews: PreviewProvider {
static var previews: some View {
-// ContentView()
- List {
- QRCodeDetailView(talerURI:
"taler://pay-push/exchange.demo.taler.net/95ZG4D1AGFGZQ7CNQ1V49D3FT18HXKA6HQT4X3XME9YSJQVFQ520")
- }
+ ContentView()
}
}
#endif
diff --git a/TalerWallet1/Views/Main/MainView.swift
b/TalerWallet1/Views/Main/MainView.swift
index b2745b6..20eea52 100644
--- a/TalerWallet1/Views/Main/MainView.swift
+++ b/TalerWallet1/Views/Main/MainView.swift
@@ -75,13 +75,11 @@ extension MainView {
SidebarItem(name: balances,
sysImage: "creditcard.fill", // TODO: Wallet Icon
view: AnyView(BalancesListView(navTitle: balances,
- model:
BalancesModel.model(currency: "*"),
hamburgerAction:
hamburgerAction)
)),
SidebarItem(name: exchanges,
sysImage: "building.columns",
view: AnyView(ExchangeListView(navTitle: exchanges,
- model:
ExchangeModel.model(),
hamburgerAction:
hamburgerAction)
)),
SidebarItem(name: settings, // TODO: "About"?
diff --git a/TalerWallet1/Views/Payment/PaymentURIView.swift
b/TalerWallet1/Views/Payment/PaymentURIView.swift
index 22048ca..c6e9ea6 100644
--- a/TalerWallet1/Views/Payment/PaymentURIView.swift
+++ b/TalerWallet1/Views/Payment/PaymentURIView.swift
@@ -6,10 +6,13 @@ import SwiftUI
import AVFoundation
import SymLog
+// Will be called either by the user scanning a QR code or tapping the
provided link, both from the shop's website
+// we show the user the payment details
struct PaymentURIView: View {
private let symLog = SymLogV()
- var url: URL
- var model: PaymentURIModel?
+ let url: URL
+
+ @EnvironmentObject private var model: WalletModel
@State var detailsForUri: PaymentDetailsForUri? = nil
@@ -27,16 +30,14 @@ struct PaymentURIView: View {
Task {
do {
if let detailsForUri {
- if let model {
- let confirmPayResult = try await
model.confirmPayM(detailsForUri.proposalId)
- symLog.log(confirmPayResult as Any)
- if confirmPayResult.type == "done" {
- // TODO: Show Hints that Payment was successfull
- playSound(success: true)
- } else {
- // TODO: show error
- playSound(success: false)
- }
+ let confirmPayResult = try await
model.confirmPayM(detailsForUri.proposalId)
+ symLog.log(confirmPayResult as Any)
+ if confirmPayResult.type == "done" {
+ // TODO: Show Hints that Payment was successfull
+ playSound(success: true)
+ } else {
+ // TODO: show error
+ playSound(success: false)
}
}
} catch { // TODO: error
@@ -59,9 +60,8 @@ struct PaymentURIView: View {
}.task {
do {
symLog.log(".task")
- if let model {
- detailsForUri = try await
model.preparePayForUriM(url.absoluteString)
- }
+ let details = try await
model.preparePayForUriM(url.absoluteString)
+ detailsForUri = details
} catch { // TODO: error
symLog.log(error.localizedDescription)
}
diff --git a/TalerWallet1/Views/Peer2peer/ReceivePurpose.swift
b/TalerWallet1/Views/Peer2peer/PaymentPurpose.swift
similarity index 60%
rename from TalerWallet1/Views/Peer2peer/ReceivePurpose.swift
rename to TalerWallet1/Views/Peer2peer/PaymentPurpose.swift
index 16add0d..e7230ea 100644
--- a/TalerWallet1/Views/Peer2peer/ReceivePurpose.swift
+++ b/TalerWallet1/Views/Peer2peer/PaymentPurpose.swift
@@ -6,40 +6,29 @@ import SwiftUI
import taler_swift
import SymLog
-struct ReceivePurpose: View {
+struct PaymentPurpose: View {
private let symLog = SymLogV()
- @FocusState private var isFocused: Bool
- @State var peerPullCheck: CheckPeerPullCreditResponse?
- var scopeInfo: ScopeInfo
- var centsToTransfer: UInt64
- @Binding var purpose: String
+ let scopeInfo: ScopeInfo
+ let centsToTransfer: UInt64
+ let fee: String
+ @Binding var summary: String
@Binding var expireDays: UInt
- var deactivateAction: () -> Void
+// var deactivateAction: () -> Void
- let formatter = CurrencyFormatter.shared // TODO: based on currency
+ @FocusState private var isFocused: Bool
+ let formatter = CurrencyFormatter.shared // TODO: based on currency
let buttonFont: Font = .title2
+
private var label: String {
let mag = pow(10, formatter.maximumFractionDigits)
return formatter.string(for: Decimal(centsToTransfer) / mag) ?? ""
}
- func pullFee(ppCheck: CheckPeerPullCreditResponse?) -> String {
- do {
- if let p2pcheck = ppCheck {
- let fee = try p2pcheck.amountRaw - p2pcheck.amountEffective
- return fee.readableDescription
- }
- } catch {}
- return ""
- }
-
var body: some View {
let amount = Amount.amountFromCents(scopeInfo.currency,
centsToTransfer)
- let model = Peer2peerModel.model(baseURL: scopeInfo.currency)
- let fee = pullFee(ppCheck: peerPullCheck)
VStack (spacing: 6) {
Text(amount.readableDescription)
Text("+ \(fee) payment fee")
@@ -49,7 +38,7 @@ struct ReceivePurpose: View {
.padding(.top)
.font(.title3)
- TextField("Purpose", text: $purpose)
+ TextField("Purpose", text: $summary)
.font(.title)
.foregroundColor(WalletColors().fieldForeground) //
text color
.background(WalletColors().fieldBackground)
@@ -63,7 +52,7 @@ struct ReceivePurpose: View {
HStack{
Spacer()
- Text("\(purpose.count)/100")
+ Text("\(summary.count)/100")
} // maximum 100 characters
Text("Expires in:")
@@ -73,13 +62,14 @@ struct ReceivePurpose: View {
.disabled(false)
.padding(.bottom)
- let buttonTitle = "Invoice \(label) \(scopeInfo.currency)"
- let disabled = (expireDays == 0) || (purpose.count < 1)
+ let disabled = (expireDays == 0) || (summary.count < 1)
NavigationLink(destination: LazyView {
- SendNow(amountToSend: amount, purpose: purpose,
expireDays: expireDays, model: model)
+ SendNow(amountToSend: nil,
+ amountToReceive: amount,
+ summary: summary, expireDays: expireDays)
}) {
- Text(buttonTitle)
+ Text("Invoice \(label) \(scopeInfo.currency)")
.font(buttonFont)
}
.buttonStyle(TalerButtonStyle(type: .prominent))
@@ -94,36 +84,28 @@ struct ReceivePurpose: View {
.background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all))
.onAppear {
DebugViewC.shared.setSheetID(VIEW_INVOICE_PURPOSE)
- print("❗️ ReceivePurpose onAppear")
+ print("❗️ PaymentPurpose onAppear")
}
.onDisappear {
- print("❗️ ReceivePurpose onDisappear")
- deactivateAction()
- }
- .task {
- symLog.log(".task")
- do {
- peerPullCheck = try await model.checkPeerPullCreditM(amount,
exchangeBaseUrl: scopeInfo.exchangeBaseUrl ?? nil) // TODO: exchangeBaseUrl!
- } catch { // TODO: error
- symLog.log(error.localizedDescription)
- }
+ print("❗️ PaymentPurpose onDisappear")
+// deactivateAction()
}
}
}
// MARK: -
#if DEBUG
-struct ReceivePurpose_Previews: PreviewProvider {
+struct PaymentPurpose_Previews: PreviewProvider {
static var previews: some View {
let scopeInfo = ScopeInfo(type: ScopeInfo.ScopeInfoType.exchange,
exchangeBaseUrl: DEMOEXCHANGE, currency: LONGCURRENCY)
- @State var purpose: String = "pUrPoSe"
+ @State var summary: String = "pUrPoSe"
@State var expireDays: UInt = 0
- ReceivePurpose(scopeInfo: scopeInfo,
+ PaymentPurpose(scopeInfo: scopeInfo,
centsToTransfer: 5,
- purpose: $purpose,
- expireDays: $expireDays) {
- print("deactivateAction")
- }
+ fee: "fee",
+ summary: $summary,
+ expireDays: $expireDays)
+// { print("deactivateAction") }
}
}
#endif
diff --git a/TalerWallet1/Views/Peer2peer/RequestPayment.swift
b/TalerWallet1/Views/Peer2peer/RequestPayment.swift
index d8d3be3..27e4aa6 100644
--- a/TalerWallet1/Views/Peer2peer/RequestPayment.swift
+++ b/TalerWallet1/Views/Peer2peer/RequestPayment.swift
@@ -6,13 +6,15 @@ import SwiftUI
import taler_swift
import SymLog
+// Will be called by the user tapping "Request Payment" in the balances list
struct RequestPayment: View {
private let symLog = SymLogV()
- let model: Peer2peerModel?
var scopeInfo: ScopeInfo
@Binding var centsToTransfer: UInt64
- @Binding var purpose: String
+ @Binding var summary: String
+
+ @EnvironmentObject private var model: WalletModel
@State private var peerPullCheck: CheckPeerPullCreditResponse? = nil
@State private var expireDays: UInt = 0
@@ -26,7 +28,7 @@ struct RequestPayment: View {
let navTitle = String(localized: "Request \(currency)")
let currencyField = CurrencyField(value: $centsToTransfer, currency:
currency)
- VStack(alignment: .leading, spacing: 6) {
+ ScrollView {
CurrencyInputView(currencyField: currencyField,
title: String(localized: "Amount to receive:"))
@@ -37,26 +39,19 @@ struct RequestPayment: View {
HStack {
let disabled = centsToTransfer == 0
- let deactivateAction = {
- print("❗️ deactivateAction")
- }
-
NavigationLink(destination: LazyView {
- ReceivePurpose(scopeInfo: scopeInfo,
+ PaymentPurpose(scopeInfo: scopeInfo,
centsToTransfer: centsToTransfer,
- purpose: $purpose,
- expireDays: $expireDays
- ) {
- deactivateAction()
- }
+ fee: someCoins.fee,
+ summary: $summary,
+ expireDays: $expireDays)
+// { deactivateAction() }
}) {
Text("Create invoice")
}
.buttonStyle(TalerButtonStyle(type: .prominent))
.disabled(disabled)
}
-
- Spacer()
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
@@ -72,12 +67,10 @@ struct RequestPayment: View {
.task(id: centsToTransfer) {
let amount = Amount.amountFromCents(currency, centsToTransfer)
do {
- if let model {
- let ppCheck = try await model.checkPeerPullCreditM(amount,
exchangeBaseUrl: nil)
- peerPullCheck = ppCheck
- // TODO: set from exchange
+ let ppCheck = try await model.checkPeerPullCreditM(amount,
exchangeBaseUrl: nil)
+ peerPullCheck = ppCheck
+ // TODO: set from exchange
// agePicker.setAges(ages: peerPushCheck?.ageRestrictionOptions)
- }
} catch { // TODO: error
symLog.log(error.localizedDescription)
peerPullCheck = nil
diff --git a/TalerWallet1/Views/Peer2peer/SendAmount.swift
b/TalerWallet1/Views/Peer2peer/SendAmount.swift
index 17e7026..a845d6d 100644
--- a/TalerWallet1/Views/Peer2peer/SendAmount.swift
+++ b/TalerWallet1/Views/Peer2peer/SendAmount.swift
@@ -10,12 +10,13 @@ import SymLog
struct SendAmount: View {
private let symLog = SymLogV()
- let model: Peer2peerModel?
let amountAvailable: Amount
@Binding var centsToTransfer: UInt64
- @Binding var purpose: String
+ @Binding var summary: String
- @State var peerPushCheck: CheckPeerPushDebitResponse?
+ @EnvironmentObject private var model: WalletModel
+
+ @State var peerPushCheck: CheckPeerPushDebitResponse? = nil
@State private var expireDays: UInt = 0
private func fee(ppCheck: CheckPeerPushDebitResponse?) -> String {
@@ -54,21 +55,18 @@ struct SendAmount: View {
let disabled = centsToTransfer == 0 // TODO: check
amountAvailable
NavigationLink(destination: LazyView {
- SendPurpose(model: model,
- amountAvailable: amountAvailable,
- centsToSend: centsToTransfer,
- fee: fee,
- purpose: $purpose,
- expireDays: $expireDays,
- deactivateAction: {})
+ SendPurpose(amountAvailable: amountAvailable,
+ centsToTransfer: centsToTransfer,
+ fee: fee,
+ summary: $summary,
+ expireDays: $expireDays)
+// { deactivateAction() }
}) {
Text("To another wallet")
}
.buttonStyle(TalerButtonStyle(type: .prominent))
.disabled(disabled)
}
-
- Spacer()
}
.frame(maxWidth: .infinity, alignment: .leading)
.padding(.horizontal)
@@ -84,12 +82,10 @@ struct SendAmount: View {
.task(id: centsToTransfer) {
let amount = Amount.amountFromCents(currency, centsToTransfer)
do {
- if let model {
- let ppCheck = try await model.checkPeerPushDebitM(amount)
- peerPushCheck = ppCheck
- // TODO: set from exchange
- // agePicker.setAges(ages:
peerPushCheck?.ageRestrictionOptions)
- }
+ let ppCheck = try await model.checkPeerPushDebitM(amount)
+ peerPushCheck = ppCheck
+ // TODO: set from exchange
+// agePicker.setAges(ages: peerPushCheck?.ageRestrictionOptions)
} catch { // TODO: error
symLog.log(error.localizedDescription)
peerPushCheck = nil
@@ -101,14 +97,13 @@ struct SendAmount: View {
#if DEBUG
struct SendAmount_Container : View {
@State private var centsToTransfer: UInt64 = 510
- @State private var purpose: String = ""
+ @State private var summary: String = ""
var body: some View {
let amount = Amount(currency: LONGCURRENCY, integer: 10, fraction: 0)
- SendAmount(model: nil,
- amountAvailable: amount,
- centsToTransfer: $centsToTransfer,
- purpose: $purpose)
+ SendAmount(amountAvailable: amount,
+ centsToTransfer: $centsToTransfer,
+ summary: $summary)
}
}
diff --git a/TalerWallet1/Views/Peer2peer/SendNow.swift
b/TalerWallet1/Views/Peer2peer/SendNow.swift
index 8615341..811c22b 100644
--- a/TalerWallet1/Views/Peer2peer/SendNow.swift
+++ b/TalerWallet1/Views/Peer2peer/SendNow.swift
@@ -10,22 +10,22 @@ import SymLog
struct SendNow: View {
private let symLog = SymLogV()
- var amountToSend: Amount
- var purpose: String
- var expireDays: UInt
+ let amountToSend: Amount?
+ let amountToReceive: Amount?
+ let summary: String
+ let expireDays: UInt
- var model: Peer2peerModel?
- @State var peerPushResponse: PeerPushResponse?
+ @EnvironmentObject private var model: WalletModel
- @State var talerURI: String? = nil
+ @State var talerURI: String = ""
var body: some View {
ScrollView {
- if talerURI == nil {
+ if talerURI.isEmpty {
LoadingView(backButtonHidden: true)
} else {
VStack() {
- QRCodeDetailView(talerURI: talerURI!)
+ QRCodeDetailView(talerURI: $talerURI, incoming:
amountToSend == nil)
Text("The QR code can also be copied and shared from
Transactions later")
.fixedSize(horizontal: false, vertical: true)
@@ -50,29 +50,38 @@ struct SendNow: View {
symLog.log(".task")
do {
// generate talerURI
- if let model {
- let timestamp = Timestamp.inSomeDays(expireDays)
- let terms = PeerContractTerms(amount: amountToSend,
summary: purpose, purse_expiration: timestamp)
+ let timestamp = Timestamp.inSomeDays(expireDays)
+ if let amountToSend {
+ let terms = PeerContractTerms(amount: amountToSend,
+ summary: summary,
+ purse_expiration: timestamp)
// TODO: user might choose baseURL
- peerPushResponse = try await
model.initiatePeerPushDebitM(nil, terms: terms)
- talerURI = peerPushResponse?.talerUri
- }
+ let response = try await model.initiatePeerPushDebitM(nil,
terms: terms)
+ talerURI = response.talerUri
+ } else if let amountToReceive {
+ let terms = PeerContractTerms(amount: amountToReceive,
+ summary: summary,
+ purse_expiration: timestamp)
+ // TODO: user might choose baseURL
+ let response = try await
model.initiatePeerPullCreditM(nil, terms: terms)
+ talerURI = response.talerUri
+ } else { talerURI = "" }
} catch { // TODO: error
symLog.log(error.localizedDescription)
+ talerURI = ""
}
} // task
}
}
// MARK: -
-//struct SendNow_Previews: PreviewProvider {
-// static var previews: some View {
-// Group {
-// SendNow(amountToSend: <#T##Amount#>,
-// purpose: <#T##String#>,
-// expireDays: <#T##UInt#>,
-// model: <#T##Peer2peerModel#>,
-// peerPushResponse: <#T##PeerPushResponse?#>,
-// talerURI:
"taler://pay-push/exchange.demo.taler.net/95ZG4D1AGFGZQ7CNQ1V49D3FT18HXKA6HQT4X3XME9YSJQVFQ520")
-// }
-// }
-//}
+struct SendNow_Previews: PreviewProvider {
+ static var previews: some View {
+ Group {
+ SendNow(amountToSend: try! Amount(fromString: LONGCURRENCY +
":4.8"),
+ amountToReceive: nil,
+ summary: "some purpose",
+ expireDays: 0,
+ talerURI:
"taler://pay-push/exchange.demo.taler.net/95ZG4D1AGFGZQ7CNQ1V49D3FT18HXKA6HQT4X3XME9YSJQVFQ520")
+ }
+ }
+}
diff --git a/TalerWallet1/Views/Peer2peer/SendPurpose.swift
b/TalerWallet1/Views/Peer2peer/SendPurpose.swift
index 298115e..a17d7f4 100644
--- a/TalerWallet1/Views/Peer2peer/SendPurpose.swift
+++ b/TalerWallet1/Views/Peer2peer/SendPurpose.swift
@@ -9,25 +9,24 @@ import SymLog
struct SendPurpose: View {
private let symLog = SymLogV()
@FocusState private var isFocused: Bool
- var model: Peer2peerModel?
- var amountAvailable: Amount
- var centsToSend: UInt64
- var fee: String
- @Binding var purpose: String
+ let amountAvailable: Amount
+ let centsToTransfer: UInt64
+ let fee: String
+ @Binding var summary: String
@Binding var expireDays: UInt
- var deactivateAction: () -> Void
+// var deactivateAction: () -> Void
let formatter = CurrencyFormatter.shared // TODO: based on currency
let buttonFont: Font = .title2
private var label: String {
let mag = pow(10, formatter.maximumFractionDigits)
- return formatter.string(for: Decimal(centsToSend) / mag) ?? ""
+ return formatter.string(for: Decimal(centsToTransfer) / mag) ?? ""
}
var body: some View {
- let amount = Amount.amountFromCents(amountAvailable.currencyStr,
centsToSend)
+ let amount = Amount.amountFromCents(amountAvailable.currencyStr,
centsToTransfer)
VStack (spacing: 6) {
Text(amount.readableDescription)
@@ -38,7 +37,7 @@ struct SendPurpose: View {
.padding(.top)
.font(.title3)
- TextField("Purpose", text: $purpose)
+ TextField("Purpose", text: $summary)
.font(.title)
.foregroundColor(WalletColors().fieldForeground) //
text color
.background(WalletColors().fieldBackground)
@@ -52,7 +51,7 @@ struct SendPurpose: View {
HStack{
Spacer()
- Text("\(purpose.count)/100")
+ Text("\(summary.count)/100")
} // maximum 100 characters
Text("Expires in:")
@@ -63,13 +62,14 @@ struct SendPurpose: View {
.disabled(false)
.padding(.bottom)
- let buttonTitle = "Send \(label)
\(amountAvailable.currencyStr) now"
- let disabled = (expireDays == 0) || (purpose.count < 1) //
TODO: check amountAvailable
+ let disabled = (expireDays == 0) || (summary.count < 1) //
TODO: check amountAvailable
NavigationLink(destination: LazyView {
- SendNow(amountToSend: amount, purpose: purpose,
expireDays: expireDays, model: model)
+ SendNow(amountToSend: amount,
+ amountToReceive: nil,
+ summary: summary, expireDays: expireDays)
}) {
- Text(buttonTitle)
+ Text("Send \(label) \(amountAvailable.currencyStr) now")
.font(buttonFont)
}
.buttonStyle(TalerButtonStyle(type: .prominent))
@@ -88,7 +88,7 @@ struct SendPurpose: View {
}
.onDisappear {
print("❗️ SendPurpose onDisappear")
- deactivateAction()
+// deactivateAction()
}
.task {
symLog.log(".task")
@@ -105,18 +105,15 @@ struct SendPurpose: View {
#if DEBUG
struct SendPurpose_Previews: PreviewProvider {
static var previews: some View {
- @State var purpose: String = ""
+ @State var summary: String = ""
@State var expireDays: UInt = 0
let amount = Amount(currency: LONGCURRENCY, integer: 10, fraction: 0)
- SendPurpose(model: nil,
- amountAvailable: amount,
- centsToSend: 543,
- fee: "0,43",
- purpose: $purpose,
- expireDays: $expireDays
- ) {
- print("deactivateAction")
- }
+ SendPurpose(amountAvailable: amount,
+ centsToTransfer: 543,
+ fee: "0,43",
+ summary: $summary,
+ expireDays: $expireDays)
+// { print("deactivateAction") }
}
}
#endif
diff --git a/TalerWallet1/Views/Settings/Pending/PendingOpsListView.swift
b/TalerWallet1/Views/Settings/Pending/PendingOpsListView.swift
index 8f29111..66691b6 100644
--- a/TalerWallet1/Views/Settings/Pending/PendingOpsListView.swift
+++ b/TalerWallet1/Views/Settings/Pending/PendingOpsListView.swift
@@ -9,8 +9,9 @@ struct PendingOpsListView: View {
private let symLog = SymLogV(0)
let navTitle = String(localized: "Pending")
+ @EnvironmentObject private var model: WalletModel
+
@State var pendingOperations: [PendingOperation] = []
- var model: PendingModel
var body: some View {
#if DEBUG
@@ -32,6 +33,7 @@ extension PendingOpsListView {
let symLog: SymLogV?
@Binding var pendingOperations: [PendingOperation]
var reloadAction: () async -> [PendingOperation]
+ @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
var body: some View {
#if DEBUG
let _ = Self._printChanges()
@@ -41,7 +43,7 @@ extension PendingOpsListView {
List(pendingOperations, id: \.self) { pendingOp in
PendingOpView(pendingOp: pendingOp)
}
- .listStyle(SidebarListStyle())
+ .listStyle(myListStyle.style).anyView
.navigationBarTitleDisplayMode(.large)
.onAppear() {
DebugViewC.shared.setViewID(VIEW_PENDING)
diff --git a/TalerWallet1/Views/Settings/SettingsView.swift
b/TalerWallet1/Views/Settings/SettingsView.swift
index 247a1e8..e299e65 100644
--- a/TalerWallet1/Views/Settings/SettingsView.swift
+++ b/TalerWallet1/Views/Settings/SettingsView.swift
@@ -27,6 +27,8 @@ struct SettingsView: View {
var hamburgerAction: () -> Void
+ @EnvironmentObject private var model: WalletModel
+
@State private var checkDisabled = false
@State private var withDrawDisabled = false
#if DEBUG
@@ -66,7 +68,7 @@ struct SettingsView: View {
}
if showDevelopItems { // show or hide the following items
NavigationLink { // whole row like in a
tableView
- LazyView { PendingOpsListView(model:
PendingModel.model()) }
+ LazyView { PendingOpsListView() }
} label: {
SettingsItem(name: String(localized: "Pending
Operations"), description: String(localized: "Exchange not yet ready...")) {}
}
@@ -80,7 +82,6 @@ struct SettingsView: View {
Button("Withdraw") {
withDrawDisabled = true // don't run twice
Task {
- let model: SettingsModel = SettingsModel()
symLog.log("Withdraw TestKUDOS")
do {
try await model.loadTestKudosM()
@@ -97,7 +98,6 @@ struct SettingsView: View {
Button("Test 1") {
checkDisabled = true // don't run twice
Task {
- let model: SettingsModel = SettingsModel()
symLog.log("running integration test")
do {
try await
model.runIntegrationTestM(newVersion: false)
@@ -114,7 +114,6 @@ struct SettingsView: View {
Button("Test 2") {
checkDisabled = true // don't run twice
Task {
- let model: SettingsModel = SettingsModel()
symLog.log("running integration test V2")
do {
try await
model.runIntegrationTestM(newVersion: true)
diff --git a/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawAcceptDone.swift
b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift
similarity index 75%
copy from TalerWallet1/Views/WithdrawBankIntegrated/WithdrawAcceptDone.swift
copy to TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift
index 766ee8d..34380e6 100644
--- a/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawAcceptDone.swift
+++ b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pAcceptDone.swift
@@ -6,23 +6,20 @@ import SwiftUI
import taler_swift
import SymLog
-struct WithdrawAcceptDone: View {
+struct P2pAcceptDone: View {
private let symLog = SymLogV()
- let navTitle = String(localized: "Confirm with Bank")
+ let navTitle = String(localized: "Received P2P")
- let exchangeBaseUrl: String
- let model: WithdrawModel?
+ let exchangeBaseUrl: String?
let url: URL
+ @EnvironmentObject private var model: WalletModel
+
@State private var confirmTransferUrl: String? = nil
@State private var transaction: Transaction? = nil
func reloadOneAction(_ transactionId: String) async throws -> Transaction {
- if let model {
- return try await model.getTransactionByIdT(transactionId)
- } else {
- throw WalletBackendError.walletCoreError
- }
+ return try await model.getTransactionByIdT(transactionId)
}
var body: some View {
@@ -44,10 +41,10 @@ struct WithdrawAcceptDone: View {
}
}.onAppear() {
symLog.log("onAppear")
- DebugViewC.shared.setSheetID(SHEET_WITHDRAW_CONFIRM)
+ DebugViewC.shared.setSheetID(SHEET_RCV_P2P_ACCEPT)
}.task {
do {
- if let model {
+ if let exchangeBaseUrl {
let result = try await
model.sendAcceptIntWithdrawalM(exchangeBaseUrl, withdrawURL: url.absoluteString)
confirmTransferUrl = result!.confirmTransferUrl
transaction = try await
model.getTransactionByIdT(result!.transactionId)
@@ -59,10 +56,9 @@ struct WithdrawAcceptDone: View {
}
}
// MARK: -
-struct WithdrawAcceptDone_Previews: PreviewProvider {
+struct P2pAcceptDone_Previews: PreviewProvider {
static var previews: some View {
- WithdrawAcceptDone(exchangeBaseUrl: DEMOEXCHANGE,
- model: nil,
+ P2pAcceptDone(exchangeBaseUrl: DEMOEXCHANGE,
url: URL(string: DEMOSHOP)!)
}
}
diff --git a/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift
b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift
new file mode 100644
index 0000000..1b0478a
--- /dev/null
+++ b/TalerWallet1/Views/Sheets/P2P_Sheets/P2pReceiveURIView.swift
@@ -0,0 +1,80 @@
+/*
+ * This file is part of GNU Taler, ©2022-23 Taler Systems S.A.
+ * See LICENSE.md
+ */
+import SwiftUI
+import taler_swift
+import SymLog
+
+// Will be called either by the user scanning a QR code or tapping the
provided link, from another user's SendCoins
+// we show the user the P2P details - but first the ToS must be accepted
+struct P2pReceiveURIView: View {
+ private let symLog = SymLogV()
+ let navTitle = String(localized: "Accept P2P Receive")
+
+ // the URL from the bank website
+ let url: URL
+ @EnvironmentObject private var model: WalletModel
+
+ @State private var peerPushCreditResponse: PreparePeerPushCreditResponse?
+
+ var body: some View {
+ let badURL = "Error in URL: \(url)"
+ VStack {
+ if let peerPushCreditResponse {
+ List {
+ let raw = peerPushCreditResponse.amountRaw
+ let effective = peerPushCreditResponse.amountEffective
+ let currency = raw.currencyStr
+ let fee = try! Amount.diff(raw, effective)
+ let outColor = WalletColors().transactionColor(false)
+ let inColor = WalletColors().transactionColor(true)
+
+ ThreeAmountsView(topTitle: String(localized: "Amount to
receive:"),
+ topAmount: raw, fee: fee,
+ bottomTitle: String(localized: "\(currency)
to be obtained:"),
+ bottomAmount: effective,
+ large: false, pending: false,
incoming: true,
+ baseURL: nil)
+ }
+ .navigationTitle(navTitle)
+ let tosAccepted = true // TODO:
https://bugs.gnunet.org/view.php?id=7869
+ if tosAccepted {
+ NavigationLink(destination: LazyView {
+ P2pAcceptDone(exchangeBaseUrl: nil, url: url)
+ }) {
+ Text("Confirm Withdrawal") //
SHEET_WITHDRAW_ACCEPT
+ }.buttonStyle(TalerButtonStyle(type: .prominent))
+ .padding()
+ } else {
+ NavigationLink(destination: LazyView {
+ WithdrawTOSView(exchangeBaseUrl: nil,
+ viewID: SHEET_RCV_P2P_TOS,
+ acceptAction: nil) // pop
back to here
+ }) {
+ Text("Check Terms of Service")
+ }.buttonStyle(TalerButtonStyle(type: .prominent))
+ .padding()
+ }
+ } else {
+ // Yikes no details or no baseURL
+// WithdrawProgressView(message: url.host ?? badURL)
+// .navigationTitle("Contacting Exchange")
+ }
+ }
+ .onAppear() {
+ symLog.log("onAppear")
+ DebugViewC.shared.setSheetID(SHEET_RCV_P2P)
+ }
+ .task {
+ do { // TODO: cancelled
+ symLog.log(".task")
+ let ppCreditResponse = try await
model.preparePeerPushCreditM(url.absoluteString)
+ peerPushCreditResponse = ppCreditResponse
+ } catch { // TODO: error
+ symLog.log(error.localizedDescription)
+ peerPushCreditResponse = nil
+ }
+ }
+ }
+}
diff --git a/TalerWallet1/Views/Sheets/URLSheet.swift
b/TalerWallet1/Views/Sheets/URLSheet.swift
index 249c138..d58eb4c 100644
--- a/TalerWallet1/Views/Sheets/URLSheet.swift
+++ b/TalerWallet1/Views/Sheets/URLSheet.swift
@@ -15,11 +15,19 @@ struct URLSheet: View {
var body: some View {
Group {
- if urlCommand == .withdraw {
- WithdrawURIView(url: urlToOpen)
- } else if urlCommand == UrlCommand.pay {
- let model = PaymentURIModel.model()
- PaymentURIView(url: urlToOpen, model: model)
+ if let urlCommand {
+ switch urlCommand {
+ case .withdraw:
+ WithdrawURIView(url: urlToOpen)
+ case .pay:
+ PaymentURIView(url: urlToOpen)
+ case .payPull:
+ Text("payPull not implemented yet")
+ case .payPush:
+ P2pReceiveURIView(url: urlToOpen)
+ case .unknown:
+ Text("unknown command")
+ }
} else {
VStack { // Error view
Spacer()
diff --git a/TalerWallet1/Views/Transactions/ThreeAmounts.swift
b/TalerWallet1/Views/Transactions/ThreeAmounts.swift
index 661fcfe..26a4cb3 100644
--- a/TalerWallet1/Views/Transactions/ThreeAmounts.swift
+++ b/TalerWallet1/Views/Transactions/ThreeAmounts.swift
@@ -79,7 +79,7 @@ struct ThreeAmountsView: View {
if let status {
HStack {
Spacer()
- Text("Status: \(status)") // TODO: localize
+ Text("Status: \(status)")
.font(.title2)
}.padding()
}
@@ -103,6 +103,7 @@ struct ThreeAmounts_Previews: PreviewProvider {
Button(String(localized: "Accept"), action: {})
.buttonStyle(TalerButtonStyle(type: .prominent))
.padding(.horizontal)
+ .disabled(true)
}
}
}
diff --git a/TalerWallet1/Views/Transactions/TransactionDetailView.swift
b/TalerWallet1/Views/Transactions/TransactionDetailView.swift
index d9e16c1..f1ea9d8 100644
--- a/TalerWallet1/Views/Transactions/TransactionDetailView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionDetailView.swift
@@ -27,8 +27,9 @@ struct TransactionDetailView: View {
let common = transaction.common
let pending = transaction.isPending
let dateString = TalerDater.dateString(from: common.timestamp)
- let navTitle = (pending ? String(localized: "Pending ") : "") +
"\(common.type)" // TODO: localize type
-
+ let localizedType = transaction.localizedType
+ let navTitle = pending ? String(localized: "Pending \(localizedType)")
+ : localizedType
Group {
List {
Text("\(dateString)")
diff --git a/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawAcceptDone.swift
b/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawAcceptDone.swift
index 766ee8d..e7cf2a1 100644
--- a/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawAcceptDone.swift
+++ b/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawAcceptDone.swift
@@ -10,19 +10,16 @@ struct WithdrawAcceptDone: View {
private let symLog = SymLogV()
let navTitle = String(localized: "Confirm with Bank")
- let exchangeBaseUrl: String
- let model: WithdrawModel?
+ let exchangeBaseUrl: String?
let url: URL
+ @EnvironmentObject private var model: WalletModel
+
@State private var confirmTransferUrl: String? = nil
@State private var transaction: Transaction? = nil
func reloadOneAction(_ transactionId: String) async throws -> Transaction {
- if let model {
return try await model.getTransactionByIdT(transactionId)
- } else {
- throw WalletBackendError.walletCoreError
- }
}
var body: some View {
@@ -47,7 +44,7 @@ struct WithdrawAcceptDone: View {
DebugViewC.shared.setSheetID(SHEET_WITHDRAW_CONFIRM)
}.task {
do {
- if let model {
+ if let exchangeBaseUrl {
let result = try await
model.sendAcceptIntWithdrawalM(exchangeBaseUrl, withdrawURL: url.absoluteString)
confirmTransferUrl = result!.confirmTransferUrl
transaction = try await
model.getTransactionByIdT(result!.transactionId)
@@ -62,7 +59,6 @@ struct WithdrawAcceptDone: View {
struct WithdrawAcceptDone_Previews: PreviewProvider {
static var previews: some View {
WithdrawAcceptDone(exchangeBaseUrl: DEMOEXCHANGE,
- model: nil,
url: URL(string: DEMOSHOP)!)
}
}
diff --git a/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawTOSView.swift
b/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawTOSView.swift
index 4df29c3..f0efbd2 100644
--- a/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawTOSView.swift
+++ b/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawTOSView.swift
@@ -11,8 +11,9 @@ struct WithdrawTOSView: View {
let navTitle = String(localized: "Terms of Service")
- var exchangeBaseUrl: String
- var model: WithdrawModel?
+ var exchangeBaseUrl: String?
+
+ @EnvironmentObject private var model: WalletModel
@State var exchangeTOS: ExchangeTermsOfService?
let viewID: Int // either VIEW_WITHDRAW_TOS or SHEET_WITHDRAW_TOS
@@ -25,7 +26,7 @@ struct WithdrawTOSView: View {
Content(symLog: symLog, exchangeTOS: exchangeTOS, myListStyle:
$myListStyle) {
Task {
do {
- if let model {
+ if let exchangeBaseUrl {
_ = try await
model.setExchangeTOSAcceptedM(exchangeBaseUrl, etag: exchangeTOS!.currentEtag)
if acceptAction != nil {
acceptAction!()
@@ -42,8 +43,14 @@ struct WithdrawTOSView: View {
.navigationTitle(navTitle)
.overlay {
if exchangeTOS == nil {
- WithdrawProgressView(message: exchangeBaseUrl.trimURL())
- .navigationTitle("Loading " + navTitle)
+ if let exchangeBaseUrl {
+ WithdrawProgressView(message:
exchangeBaseUrl.trimURL())
+ .navigationTitle("Loading " + navTitle)
+ } else {
+ // Yikes!
+ WithdrawProgressView(message: "No exchangeBaseUrl!")
+ .navigationTitle("Loading " + navTitle)
+ }
}
}
}.onAppear() {
@@ -54,7 +61,7 @@ struct WithdrawTOSView: View {
}
}.task {
do {
- if let model {
+ if let exchangeBaseUrl {
let someTOS = try await
model.loadExchangeTermsOfServiceM(exchangeBaseUrl)
exchangeTOS = someTOS
}
diff --git a/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawURIView.swift
b/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawURIView.swift
index 6f851ce..85779a7 100644
--- a/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawURIView.swift
+++ b/TalerWallet1/Views/WithdrawBankIntegrated/WithdrawURIView.swift
@@ -16,7 +16,7 @@ struct WithdrawURIView: View {
// the URL from the bank website
let url: URL
- let model = WithdrawModel.model(baseURL: "global") // TODO: get
baseURL from URL
+ @EnvironmentObject private var model: WalletModel
// the exchange used for this withdrawal.
@State private var exchangeBaseUrl: String? = nil
@@ -48,7 +48,7 @@ struct WithdrawURIView: View {
let tosAccepted = manualWithdrawalDetails.tosAccepted
if tosAccepted {
NavigationLink(destination: LazyView {
- WithdrawAcceptDone(exchangeBaseUrl: exchangeBaseUrl,
model: model, url: url)
+ WithdrawAcceptDone(exchangeBaseUrl: exchangeBaseUrl,
url: url)
}) {
Text("Confirm Withdrawal") //
SHEET_WITHDRAW_ACCEPT
}.buttonStyle(TalerButtonStyle(type: .prominent))
@@ -56,7 +56,6 @@ struct WithdrawURIView: View {
} else {
NavigationLink(destination: LazyView {
WithdrawTOSView(exchangeBaseUrl: exchangeBaseUrl,
- model: model,
viewID: SHEET_WITHDRAW_TOS,
acceptAction: nil) // pop
back to here
}) {
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-ios] 11/54: Accessibility, (continued)
- [taler-taler-ios] 11/54: Accessibility, gnunet, 2023/06/30
- [taler-taler-ios] 18/54: remove loaded, gnunet, 2023/06/30
- [taler-taler-ios] 09/54: Launch animation, SideBarView, gnunet, 2023/06/30
- [taler-taler-ios] 01/54: Big update after DD37, gnunet, 2023/06/30
- [taler-taler-ios] 13/54: Overhaul withdraw + p2p, gnunet, 2023/06/30
- [taler-taler-ios] 17/54: for debugging time-outs, gnunet, 2023/06/30
- [taler-taler-ios] 10/54: Reduce Logging, gnunet, 2023/06/30
- [taler-taler-ios] 12/54: Localization, gnunet, 2023/06/30
- [taler-taler-ios] 08/54: Preparations for localization + accessability, gnunet, 2023/06/30
- [taler-taler-ios] 19/54: remove dismissFirst, gnunet, 2023/06/30
- [taler-taler-ios] 14/54: Made Model a Singleton,
gnunet <=
- [taler-taler-ios] 40/54: TransactionType, gnunet, 2023/06/30
- [taler-taler-ios] 26/54: PeerPullDebit, gnunet, 2023/06/30
- [taler-taler-ios] 16/54: Dummy, gnunet, 2023/06/30
- [taler-taler-ios] 34/54: sizeCategory, task, gnunet, 2023/06/30
- [taler-taler-ios] 06/54: Notifications, gnunet, 2023/06/30
- [taler-taler-ios] 42/54: BalanceRow, gnunet, 2023/06/30
- [taler-taler-ios] 15/54: Suspend-Resume, gnunet, 2023/06/30
- [taler-taler-ios] 21/54: Sounds, P2P receive, gnunet, 2023/06/30
- [taler-taler-ios] 07/54: Big Model update, removed unneccessary thread-safety code, gnunet, 2023/06/30
- [taler-taler-ios] 41/54: playSound, gnunet, 2023/06/30