[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-ios] branch master updated (4b4d112 -> 1a6daf7)
From: |
gnunet |
Subject: |
[taler-taler-ios] branch master updated (4b4d112 -> 1a6daf7) |
Date: |
Thu, 19 Dec 2024 23:12:30 +0100 |
This is an automated email from the git hooks/post-receive script.
marc-stibane pushed a change to branch master
in repository taler-ios.
from 4b4d112 Spanish translations
new 2e7d64a fix #9400
new 85bed85 isInternal #9332
new 5654595 cleanup
new 62c1a07 terms for tx
new 8a66280 NavigationModel tosView
new 661b668 ForEachWithIndex
new f33818a A11Y colors + fontsize
new 111c5f5 A11Y VoiceOver dismiss button
new 77cc979 hide tabBar in ToS
new a142dd1 API wording
new a761a68 exportDbToFile
new 790f617 L10N
new 6201f7e withTerms
new b205d06 prepare
new 400a327 loc
new 1d24c5f cleanup
new 642f7c9 L10N
new 1a6daf7 Bump version to 0.14.1 (0.14.1)
The 18 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails. The revisions
listed as "add" were already present in the repository and have only
been added to this reference.
Summary of changes:
TalerWallet.xcodeproj/project.pbxproj | 20 ++++--
.../Assets.xcassets/Error.colorset/Contents.json | 6 +-
TalerWallet1/Backend/WalletCore.swift | 11 +++-
TalerWallet1/Controllers/Controller.swift | 2 +-
TalerWallet1/Controllers/PublicConstants.swift | 2 +
TalerWallet1/Helper/Font+Taler.swift | 2 +
TalerWallet1/Helper/WalletColors.swift | 33 +++++-----
TalerWallet1/Localizable.xcstrings | 74 ++++++++++++++++++++--
TalerWallet1/Model/Model+Deposit.swift | 3 +
TalerWallet1/Model/Model+Withdraw.swift | 2 +-
TalerWallet1/Model/WalletModel.swift | 62 ++++++++++++++----
TalerWallet1/Views/Actions/ActionsSheet.swift | 29 +++++----
.../Views/Actions/Banking/ManualWithdraw.swift | 67 +++++++++++++-------
TalerWallet1/Views/Actions/TwoRowButtons.swift | 3 +-
TalerWallet1/Views/HelperViews/Buttons.swift | 19 +++---
.../HelperViews/ForEachWithIndex.swift} | 18 ++++--
TalerWallet1/Views/HelperViews/SelectDays.swift | 3 +-
TalerWallet1/Views/HelperViews/SubjectInputV.swift | 2 +-
TalerWallet1/Views/HelperViews/TabBarView.swift | 2 +-
.../Views/HelperViews/TransactionButton.swift | 14 ++--
TalerWallet1/Views/HelperViews/View+NavLink.swift | 4 +-
TalerWallet1/Views/Main/MainView.swift | 27 +++-----
TalerWallet1/Views/Main/NavigationModel.swift | 35 ++++++++++
.../Views/Settings/Bank/BankEditView.swift | 8 +--
.../Views/Settings/Exchange/ExchangeListView.swift | 6 +-
.../Views/Settings/Exchange/ExchangeRowView.swift | 28 +++++++-
.../Settings/Exchange/ExchangeSectionView.swift | 9 ++-
TalerWallet1/Views/Settings/SettingsItem.swift | 2 +-
TalerWallet1/Views/Settings/SettingsView.swift | 6 +-
.../WithdrawBankIntegrated/WithdrawTOSView.swift | 3 +-
TalerWallet1/Views/Sheets/WithdrawExchangeV.swift | 5 +-
.../Views/Transactions/TransactionSummaryV.swift | 3 +-
TestFlight/WhatToTest.en-US.txt | 6 ++
33 files changed, 369 insertions(+), 147 deletions(-)
copy TalerWallet1/{Helper/AnyTransition+backslide.swift =>
Views/HelperViews/ForEachWithIndex.swift} (68%)
create mode 100644 TalerWallet1/Views/Main/NavigationModel.swift
diff --git a/TalerWallet.xcodeproj/project.pbxproj
b/TalerWallet.xcodeproj/project.pbxproj
index f7d9eec..f4b954b 100644
--- a/TalerWallet.xcodeproj/project.pbxproj
+++ b/TalerWallet.xcodeproj/project.pbxproj
@@ -312,6 +312,10 @@
4EEC157A29F9427F00D46A03 /* QRSheet.swift in Sources */ = {isa
= PBXBuildFile; fileRef = 4EEC157929F9427F00D46A03 /* QRSheet.swift */; };
4EEC3A712B2285A200D05F9D /* WithdrawExchangeV.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EEC3A702B2285A200D05F9D /*
WithdrawExchangeV.swift */; };
4EEC3A722B2285A200D05F9D /* WithdrawExchangeV.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EEC3A702B2285A200D05F9D /*
WithdrawExchangeV.swift */; };
+ 4EED38552D140C1400F6C038 /* NavigationModel.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EED38542D140C1400F6C038 /*
NavigationModel.swift */; };
+ 4EED38562D140C1400F6C038 /* NavigationModel.swift in Sources */
= {isa = PBXBuildFile; fileRef = 4EED38542D140C1400F6C038 /*
NavigationModel.swift */; };
+ 4EED38582D1485AB00F6C038 /* ForEachWithIndex.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EED38572D1485AB00F6C038 /*
ForEachWithIndex.swift */; };
+ 4EED38592D1485AB00F6C038 /* ForEachWithIndex.swift in Sources
*/ = {isa = PBXBuildFile; fileRef = 4EED38572D1485AB00F6C038 /*
ForEachWithIndex.swift */; };
4EF840A72A0B85F400EE0D47 /* CopyShare.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EF840A62A0B85F400EE0D47 /* CopyShare.swift */;
};
4EFA39602AA7946B00742548 /* ToSButtonView.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EFA395F2AA7946B00742548 /* ToSButtonView.swift
*/; };
4EFA39612AA7946B00742548 /* ToSButtonView.swift in Sources */ =
{isa = PBXBuildFile; fileRef = 4EFA395F2AA7946B00742548 /* ToSButtonView.swift
*/; };
@@ -520,6 +524,8 @@
4EEC157729F9032900D46A03 /* Sheet.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= Sheet.swift; sourceTree = "<group>"; };
4EEC157929F9427F00D46A03 /* QRSheet.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= QRSheet.swift; sourceTree = "<group>"; };
4EEC3A702B2285A200D05F9D /* WithdrawExchangeV.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= WithdrawExchangeV.swift; sourceTree = "<group>"; };
+ 4EED38542D140C1400F6C038 /* NavigationModel.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path =
NavigationModel.swift; sourceTree = "<group>"; };
+ 4EED38572D1485AB00F6C038 /* ForEachWithIndex.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path =
ForEachWithIndex.swift; sourceTree = "<group>"; };
4EF840A62A0B85F400EE0D47 /* CopyShare.swift */ = {isa =
PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path
= CopyShare.swift; sourceTree = "<group>"; };
4EFA395F2AA7946B00742548 /* ToSButtonView.swift */ = {isa =
PBXFileReference; lastKnownFileType = sourcecode.swift; path =
ToSButtonView.swift; sourceTree = "<group>"; };
4EFFDD6A2A501121000C1C6A /* Localizable.xcstrings */ = {isa =
PBXFileReference; lastKnownFileType = text.json.xcstrings; path =
Localizable.xcstrings; sourceTree = "<group>"; };
@@ -861,6 +867,7 @@
isa = PBXGroup;
children = (
4EB095442989CBFE0043A8A1 /* MainView.swift */,
+ 4EED38542D140C1400F6C038 /*
NavigationModel.swift */,
4EB095452989CBFE0043A8A1 /* ErrorView.swift */,
4EB095392989CBFE0043A8A1 /*
WalletEmptyView.swift */,
);
@@ -879,6 +886,7 @@
4EF840A62A0B85F400EE0D47 /* CopyShare.swift */,
4E53A33629F50B7B00830EC2 /* CurrencyField.swift
*/,
4EA551242A2C923600FEC9A8 /*
CurrencyInputView.swift */,
+ 4EED38572D1485AB00F6C038 /*
ForEachWithIndex.swift */,
4E5D2C8A2C574CB0003F7A49 /*
GradientBorder.swift */,
4E0A71172C3AB099002485BB /* IconBadge.swift */,
4EB095432989CBFE0043A8A1 /*
LaunchAnimationView.swift */,
@@ -1236,6 +1244,7 @@
4E3EAE212A990778009F1BE8 /* Buttons.swift in
Sources */,
4E3EAE222A990778009F1BE8 /*
TransactionButton.swift in Sources */,
4EEC118D2B83DE4800146CFF /* AmountInputV.swift
in Sources */,
+ 4EED38582D1485AB00F6C038 /*
ForEachWithIndex.swift in Sources */,
4E77976F2C4BEA4E005D6ECB /* BalanceCellV.swift
in Sources */,
4E3EAE232A990778009F1BE8 /*
BalancesSectionView.swift in Sources */,
4E3EAE242A990778009F1BE8 /*
QRGeneratorView.swift in Sources */,
@@ -1333,6 +1342,7 @@
4E3EAE5F2A990778009F1BE8 /* QRSheet.swift in
Sources */,
4E3EAE602A990778009F1BE8 /*
P2pReceiveURIView.swift in Sources */,
4E3EAE612A990778009F1BE8 /* ListStyle.swift in
Sources */,
+ 4EED38552D140C1400F6C038 /*
NavigationModel.swift in Sources */,
4E3EAE622A990778009F1BE8 /*
TransactionSummaryV.swift in Sources */,
4E3EAE632A990778009F1BE8 /* WalletCore.swift in
Sources */,
4E3EAE642A990778009F1BE8 /*
LaunchAnimationView.swift in Sources */,
@@ -1375,6 +1385,7 @@
4EB0956A2989CBFE0043A8A1 /* Buttons.swift in
Sources */,
4EBA82AB2A3EB2CA00E5F39A /*
TransactionButton.swift in Sources */,
4EEC118E2B83DE4800146CFF /* AmountInputV.swift
in Sources */,
+ 4EED38592D1485AB00F6C038 /*
ForEachWithIndex.swift in Sources */,
4E7797702C4BEA4E005D6ECB /* BalanceCellV.swift
in Sources */,
4EB095602989CBFE0043A8A1 /*
BalancesSectionView.swift in Sources */,
4EEC157329F8242800D46A03 /*
QRGeneratorView.swift in Sources */,
@@ -1472,6 +1483,7 @@
4EEC157A29F9427F00D46A03 /* QRSheet.swift in
Sources */,
4E3B4BC12A41E6C200CC88B8 /*
P2pReceiveURIView.swift in Sources */,
4E6EDD872A363D8D0031D520 /* ListStyle.swift in
Sources */,
+ 4EED38562D140C1400F6C038 /*
NavigationModel.swift in Sources */,
4EB095582989CBFE0043A8A1 /*
TransactionSummaryV.swift in Sources */,
4EB095202989CBCB0043A8A1 /* WalletCore.swift in
Sources */,
4EB095672989CBFE0043A8A1 /*
LaunchAnimationView.swift in Sources */,
@@ -1753,7 +1765,7 @@
CODE_SIGN_ENTITLEMENTS =
"$(TARGET_NAME).entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 0.14.0;
+ CURRENT_PROJECT_VERSION = 0.14.1;
DEVELOPMENT_TEAM = GUDDQ9428Y;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1771,7 +1783,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 0.14.0;
+ MARKETING_VERSION = 0.14.1;
PRODUCT_BUNDLE_IDENTIFIER =
"com.taler-systems.talerwallet-2";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1795,7 +1807,7 @@
CODE_SIGN_ENTITLEMENTS =
"$(TARGET_NAME).entitlements";
CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 0.14.0;
+ CURRENT_PROJECT_VERSION = 0.14.1;
DEVELOPMENT_TEAM = GUDDQ9428Y;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
@@ -1813,7 +1825,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
- MARKETING_VERSION = 0.14.0;
+ MARKETING_VERSION = 0.14.1;
PRODUCT_BUNDLE_IDENTIFIER =
"com.taler-systems.talerwallet-2";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
diff --git a/TalerWallet1/Assets.xcassets/Error.colorset/Contents.json
b/TalerWallet1/Assets.xcassets/Error.colorset/Contents.json
index b09073b..b29ffd3 100644
--- a/TalerWallet1/Assets.xcassets/Error.colorset/Contents.json
+++ b/TalerWallet1/Assets.xcassets/Error.colorset/Contents.json
@@ -23,9 +23,9 @@
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
- "blue" : "36",
- "green" : "52",
- "red" : "234"
+ "blue" : "99",
+ "green" : "99",
+ "red" : "255"
}
},
"idiom" : "universal"
diff --git a/TalerWallet1/Backend/WalletCore.swift
b/TalerWallet1/Backend/WalletCore.swift
index 5dbe9e4..8e8010a 100644
--- a/TalerWallet1/Backend/WalletCore.swift
+++ b/TalerWallet1/Backend/WalletCore.swift
@@ -76,6 +76,8 @@ class WalletCore: QuickjsMessageHandler {
let type: String
let id: String?
let reservePub: String?
+ let isInternal: Bool?
+ let hintTransactionId: String?
let event: [String: AnyCodable]?
}
@@ -324,7 +326,14 @@ extension WalletCore {
try handlePendingProcessed(payload)
case Notification.Name.BalanceChange.rawValue:
symLog.log(message)
- postNotification(.BalanceChange)
+ if !(payload.isInternal ?? false) { // don't re-post
internals
+ if let txID = payload.hintTransactionId {
+ if txID.contains("txn:refresh:") {
+ break
+ }
+ }
+ postNotification(.BalanceChange)
+ }
case Notification.Name.BankAccountChange.rawValue:
symLog.log(message)
postNotification(.BankAccountChange)
diff --git a/TalerWallet1/Controllers/Controller.swift
b/TalerWallet1/Controllers/Controller.swift
index 6a83ee5..499f5ff 100755
--- a/TalerWallet1/Controllers/Controller.swift
+++ b/TalerWallet1/Controllers/Controller.swift
@@ -259,7 +259,7 @@ class Controller: ObservableObject {
if backendState == .instantiated {
backendState = .initing
do {
- let versionInfo = try await model.initWalletCoreT(setTesting:
setTesting)
+ let versionInfo = try await model.initWalletCore(setTesting:
setTesting)
WalletCore.shared.versionInfo = versionInfo
backendState = .ready // dismiss the
launch animation
} catch { // rethrows
diff --git a/TalerWallet1/Controllers/PublicConstants.swift
b/TalerWallet1/Controllers/PublicConstants.swift
index e8589ec..1650361 100644
--- a/TalerWallet1/Controllers/PublicConstants.swift
+++ b/TalerWallet1/Controllers/PublicConstants.swift
@@ -7,6 +7,7 @@
*/
import Foundation
+public let MAXEXCHANGES = 1000 // per currency
public let CHF_4217 = "CHF" // ISO-4217 Swiss Francs
public let EUR_4217 = "EUR" // ISO-4217 Euro
public let HUF_4217 = "HUF" // ISO-4217 Hungarian Forint
@@ -17,6 +18,7 @@ public let DRAGDELAY = 0.5
public let DRAGDURATION = 0.45
public let DRAGSPEED = 0.1
public let MAXRECENT = 4 // # of rows in Recent Transactions
+public let SCANDETENT = 0.999 // instead .large sheet - in the .001
is a VoiceOver dismiss button
public let ICONLEADING = CGFloat(-8)
public let HSPACING = CGFloat(10) // space between items in
HStack
diff --git a/TalerWallet1/Helper/Font+Taler.swift
b/TalerWallet1/Helper/Font+Taler.swift
index 7650a75..fe1075c 100644
--- a/TalerWallet1/Helper/Font+Taler.swift
+++ b/TalerWallet1/Helper/Font+Taler.swift
@@ -172,6 +172,7 @@ extension TalerFont { // old running
static var largeTitle: TalerFont { TalerFont(fontName, size: 34,
relativeTo: .largeTitle) } // 34 -> 38
static var title: TalerFont { TalerFont(fontName, size: 28,
relativeTo: .title) } // 28 -> 31
+ static var title1: TalerFont { TalerFont(fontName, size: 24,
relativeTo: .title2) } // Destructive Buttons
static var title2: TalerFont { TalerFont(fontName, size: 22,
relativeTo: .title2) } // 22 -> 25
static var title3: TalerFont { TalerFont(fontName, size: 20,
relativeTo: .title3) } // 20 -> 23
static var picker: TalerFont { TalerFont(fontName, size: 18,
relativeTo: .body) } // picker uses a different size!
@@ -179,6 +180,7 @@ extension TalerFont { // old running
static var body: TalerFont { TalerFont(fontName, size: 17,
relativeTo: .body) } // 17 -> 19
static var callout: TalerFont { TalerFont(fontName, size: 16,
relativeTo: .callout) } // 16 -> 18
static var subheadline: TalerFont { TalerFont(fontName, size: 15,
relativeTo: .subheadline) } // 15 -> 17
+ static var table: TalerFont { TalerFont(fontName, size: 14,
relativeTo: .subheadline) } // tableview uses a different size!
static var footnote: TalerFont { TalerFont(fontName, size: 13,
relativeTo: .footnote) } // 13 -> 15
static var caption: TalerFont { TalerFont(fontName, size: 12,
relativeTo: .caption) } // 12 -> 13
static var badge: TalerFont { TalerFont(fontName, size: 10,
relativeTo: .caption) } // 12 -> 13
diff --git a/TalerWallet1/Helper/WalletColors.swift
b/TalerWallet1/Helper/WalletColors.swift
index 830169f..6adf932 100644
--- a/TalerWallet1/Helper/WalletColors.swift
+++ b/TalerWallet1/Helper/WalletColors.swift
@@ -9,7 +9,7 @@ fileprivate let grouped = true
public struct WalletColors {
@AppStorage("minimalistic") var minimalistic: Bool = false
- let tint = Color(.tintColor)
+// let tint = Color(.tintColor)
let gray1 = Color(.systemGray) // uncompleted
let gray2 = Color(.systemGray2) // disabled Fore
let gray3 = Color(.systemGray3)
@@ -21,26 +21,26 @@ public struct WalletColors {
let gray8 = grouped ? Color(.secondarySystemGroupedBackground)
: Color(.secondarySystemBackground) // disabled
Back
- let attention = Color.red
- let confirm = Color.yellow
+ let attention = Color.red // TODO: WalletColors().errorColor
+ let confirm = Color.yellow // TODO: WalletColors().warningColor
// TODO: In Japan, negative is blue, and positive is red
let positive = Color.green
let negative = Color.red
- func buttonForeColor(pressed: Bool, disabled: Bool,
- prominent: Bool = false, balance: Bool = false) ->
Color {
- balance ? Color.primary
- : disabled ? gray2
- : !prominent ? tint
- : pressed ? gray6 : gray5
+ func buttonForeColor(pressed: Bool,
+ disabled: Bool,
+ prominent: Bool = false) -> Color {
+ disabled ? gray2
+ : !prominent ? talerColor
+ : pressed ? gray6 : Color.white
}
- func buttonBackColor(pressed: Bool, disabled: Bool,
- prominent: Bool = false, balance: Bool = false) ->
Color {
- balance ? (pressed ? gray5 : gray6)
- : disabled ? gray7
- : prominent ? tint
+ func buttonBackColor(pressed: Bool,
+ disabled: Bool,
+ prominent: Bool = false) -> Color {
+ disabled ? gray7
+ : prominent ? talerColor
: pressed ? gray4 : gray5
}
@@ -90,6 +90,10 @@ public struct WalletColors {
Color("Error")
}
+ var talerColor: Color {
+ Color("Taler")
+ }
+
func pendingColor(_ incoming: Bool) -> Color {
incoming ? Color("PendingIncoming")
: Color("PendingOutgoing")
@@ -99,5 +103,4 @@ public struct WalletColors {
incoming ? Color("Incoming")
: Color("Outgoing")
}
-
}
diff --git a/TalerWallet1/Localizable.xcstrings
b/TalerWallet1/Localizable.xcstrings
index 55767fd..9faa69a 100755
--- a/TalerWallet1/Localizable.xcstrings
+++ b/TalerWallet1/Localizable.xcstrings
@@ -525,6 +525,12 @@
"state" : "translated",
"value" : "%@"
}
+ },
+ "es" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@"
+ }
}
}
},
@@ -558,6 +564,12 @@
"state" : "translated",
"value" : "%@:"
}
+ },
+ "es" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%@:"
+ }
}
}
},
@@ -723,7 +735,7 @@
}
},
"%llu Days" : {
- "comment" : "30 Days, always plural (10..30), 4 letters max., abbreviate
if longer\n7 Days, always plural (3..9), 4 letters max., abbreviate if longer",
+ "comment" : "7 Days, always plural (3..9), 4 letters max., abbreviate if
longer",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -1353,7 +1365,7 @@
}
},
"Add bank account" : {
- "comment" : "VoiceOver for the + button\ntitle of the addExchange alert",
+ "comment" : "VoiceOver for the + button",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -1370,7 +1382,7 @@
}
},
"Add payment service" : {
- "comment" : "VoiceOver for the + button\ntitle of the addExchange alert",
+ "comment" : "VoiceOver for the + button",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -1939,7 +1951,7 @@
},
"es" : {
"stringUnit" : {
- "state" : "needs_review",
+ "state" : "translated",
"value" : "Confirmar ahora"
}
},
@@ -2820,6 +2832,12 @@
"state" : "translated",
"value" : "Demo-Hinweise"
}
+ },
+ "es" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Pistas de demostración"
+ }
}
}
},
@@ -2846,7 +2864,7 @@
}
},
"Deposit" : {
- "comment" : "RefreshReason\nTransactionType",
+ "comment" : "TransactionType",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -5795,6 +5813,12 @@
"state" : "translated",
"value" : "Einführung"
}
+ },
+ "es" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Incorporación"
+ }
}
}
},
@@ -6889,7 +6913,7 @@
}
},
"Recoup" : {
- "comment" : "RefreshReason\nTransactionType",
+ "comment" : "TransactionType",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -6958,7 +6982,7 @@
}
},
"Refund" : {
- "comment" : "RefreshReason\nTransactionType",
+ "comment" : "TransactionType",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -7822,6 +7846,12 @@
"state" : "translated",
"value" : "Demo-Hinweise anzeigen"
}
+ },
+ "es" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Mostrar pistas para dinero de demostración"
+ }
}
}
},
@@ -8469,6 +8499,30 @@
}
}
},
+ "thirtyDays" : {
+ "comment" : "30 Days, always plural (10..30), 4 letters max., abbreviate
if longer",
+ "extractionState" : "extracted_with_value",
+ "localizations" : {
+ "de" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%llu Tage"
+ }
+ },
+ "en" : {
+ "stringUnit" : {
+ "state" : "new",
+ "value" : "%llu Days"
+ }
+ },
+ "es" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "%llu días"
+ }
+ }
+ }
+ },
"This is mandatory, otherwise your money will not arrive in this wallet."
: {
"localizations" : {
"de" : {
@@ -9398,6 +9452,12 @@
"state" : "translated",
"value" : "Unbekannter Zahlungsdienst"
}
+ },
+ "es" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Servicio de pago desconocido"
+ }
}
}
},
diff --git a/TalerWallet1/Model/Model+Deposit.swift
b/TalerWallet1/Model/Model+Deposit.swift
index 444b98c..b5c54d5 100644
--- a/TalerWallet1/Model/Model+Deposit.swift
+++ b/TalerWallet1/Model/Model+Deposit.swift
@@ -121,6 +121,9 @@ struct CheckDepositResponse: Codable {
let totalDepositCost: Amount
let effectiveDepositAmount: Amount
let fees: DepositFees
+ let kycSoftLimit: Amount?
+ let kycHardLimit: Amount?
+ let kycExchanges: [String]? // Base URL of exchanges that
would likely require soft KYC
}
/// A request to get an exchange's deposit contract terms.
fileprivate struct CheckDeposit: WalletBackendFormattedRequest {
diff --git a/TalerWallet1/Model/Model+Withdraw.swift
b/TalerWallet1/Model/Model+Withdraw.swift
index 34c9a52..7e88add 100644
--- a/TalerWallet1/Model/Model+Withdraw.swift
+++ b/TalerWallet1/Model/Model+Withdraw.swift
@@ -235,7 +235,7 @@ fileprivate struct GetQrCodesForPayto:
WalletBackendFormattedRequest {
// MARK: -
extension WalletModel {
/// load withdraw-exchange details. Networking involved
- nonisolated func loadWithdrawalExchangeForUri(_ talerUri: String,
+ nonisolated func prepareWithdrawExchange(_ talerUri: String,
viewHandles: Bool = false)
async throws -> WithdrawExchangeResponse {
let request = PrepareWithdrawExchange(talerUri: talerUri)
diff --git a/TalerWallet1/Model/WalletModel.swift
b/TalerWallet1/Model/WalletModel.swift
index 091c6cb..0aac3e1 100644
--- a/TalerWallet1/Model/WalletModel.swift
+++ b/TalerWallet1/Model/WalletModel.swift
@@ -98,20 +98,22 @@ extension WalletModel {
fileprivate struct GetTransactionById: WalletBackendFormattedRequest {
typealias Response = Transaction
func operation() -> String { "getTransactionById" }
- func args() -> Args { Args(transactionId: transactionId) }
+ func args() -> Args { Args(transactionId: transactionId,
includeContractTerms: withTerms) }
var transactionId: String
+ var withTerms: Bool?
struct Args: Encodable {
var transactionId: String
+ var includeContractTerms: Bool?
}
}
extension WalletModel {
/// get the specified transaction from Wallet-Core. No networking involved
- nonisolated func getTransactionById(_ transactionId: String, viewHandles:
Bool = false)
+ nonisolated func getTransactionById(_ transactionId: String, withTerms:
Bool? = nil, viewHandles: Bool = false)
async throws -> Transaction {
- let request = GetTransactionById(transactionId: transactionId)
+ let request = GetTransactionById(transactionId: transactionId,
withTerms: withTerms)
return try await sendRequest(request, ASYNCDELAY, viewHandles:
viewHandles)
}
}
@@ -177,8 +179,7 @@ fileprivate struct ConfigRequest:
WalletBackendFormattedRequest {
extension WalletModel {
/// initalize Wallet-Core. Will do networking
- func setConfigT(setTesting: Bool) async throws -> VersionInfo {
- // T for any Thread
+ nonisolated func setConfig(setTesting: Bool) async throws -> VersionInfo {
let request = ConfigRequest(setTesting: setTesting)
let response = try await sendRequest(request, 0) // no Delay
return response.versionInfo
@@ -216,8 +217,7 @@ fileprivate struct InitRequest:
WalletBackendFormattedRequest {
extension WalletModel {
/// initalize Wallet-Core. Might do networking
- func initWalletCoreT(setTesting: Bool, viewHandles: Bool = false) async
throws -> VersionInfo {
- // T for any Thread
+ nonisolated func initWalletCore(setTesting: Bool, viewHandles: Bool =
false) async throws -> VersionInfo {
let dbPath = try dbPath()
// logger.debug("dbPath: \(dbPath)")
let request = InitRequest(persistentStoragePath: dbPath, setTesting:
setTesting)
@@ -285,12 +285,16 @@ extension WalletModel {
}
}
- private func dbPath () throws -> String {
+ private func dbPath(_ export:Bool = false) throws -> String {
if #available(iOS 16.0, *) {
let documents = URL.documentsDirectory
// accessible by FileSharing
+ let docsPath = documents.path(percentEncoded: false)
+ if export {
+ return docsPath
+ }
let appSupport = URL.applicationSupportDirectory
#if DEBUG || GNU_TALER
- return documents.path(percentEncoded: false)
+ return docsPath
#else // TALER_WALLET
migrate(from: documents, to: appSupport)
return appSupport.path(percentEncoded: false)
@@ -300,6 +304,9 @@ extension WalletModel {
let appDirNr: FileManager.SearchPathDirectory =
.applicationSupportDirectory
if let documentsDir = FileManager.default.urls(for: docDirNr, in:
.userDomainMask).first,
let appSupportDir = FileManager.default.urls(for: appDirNr, in:
.userDomainMask).first {
+ if export {
+ return path(documentsDir)
+ }
#if DEBUG || GNU_TALER
return path(documentsDir)
#else
@@ -313,7 +320,7 @@ extension WalletModel {
}
}
- private func cachePath () throws -> String {
+ private func cachePath() throws -> String {
let fileManager = FileManager.default
if let cachesURL = fileManager.urls(for: .cachesDirectory, in:
.userDomainMask).first {
let cacheURL = cachesURL.appendingPathComponent("cache.json")
@@ -347,13 +354,42 @@ fileprivate struct ResetRequest:
WalletBackendFormattedRequest {
extension WalletModel {
/// reset Wallet-Core
- func resetWalletCoreT(viewHandles: Bool = false) async throws {
- // T for any Thread
+ nonisolated func resetWalletCore(viewHandles: Bool = false) async throws {
let request = ResetRequest()
_ = try await sendRequest(request, 0, viewHandles: viewHandles)
}
}
// MARK: -
+fileprivate struct ExportDbToFile: WalletBackendFormattedRequest {
+ func operation() -> String { "exportDbToFile" }
+ func args() -> Args { Args(directory: directory, stem: stem) }
+
+ var directory: String
+ var stem: String
+ struct Args: Encodable {
+ var directory: String
+ var stem: String
+ } // no arguments needed
+ struct Response: Decodable, Sendable { // path of the copied
DB
+ var path: String
+ }
+}
+
+extension WalletModel {
+ /// export DB
+ nonisolated func exportDbToFile(viewHandles: Bool = false)
+ async throws -> String? {
+ if let dbPath = try? dbPath(true) {
+ let stem = String("Taler " + TalerDater.dateString())
+ let request = ExportDbToFile(directory: dbPath, stem: stem)
+ let response = try await sendRequest(request, 0, viewHandles:
viewHandles)
+ return response.path
+ } else {
+ return nil
+ }
+ }
+}
+// MARK: -
fileprivate struct DevExperimentRequest: WalletBackendFormattedRequest {
func operation() -> String { "applyDevExperiment" }
func args() -> Args { Args(devExperimentUri: talerUri) }
@@ -368,7 +404,7 @@ fileprivate struct DevExperimentRequest:
WalletBackendFormattedRequest {
extension WalletModel {
/// tell wallet-core to mock new transactions
- func devExperimentT(talerUri: String, viewHandles: Bool = false) async
throws {
+ nonisolated func devExperimentT(talerUri: String, viewHandles: Bool =
false) async throws {
// T for any Thread
let request = DevExperimentRequest(talerUri: talerUri)
_ = try await sendRequest(request, 0, viewHandles: viewHandles)
diff --git a/TalerWallet1/Views/Actions/ActionsSheet.swift
b/TalerWallet1/Views/Actions/ActionsSheet.swift
index 094d0de..9786de6 100644
--- a/TalerWallet1/Views/Actions/ActionsSheet.swift
+++ b/TalerWallet1/Views/Actions/ActionsSheet.swift
@@ -65,7 +65,8 @@ struct ActionsSheet: View {
}
Button(action: shopAction) {
HStack {
- ButtonIconBadge(type: .payment, foreColor:
.accentColor, done: false)
+ let talerColor = WalletColors().talerColor
+ ButtonIconBadge(type: .payment, foreColor: talerColor,
done: false)
Spacer()
Text(title)
Spacer()
@@ -96,11 +97,13 @@ struct DualHeightSheet: View {
@Binding var qrButtonTapped: Bool
let logger = Logger(subsystem: "net.taler.gnu", category: "DualSheet")
-// @State private var sheetHeight: CGFloat = .zero
- @State private var selectedDetent: PresentationDetent = .fraction(0.1)
+ @Environment(\.colorScheme) private var colorScheme
+ @Environment(\.colorSchemeContrast) private var colorSchemeContrast
+ let scanDetent: PresentationDetent = .fraction(SCANDETENT)
+// @State private var selectedDetent: PresentationDetent = scanDetent
// Cannot use instance member 'scanDetent' within property initializer
+ @State private var selectedDetent: PresentationDetent = .fraction(0.1)
// workaround - update in .task
+// @State private var detents: Set<PresentationDetent> = [scanDetent]
@State private var detents: Set<PresentationDetent> = [.fraction(0.1)]
-// @State private var selectedDetent: PresentationDetent = .large
-// @State private var detents: Set<PresentationDetent> = [.large]
@State private var qrButtonTapped2: Bool = false
@State private var innerHeight: CGFloat = .zero
@State private var sheetHeight: CGFloat = .zero
@@ -109,18 +112,20 @@ struct DualHeightSheet: View {
Task {
//(1 second = 1_000_000_000 nanoseconds)
try? await Task.sleep(nanoseconds: 80_000_000)
- guard selectedDetent == .large else { return }
- detents = [.large]
+ guard selectedDetent == scanDetent else { return }
+ detents = [scanDetent]
}
}
var body: some View {
ScrollView {
+ let background = colorScheme == .dark ? WalletColors().gray6
+ : WalletColors().gray2
ActionsSheet(stack: stack.push(),
qrButtonTapped: $qrButtonTapped2)
.presentationDragIndicator(.hidden)
.presentationBackground {
- WalletColors().gray2
+ background
/// overflow the bottom of the screen by a sufficient amount
to fill the gap that is seen when the size changes
.padding(.bottom, -1000)
}
@@ -132,7 +137,7 @@ struct DualHeightSheet: View {
qrButtonTapped = true // tell our caller
withAnimation(Animation.easeIn(duration: 0.6)) {
// animate this sheet to full height
- selectedDetent = .large
+ selectedDetent = scanDetent
}
}
}
@@ -152,13 +157,13 @@ struct DualHeightSheet: View {
}
.presentationDetents(detents, selection: $selectedDetent)
.onChange(of: selectedDetent) { newValue in
- if newValue == .large {
- logger.trace("onChange❗️selectedDetent = .large)")
+ if newValue == scanDetent {
+ logger.trace("onChange❗️selectedDetent = \(SCANDETENT)")
updateDetentsWithDelay()
qrButtonTapped = true // tell our caller
} else {
logger.trace("onChange❗️selectedDetent =
.height(\(sheetHeight))")
- detents = [.large, .height(sheetHeight)]
+ detents = [scanDetent, .height(sheetHeight)]
}
}
.task {
diff --git a/TalerWallet1/Views/Actions/Banking/ManualWithdraw.swift
b/TalerWallet1/Views/Actions/Banking/ManualWithdraw.swift
index e430010..eb543cf 100644
--- a/TalerWallet1/Views/Actions/Banking/ManualWithdraw.swift
+++ b/TalerWallet1/Views/Actions/Banking/ManualWithdraw.swift
@@ -16,6 +16,8 @@ struct ManualWithdraw: View {
let stack: CallStack
@Binding var selectedBalance: Balance?
@Binding var amountLastUsed: Amount
+ @Binding var amountToTransfer: Amount
+ @Binding var exchange: Exchange? // only for withdraw-exchange
let isSheet: Bool
@EnvironmentObject private var controller: Controller
@@ -23,10 +25,13 @@ struct ManualWithdraw: View {
@State private var balanceIndex = 0
@State private var balance: Balance? = nil // nil only when balances
== []
@State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN)
- @State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
+// @State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
private func viewDidLoad() async {
- if let selectedBalance {
+ if let exchange {
+ currencyInfo = controller.info(for: exchange.scopeInfo,
controller.currencyTicker)
+ return
+ } else if let selectedBalance {
balance = selectedBalance
balanceIndex = controller.balances.firstIndex(of: selectedBalance)
?? 0
} else {
@@ -56,20 +61,29 @@ struct ManualWithdraw: View {
let count = controller.balances.count
let _ = symLog.log("count = \(count)")
let scrollView = ScrollView {
- if count > 0 {
- ScopePicker(value: $balanceIndex, onlyNonZero: false)
- { index in
- balanceIndex = index
- balance = controller.balances[index]
- }
- .padding(.horizontal)
- .padding(.bottom, 4)
- }
- if let balance {
+ if let exchange {
ManualWithdrawContent(stack: stack.push(),
- scope: balance.scopeInfo,
+ scope: exchange.scopeInfo,
amountLastUsed: $amountLastUsed,
- amountToTransfer: $amountToTransfer)
+ amountToTransfer: $amountToTransfer,
+ exchange: $exchange)
+ } else {
+ if count > 0 {
+ ScopePicker(value: $balanceIndex, onlyNonZero: false)
+ { index in
+ balanceIndex = index
+ balance = controller.balances[index]
+ }
+ .padding(.horizontal)
+ .padding(.bottom, 4)
+ }
+ if let balance {
+ ManualWithdrawContent(stack: stack.push(),
+ scope: balance.scopeInfo,
+ amountLastUsed: $amountLastUsed,
+ amountToTransfer: $amountToTransfer,
+ exchange: $exchange)
+ }
}
} // ScrollView
.navigationTitle(navTitle)
@@ -91,7 +105,11 @@ struct ManualWithdraw: View {
.task(id: balanceIndex + (1000 * controller.currencyTicker)) {
// runs whenever the user changes the exchange via
ScopePicker, or on new currencyInfo
symLog.log("❗️ task \(balanceIndex)")
- if let balance {
+ if let exchange {
+ let scopeInfo = exchange.scopeInfo
+ amountToTransfer.setCurrency(scopeInfo.currency)
+ currencyInfo = controller.info(for: scopeInfo,
controller.currencyTicker)
+ } else if let balance {
let scopeInfo = balance.scopeInfo
amountToTransfer.setCurrency(scopeInfo.currency)
currencyInfo = controller.info(for: scopeInfo,
controller.currencyTicker)
@@ -117,6 +135,7 @@ struct ManualWithdrawContent: View {
let scope: ScopeInfo
@Binding var amountLastUsed: Amount
@Binding var amountToTransfer: Amount
+ @Binding var exchange: Exchange?
@EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
@@ -126,10 +145,6 @@ struct ManualWithdrawContent: View {
// @State var ageMenuList: [Int] = []
// @State var selectedAge = 0
- @State private var exchanges: [Exchange] = []
- @State private var exchange: Exchange? = nil
-
-
private func exchangeVia(_ baseURL: String?) -> String? {
if let baseURL {
return String(localized: "via \(baseURL.trimURL)", comment:
"currency/exchange chooser")
@@ -161,6 +176,13 @@ struct ManualWithdrawContent: View {
return nil
} // computeFee
+ @MainActor
+ private func reloadExchange(_ baseURL: String) async {
+ if exchange == nil || exchange?.tosStatus != .accepted {
+ symLog.log("getExchangeByUrl(\(baseURL))")
+ exchange = try? await model.getExchangeByUrl(url: baseURL)
+ }
+ }
@MainActor
private func viewDidLoad2() async {
// neues scope wenn balance geändert wird?
@@ -168,10 +190,6 @@ struct ManualWithdrawContent: View {
viewHandles: true)
if let details {
detailsForAmount = details
- if exchange == nil || exchange?.tosStatus != .accepted {
- symLog.log("getExchangeByUrl(\(details.exchangeBaseUrl))")
- exchange = try? await model.getExchangeByUrl(url:
details.exchangeBaseUrl)
- }
}
}
@@ -243,7 +261,8 @@ struct ManualWithdrawContent: View {
.padding(.top)
}
} // Group
- .padding(.horizontal)
+ .padding(.horizontal)
+ .task { await reloadExchange(detailsForAmount.exchangeBaseUrl)
}
} else {
LoadingView(scopeInfo: scope, message: nil)
.task { await viewDidLoad2() }
diff --git a/TalerWallet1/Views/Actions/TwoRowButtons.swift
b/TalerWallet1/Views/Actions/TwoRowButtons.swift
index 3506d1d..7b7ad69 100644
--- a/TalerWallet1/Views/Actions/TwoRowButtons.swift
+++ b/TalerWallet1/Views/Actions/TwoRowButtons.swift
@@ -34,7 +34,8 @@ struct TypeButton: View {
let blue = debug ? Color.blue : Color.clear
let orange = debug ? Color.orange : Color.clear
#endif
- let badge = ButtonIconBadge(type: type, foreColor: .accentColor, done:
false)
+ let talerColor = WalletColors().talerColor
+ let badge = ButtonIconBadge(type: type, foreColor: talerColor, done:
false)
let hLayout = HStack {
badge
Spacer()
diff --git a/TalerWallet1/Views/HelperViews/Buttons.swift
b/TalerWallet1/Views/HelperViews/Buttons.swift
index f4c085d..34950e6 100644
--- a/TalerWallet1/Views/HelperViews/Buttons.swift
+++ b/TalerWallet1/Views/HelperViews/Buttons.swift
@@ -108,23 +108,23 @@ struct QRButton : View {
showCameraAlert = false
}
let scanText = String(localized: "Scan QR code", comment: "Button
title, a11y")
- let qr = "qrcode.viewfinder"
- let qrImage = Text("\(Image(systemName: qr))", comment: "QR Image")
+ let qrImage = Image(systemName: QRBUTTON)
+ let qrText = Text("\(qrImage)", comment: "QR Image")
Button(action: checkCameraAvailable) {
if isNavBarItem {
if !minimalistic {
Text("Scan QR", comment: "Button title")
.talerFont(.title3)
}
- qrImage.talerFont(.title2)
+ qrText.talerFont(.title2)
} else if minimalistic {
let width = UIScreen.screenWidth / 7
- qrImage.talerFont(.largeTitle)
+ qrText.talerFont(.largeTitle)
.padding(.horizontal, width)
// .padding(.vertical)
} else {
HStack(spacing: 16) {
- qrImage.talerFont(.title)
+ qrText.talerFont(.title)
Text(scanText)
}.padding(.horizontal)
}
@@ -192,7 +192,6 @@ struct ReloadButton : View {
struct TalerButtonStyle: ButtonStyle {
enum TalerButtonStyleType {
case plain
- case balance
case bordered
case prominent
}
@@ -221,8 +220,7 @@ struct TalerButtonStyle: ButtonStyle {
}
return WalletColors().buttonForeColor(pressed: pressed,
disabled: disabled,
- prominent: type == .prominent,
- balance: type == .balance)
+ prominent: type == .prominent)
}
func backColor(type: TalerButtonStyleType, pressed: Bool, disabled: Bool)
-> Color {
if type == .plain && !pressed {
@@ -230,8 +228,7 @@ struct TalerButtonStyle: ButtonStyle {
}
return WalletColors().buttonBackColor(pressed: pressed,
disabled: disabled,
- prominent: type == .prominent,
- balance: type == .balance)
+ prominent: type == .prominent)
}
struct BackgroundView: View {
@@ -297,7 +294,7 @@ fileprivate struct ContentView_Previews: PreviewProvider {
static var previews: some View {
let testButtonTitle = String("Placeholder")
Button(testButtonTitle) {}
- .buttonStyle(TalerButtonStyle(type: .balance, aligned: .trailing))
+ .buttonStyle(TalerButtonStyle(type: .bordered, aligned: .trailing))
}
}
#endif
diff --git a/TalerWallet1/Helper/AnyTransition+backslide.swift
b/TalerWallet1/Views/HelperViews/ForEachWithIndex.swift
similarity index 68%
copy from TalerWallet1/Helper/AnyTransition+backslide.swift
copy to TalerWallet1/Views/HelperViews/ForEachWithIndex.swift
index 3cd1d81..1eb5dfd 100644
--- a/TalerWallet1/Helper/AnyTransition+backslide.swift
+++ b/TalerWallet1/Views/HelperViews/ForEachWithIndex.swift
@@ -1,5 +1,6 @@
/* MIT License
- * Copyright (c) 2021 noranraskin
+ * Copyright (c) 2021 Khoa aka onmyway133
+ * https://onmyway133.com/posts/how-to-use-foreach-with-indices-in-swiftui/
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
deal
@@ -19,12 +20,17 @@
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE
* SOFTWARE.
*/
+
import SwiftUI
-extension AnyTransition {
- static var backslide: AnyTransition {
- AnyTransition.asymmetric(
- insertion: .move(edge: .trailing),
- removal: .move(edge: .leading))
+struct ForEachWithIndex<Data: RandomAccessCollection, Content: View>: View
+ where Data.Element: Identifiable, Data.Element: Hashable {
+ let data: Data
+ @ViewBuilder let content: (Data.Index, Data.Element) -> Content
+
+ var body: some View {
+ ForEach(Array(zip(data.indices, data)), id: \.1) { index, element in
+ content(index, element)
+ }
}
}
diff --git a/TalerWallet1/Views/HelperViews/SelectDays.swift
b/TalerWallet1/Views/HelperViews/SelectDays.swift
index 633c750..6b5fa8f 100644
--- a/TalerWallet1/Views/HelperViews/SelectDays.swift
+++ b/TalerWallet1/Views/HelperViews/SelectDays.swift
@@ -69,7 +69,8 @@ struct SelectDays: View {
if developerMode {
Text(verbatim: "1 Day")
} else {
- Text("\(THIRTYDAYS) Days", comment: "30 Days, always
plural (10..30), 4 letters max., abbreviate if longer")
+ let thirtyDays = String(localized: "thirtyDays",
defaultValue: "\(THIRTYDAYS) Days", comment: "30 Days, always plural (10..30),
4 letters max., abbreviate if longer")
+ Text(thirtyDays)
}
}.buttonStyle(TalerButtonStyle(type: (selected == THIRTYDAYS)
? .prominent : .bordered, dimmed: true,
disabled: !isEnabled ||
maxExpiration < THIRTYDAYS))
diff --git a/TalerWallet1/Views/HelperViews/SubjectInputV.swift
b/TalerWallet1/Views/HelperViews/SubjectInputV.swift
index c5c306a..376f0ba 100644
--- a/TalerWallet1/Views/HelperViews/SubjectInputV.swift
+++ b/TalerWallet1/Views/HelperViews/SubjectInputV.swift
@@ -88,7 +88,7 @@ struct SubjectInputV<TargetView: View>: View {
//// Text(feeLabel)
// }
// .talerFont(.body)
-//// .foregroundColor(insufficient ? .red :
WalletColors().secondary(colorScheme, colorSchemeContrast))
+// // .foregroundColor(insufficient ? WalletColors().errorColor
: WalletColors().secondary(colorScheme, colorSchemeContrast))
// .foregroundColor(WalletColors().secondary(colorScheme,
colorSchemeContrast))
//// .accessibility(sortPriority: 1)
// .padding(4)
diff --git a/TalerWallet1/Views/HelperViews/TabBarView.swift
b/TalerWallet1/Views/HelperViews/TabBarView.swift
index f1d4392..178c08f 100644
--- a/TalerWallet1/Views/HelperViews/TabBarView.swift
+++ b/TalerWallet1/Views/HelperViews/TabBarView.swift
@@ -93,7 +93,7 @@ struct TabBarView: View {
}
}
}.id(tab)
- .foregroundColor(selection == tab ? .accentColor : .secondary)
+ .foregroundColor(selection == tab ? WalletColors().talerColor :
.secondary)
.padding(.vertical, 8)
.accessibilityElement(children: .combine)
.accessibility(label: Text(tab.title))
diff --git a/TalerWallet1/Views/HelperViews/TransactionButton.swift
b/TalerWallet1/Views/HelperViews/TransactionButton.swift
index 21c8837..d54fa34 100755
--- a/TalerWallet1/Views/HelperViews/TransactionButton.swift
+++ b/TalerWallet1/Views/HelperViews/TransactionButton.swift
@@ -21,7 +21,7 @@ struct WarningButton: View {
@State private var showAlert: Bool = false
var body: some View {
- Button(role: role,
+ Button(//role: role,
action: {
if !disabled {
if shouldShowWarning && (role == .destructive || role ==
.cancel) {
@@ -31,15 +31,17 @@ struct WarningButton: View {
}
}
}) {
- HStack(spacing: 50) {
- Text(buttonTitle)
+ HStack(spacing: 20) {
if let buttonIcon {
Image(systemName: buttonIcon)
}
+ Text(buttonTitle)
}
.frame(maxWidth: .infinity)
+ .foregroundColor(role == .destructive ? WalletColors().errorColor
+ : WalletColors().talerColor)
}
- .talerFont(.title2)
+ .talerFont(.title1)
.buttonStyle(.bordered)
.controlSize(.large)
.disabled(disabled)
@@ -88,9 +90,9 @@ struct TransactionButton: View {
let buttonTitle = executed ? command.localizedActionExecuted
: command.localizedActionTitle
WarningButton(warningText: warning,
- buttonTitle: command.localizedActionTitle,
+ buttonTitle: buttonTitle,
buttonIcon: command.localizedActionImage,
- role: role,
+ role: role,
// TODO: WalletColors().errorColor
disabled: $disabled,
action: doAction)
}
diff --git a/TalerWallet1/Views/HelperViews/View+NavLink.swift
b/TalerWallet1/Views/HelperViews/View+NavLink.swift
index 54bc7a6..e453a42 100644
--- a/TalerWallet1/Views/HelperViews/View+NavLink.swift
+++ b/TalerWallet1/Views/HelperViews/View+NavLink.swift
@@ -48,10 +48,10 @@ struct NavLink <Content : View> : View {
}
var body: some View {
- if tag != 0 {
+ if tag != 0 { // actions: $navModel.actionSelected will hide the
tabBar
NavigationLink(destination: content, tag: tag, selection:
$selection)
{ EmptyView() }.frame(width: 0).opacity(0).hidden()
- } else {
+ } else { // shortcuts, AddButton
NavigationLink(destination: content, isActive: $isActive)
{ EmptyView() }.frame(width: 0).opacity(0).hidden()
}
diff --git a/TalerWallet1/Views/Main/MainView.swift
b/TalerWallet1/Views/Main/MainView.swift
index 01364fa..68b342e 100644
--- a/TalerWallet1/Views/Main/MainView.swift
+++ b/TalerWallet1/Views/Main/MainView.swift
@@ -117,10 +117,11 @@ struct MainView: View {
) {
let qrSheet = AnyView(QRSheet(stack: stack.push(".sheet"),
selectedBalance: $selectedBalance))
- let _ = logger.trace("❗️showScanner: .large❗️")
+ let _ = logger.trace("❗️showScanner: \(SCANDETENT)❗️")
if #available(iOS 16.4, *) {
+ let scanDetent: PresentationDetent = .fraction(SCANDETENT)
Sheet(stack: stack.push(), sheetView: qrSheet)
- .presentationDetents([.large])
+ .presentationDetents([scanDetent])
.transition(.opacity)
} else {
Sheet(stack: stack.push(), sheetView: qrSheet)
@@ -201,19 +202,6 @@ extension Label where Title == Text, Icon == Image {
// MARK: - Content
extension MainView {
- class NavigationModel: ObservableObject {
- @Published var tabBarHidden = 0
-
- @Published var actionSelected: Int? = nil {
- didSet {
- if actionSelected != nil {
- tabBarHidden += 1
- } else {
- tabBarHidden = 0
- }
- }
- }
- }
struct MainContent: View {
let logger: Logger
@@ -247,7 +235,7 @@ extension MainView {
@State private var amountToTransfer = Amount.zero(currency:
EMPTYSTRING) // Update currency when used
@State private var amountLastUsed = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
@State private var summary: String = EMPTYSTRING
- @State private var myExchange: Exchange? = nil
+ @State private var exchange: Exchange? = nil
private var openKycButton: some View {
Button("KYC") {
@@ -328,9 +316,11 @@ extension MainView {
let manualWithdrawDest = ManualWithdraw(stack:
stack.push(Self.name),
selectedBalance: $selectedBalance,
amountLastUsed: $amountLastUsed,
// currency needs to be updated!
+ amountToTransfer: $amountToTransfer,
+ exchange: $exchange,
// only for withdraw-exchange
isSheet: false)
/// each NavigationView needs its own NavLinks
- let balanceActions = Group {
+ let balanceActions = Group {
// actionSelected will hide the tabBar
NavLink(1, $navModel.actionSelected) { sendDest }
NavLink(2, $navModel.actionSelected) { requestDest }
NavLink(3, $navModel.actionSelected) { depositDest }
@@ -363,7 +353,7 @@ extension MainView {
}.navigationViewStyle(.stack)
let settingsStack = NavigationView {
SettingsView(stack: stack.push(),
- navTitle: settingsTitle)
+ navTitle: settingsTitle)
.background(settingsActions)
}.navigationViewStyle(.stack)
/// our custom tabBar with the Actions button in the middle
@@ -392,6 +382,7 @@ extension MainView {
.ignoresSafeArea(.keyboard, edges: .bottom)
.accessibilityHidden(true) // for a11y we
use the original tabBar, not our custom one
} // ZStack
+ .environmentObject(navModel)
.frame(maxWidth: .infinity, maxHeight: .infinity)
.onNotification(.SendAction) { triggerAction(1) }
.onNotification(.RequestAction) { triggerAction(2) }
diff --git a/TalerWallet1/Views/Main/NavigationModel.swift
b/TalerWallet1/Views/Main/NavigationModel.swift
new file mode 100644
index 0000000..bdb48a0
--- /dev/null
+++ b/TalerWallet1/Views/Main/NavigationModel.swift
@@ -0,0 +1,35 @@
+/*
+ * This file is part of GNU Taler, ©2022-24 Taler Systems S.A.
+ * See LICENSE.md
+ */
+/**
+ * Controller
+ *
+ * @author Marc Stibane
+ */
+import Foundation
+import SwiftUI
+
+class NavigationModel: ObservableObject {
+ @Published var tabBarHidden = 0
+
+ @Published var tosView: Int? = nil {
+ didSet {
+ if tosView != nil {
+ tabBarHidden += 1
+ } else if actionSelected == nil {
+ tabBarHidden = 0
+ }
+ }
+ }
+
+ @Published var actionSelected: Int? = nil {
+ didSet {
+ if actionSelected != nil {
+ tabBarHidden += 1
+ } else if tosView == nil {
+ tabBarHidden = 0
+ }
+ }
+ }
+}
diff --git a/TalerWallet1/Views/Settings/Bank/BankEditView.swift
b/TalerWallet1/Views/Settings/Bank/BankEditView.swift
index 38656a5..6258110 100755
--- a/TalerWallet1/Views/Settings/Bank/BankEditView.swift
+++ b/TalerWallet1/Views/Settings/Bank/BankEditView.swift
@@ -210,10 +210,10 @@ struct BankEditView: View {
let warningText1 = String(localized: "Are you sure you want to
forget this bank account?")
WarningButton(warningText: warningText1,
buttonTitle: buttonTitle,
- buttonIcon: "trash",
- role: .destructive,
- disabled: $disabled,
- action: deleteAccount)
+ buttonIcon: "trash",
+ role: .destructive,
// TODO: WalletColors().errorColor
+ disabled: $disabled,
+ action: deleteAccount)
.padding(.top)
}.listRowSeparator(.hidden)
} // List
diff --git a/TalerWallet1/Views/Settings/Exchange/ExchangeListView.swift
b/TalerWallet1/Views/Settings/Exchange/ExchangeListView.swift
index 76b4b53..a87e640 100644
--- a/TalerWallet1/Views/Settings/Exchange/ExchangeListView.swift
+++ b/TalerWallet1/Views/Settings/Exchange/ExchangeListView.swift
@@ -75,7 +75,6 @@ struct ExchangeListCommonV: View {
let symLog: SymLogV?
let stack: CallStack
- @EnvironmentObject private var model: WalletModel
@EnvironmentObject private var controller: Controller
@AppStorage("minimalistic") var minimalistic: Bool = false
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
@@ -85,9 +84,10 @@ struct ExchangeListCommonV: View {
let _ = Self._printChanges()
let _ = symLog?.vlog() // just to get the # to compare it with
.onAppear & onDisappear
#endif
- let sortedList = List(controller.balances, id: \.self) { balance in
+ let sortedList = List(Array(controller.balances.enumerated()), id:
\.element) { index, balance in
ExchangeSectionView(stack: stack.push(),
- balance: balance)
+ balance: balance,
+ thousand: index * MAXEXCHANGES)
}
let emptyList = List {
diff --git a/TalerWallet1/Views/Settings/Exchange/ExchangeRowView.swift
b/TalerWallet1/Views/Settings/Exchange/ExchangeRowView.swift
index 2050196..41fb08d 100644
--- a/TalerWallet1/Views/Settings/Exchange/ExchangeRowView.swift
+++ b/TalerWallet1/Views/Settings/Exchange/ExchangeRowView.swift
@@ -13,10 +13,12 @@ struct ExchangeRowView: View {
private let symLog = SymLogV(0)
let stack: CallStack
let exchange: Exchange
+ let index: Int
@Environment(\.sizeCategory) var sizeCategory
@EnvironmentObject private var controller: Controller
@EnvironmentObject private var model: WalletModel
+ @EnvironmentObject private var navModel: NavigationModel
@AppStorage("minimalistic") var minimalistic: Bool = false
var body: some View {
@@ -36,12 +38,33 @@ struct ExchangeRowView: View {
.talerFont(.body)
}
}
+ let cellView = HStack {
+ rowView
+ Spacer()
+ Text(Image(systemName: "chevron.right"))
+ .talerFont(.table)
+ .foregroundColor(.secondary)
+ }.background { // only needed for .onTapGesture
+ Color.gray.opacity(0.001)
+ }
let showToS = WithdrawTOSView(stack: stack.push(),
exchangeBaseUrl: baseURL,
viewID: VIEW_WITHDRAW_TOS,
acceptAction: nil) // pop back to here
+ let actions = Group {
+ NavLink(index, $navModel.tosView) { showToS }
+ }
+
Group {
- NavigationLink(destination: showToS) { rowView }
+// NavigationLink(destination: showToS) { rowView }
+ cellView
+ .background(actions)
+ .onTapGesture {
+ navModel.tosView = index
+ }
+// .task {
+// navModel.tosView = false
+// }
}.listRowSeparator(.hidden)
}
}
@@ -75,7 +98,8 @@ fileprivate struct ExchangeRow_Previews: PreviewProvider {
exchangeUpdateStatus: .ready,
ageRestrictionOptions: [])
ExchangeRowView(stack: CallStack("Preview"),
- exchange: exchange1)
+ exchange: exchange1,
+ index: 1)
}
}
diff --git a/TalerWallet1/Views/Settings/Exchange/ExchangeSectionView.swift
b/TalerWallet1/Views/Settings/Exchange/ExchangeSectionView.swift
index 6ac1195..0a58229 100755
--- a/TalerWallet1/Views/Settings/Exchange/ExchangeSectionView.swift
+++ b/TalerWallet1/Views/Settings/Exchange/ExchangeSectionView.swift
@@ -15,6 +15,7 @@ struct ExchangeSectionView: View {
private let symLog = SymLogV(0)
let stack: CallStack
let balance: Balance
+ let thousand: Int
@EnvironmentObject private var model: WalletModel
@EnvironmentObject private var controller: Controller
@@ -102,9 +103,11 @@ struct ExchangeSectionView: View {
let scopeInfo = balance.scopeInfo
let currency = scopeInfo.currency
Section {
- ForEach(exchanges) { exchange in
+ ForEachWithIndex(data: exchanges) { index, exchange in
+ let _ = symLog.log("Index: \(thousand + index)")
ExchangeRowView(stack: stack.push(),
- exchange: exchange)
+ exchange: exchange,
+ index: thousand + index + 1)
.listRowSeparator(.hidden)
}
if developerMode && (DEMOCURRENCY == currency || TESTCURRENCY ==
currency) {
@@ -143,7 +146,7 @@ struct ExchangeSectionView: View {
WarningButton(warningText: warningText1,
buttonTitle: buttonTitle,
buttonIcon: "trash",
- role: .destructive,
+ role: .destructive,
// TODO: WalletColors().errorColor
disabled: $disabled,
action: deleteExchange)
.padding(.top)
diff --git a/TalerWallet1/Views/Settings/SettingsItem.swift
b/TalerWallet1/Views/Settings/SettingsItem.swift
index fda6f70..6525148 100644
--- a/TalerWallet1/Views/Settings/SettingsItem.swift
+++ b/TalerWallet1/Views/Settings/SettingsItem.swift
@@ -31,7 +31,7 @@ struct SettingsItem<Content: View>: View {
HStack {
VStack {
let isWeb = id1?.hasPrefix("web") ?? false
- let foreColor = isWeb ? WalletColors().tint
+ let foreColor = isWeb ? WalletColors().talerColor
: .primary
HStack(spacing: 8.0) {
if let imageName {
diff --git a/TalerWallet1/Views/Settings/SettingsView.swift
b/TalerWallet1/Views/Settings/SettingsView.swift
index da2d034..397e99d 100644
--- a/TalerWallet1/Views/Settings/SettingsView.swift
+++ b/TalerWallet1/Views/Settings/SettingsView.swift
@@ -59,12 +59,12 @@ struct SettingsView: View {
}
}
private var resetButton: some View {
- Button("Reset", role: .destructive) {
+ Button("Reset", role: .destructive) {
// TODO: WalletColors().errorColor
didReset = true
showResetAlert = false
Task { // runs on MainActor
symLog.log("❗️Reset wallet-core❗️")
- try? await model.resetWalletCoreT()
+ try? await model.resetWalletCore()
}
}
}
@@ -223,7 +223,7 @@ struct SettingsView: View {
Button(title) {
Task { // runs on MainActor
symLog.log("running applyDevExperiment
Refresh")
- try? await model.setConfigT(setTesting:
true)
+ try? await model.setConfig(setTesting:
true)
try? await model.devExperimentT(talerUri:
"taler://dev-experiment/start-block-refresh")
try? await model.devExperimentT(talerUri:
"taler://dev-experiment/insert-pending-refresh")
}
diff --git
a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawTOSView.swift
b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawTOSView.swift
index ca4723c..3769237 100644
--- a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawTOSView.swift
+++ b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawTOSView.swift
@@ -163,7 +163,8 @@ extension WithdrawTOSView {
.padding(.horizontal)
list.safeAreaInset(edge: .bottom) {
if showButton {
- button.padding(.bottom, 40)
+ button
+// .padding(.bottom, 40)
}
}
}
diff --git a/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift
b/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift
index 464fd5b..42cd333 100644
--- a/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift
+++ b/TalerWallet1/Views/Sheets/WithdrawExchangeV.swift
@@ -29,7 +29,7 @@ struct WithdrawExchangeV: View {
private func viewDidLoad() async {
if exchange == nil {
symLog.log(".task")
- if let withdrawExchange = try? await
model.loadWithdrawalExchangeForUri(url.absoluteString) {
+ if let withdrawExchange = try? await
model.prepareWithdrawExchange(url.absoluteString) {
let baseUrl = withdrawExchange.exchangeBaseUrl
symLog.log("getExchangeByUrl(\(baseUrl))")
if let exc = try? await model.getExchangeByUrl(url: baseUrl) {
@@ -42,6 +42,7 @@ struct WithdrawExchangeV: View {
amountToTransfer.setCurrency(currency)
// is already Amount.zero()
}
+ amountLastUsed.setCurrency(amountToTransfer.currencyStr)
exchange = exc
} else {
exchange = nil
@@ -61,6 +62,8 @@ struct WithdrawExchangeV: View {
ManualWithdraw(stack: stack.push(),
selectedBalance: $selectedBalance,
amountLastUsed: $amountLastUsed,
+ amountToTransfer: $amountToTransfer,
+ exchange: $exchange, // only for
withdraw-exchange
isSheet: true)
}
.task(id: controller.currencyTicker) {
diff --git a/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
index b1b71f5..9d4dab9 100755
--- a/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
+++ b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
@@ -59,7 +59,8 @@ struct TransactionSummaryV: View {
@Namespace var topID
func loadTransaction() async {
- if let reloadedTransaction = try? await
model.getTransactionById(transactionId, viewHandles: false) {
+ if let reloadedTransaction = try? await
model.getTransactionById(transactionId,
+ withTerms:
true, viewHandles: false) {
symLog.log("reloaded transaction:
\(reloadedTransaction.common.txState.major)")
withAnimation { transaction = reloadedTransaction; viewId = UUID()
} // redraw
if outTransaction != nil {
diff --git a/TestFlight/WhatToTest.en-US.txt b/TestFlight/WhatToTest.en-US.txt
index c091c21..bb5801a 100644
--- a/TestFlight/WhatToTest.en-US.txt
+++ b/TestFlight/WhatToTest.en-US.txt
@@ -1,3 +1,9 @@
+Version 0.14.1 (wallet-core 0.14.1)
+
+- bugfix: withdraw-template works again
+- Spanish localization
+
+
Version 0.14.0 (wallet-core 0.14.0)
• New UI with Action button
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-ios] branch master updated (4b4d112 -> 1a6daf7),
gnunet <=
- [taler-taler-ios] 04/18: terms for tx, gnunet, 2024/12/19
- [taler-taler-ios] 01/18: fix #9400, gnunet, 2024/12/19
- [taler-taler-ios] 08/18: A11Y VoiceOver dismiss button, gnunet, 2024/12/19
- [taler-taler-ios] 05/18: NavigationModel tosView, gnunet, 2024/12/19
- [taler-taler-ios] 09/18: hide tabBar in ToS, gnunet, 2024/12/19
- [taler-taler-ios] 02/18: isInternal #9332, gnunet, 2024/12/19
- [taler-taler-ios] 06/18: ForEachWithIndex, gnunet, 2024/12/19
- [taler-taler-ios] 03/18: cleanup, gnunet, 2024/12/19
- [taler-taler-ios] 07/18: A11Y colors + fontsize, gnunet, 2024/12/19
- [taler-taler-ios] 10/18: API wording, gnunet, 2024/12/19