[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taler-ios] branch master updated (e921612 -> 16eefa4)
From: |
gnunet |
Subject: |
[taler-taler-ios] branch master updated (e921612 -> 16eefa4) |
Date: |
Sun, 29 Sep 2024 10:14:16 +0200 |
This is an automated email from the git hooks/post-receive script.
marc-stibane pushed a change to branch master
in repository taler-ios.
from e921612 Rectangle height must be > 0
new 8507612 getMaxDepositAmount, getMaxPeerPushDebitAmount
new b39155d currencyInput
new e6deff7 fixedInnerHeight
new 7b974dd cleanup
new e7dfcd5 dismiss after delete
new 728792c GetMaxPeerPushAmount
new 8b3ce55 don't beep twice for expirations
new e4c17bc strikethrough
new b400eca filterByState
new 32eb6cd cleanup
new e11066f delete rows (swipeActions)
new 16eefa4 German localization
The 12 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:
TalerWallet1/Backend/WalletCore.swift | 17 ++++-
TalerWallet1/Localizable.xcstrings | 23 +++++++
TalerWallet1/Model/Model+Deposit.swift | 28 +++++++++
TalerWallet1/Model/Model+P2P.swift | 22 ++++---
TalerWallet1/Model/Model+Transactions.swift | 26 ++++++--
TalerWallet1/Model/WalletModel.swift | 2 +-
TalerWallet1/Views/Balances/BalanceCellV.swift | 1 +
TalerWallet1/Views/Balances/BalancesListView.swift | 2 +-
.../Views/Balances/BalancesPendingRowV.swift | 6 +-
.../Views/Balances/BalancesSectionView.swift | 71 +++++++++++----------
TalerWallet1/Views/Balances/SendRequestV.swift | 2 +-
TalerWallet1/Views/Banking/DepositAmountV.swift | 3 -
.../Views/Banking/ManualWithdrawDone.swift | 2 +-
TalerWallet1/Views/HelperViews/AmountInputV.swift | 24 ++++----
TalerWallet1/Views/HelperViews/AmountRowV.swift | 1 +
TalerWallet1/Views/HelperViews/AmountV.swift | 13 +++-
TalerWallet1/Views/HelperViews/BarGraph.swift | 2 +-
TalerWallet1/Views/HelperViews/CurrencyField.swift | 20 +++---
.../Views/HelperViews/CurrencyInputView.swift | 4 +-
.../Views/HelperViews/TransactionButton.swift | 31 +++++-----
.../Views/HelperViews/View+fixedInnerHeight.swift | 3 +-
TalerWallet1/Views/Overview/OverviewRowV.swift | 7 ++-
TalerWallet1/Views/Overview/OverviewSectionV.swift | 72 ++++++++++++----------
TalerWallet1/Views/Peer2peer/P2PReadyV.swift | 2 +-
TalerWallet1/Views/Peer2peer/RequestPayment.swift | 3 +-
TalerWallet1/Views/Peer2peer/SendAmount.swift | 20 ++++--
.../Views/Sheets/Payment/PayTemplateV.swift | 4 +-
.../Views/Sheets/Refund/RefundURIView.swift | 2 +-
.../WithdrawBankIntegrated/WithdrawURIView.swift | 3 +-
.../Views/Transactions/TransactionRowView.swift | 3 +-
.../Views/Transactions/TransactionSummaryV.swift | 54 ++++++++++++----
.../Views/Transactions/TransactionsListView.swift | 59 +++++++++++-------
32 files changed, 357 insertions(+), 175 deletions(-)
diff --git a/TalerWallet1/Backend/WalletCore.swift
b/TalerWallet1/Backend/WalletCore.swift
index ceaf583..bcf1011 100644
--- a/TalerWallet1/Backend/WalletCore.swift
+++ b/TalerWallet1/Backend/WalletCore.swift
@@ -39,6 +39,8 @@ class WalletCore: QuickjsMessageHandler {
var isLogging: Bool
let logger = Logger(subsystem: "net.taler.gnu", category: "WalletCore")
+ private var expired: [String] = [] // save txID of expired items to
not beep twice
+
private struct FullRequest: Encodable {
let operation: String
let id: UInt
@@ -225,7 +227,12 @@ extension WalletCore {
if let newMinor {
if newMinor == .refreshExpired {
logger.warning("RefreshExpired:
\(decoded.transactionId, privacy: .private(mask: .hash))")
- Controller.shared.playSound(0)
+ if let index = expired.firstIndex(of:
components[2]) {
+ expired.remove(at: index)
// don't beep twice
+ } else {
+ expired.append(components[2])
+ Controller.shared.playSound(0)
// beep at first sight
+ }
postNotification(.TransactionExpired,
userInfo: [TRANSACTIONTRANSITION: decoded])
return
}
@@ -234,9 +241,13 @@ extension WalletCore {
postNotification(.TransactionStateTransition,
userInfo: [TRANSACTIONTRANSITION: decoded])
case .expired:
logger.warning("Expired: \(decoded.transactionId,
privacy: .private(mask: .hash))")
- Controller.shared.playSound(0)
+ if let index = expired.firstIndex(of:
components[2]) {
+ expired.remove(at: index)
// don't beep twice
+ } else {
+ expired.append(components[2])
+ Controller.shared.playSound(0)
// beep at first sight
+ }
postNotification(.TransactionExpired, userInfo:
[TRANSACTIONTRANSITION: decoded])
- return
case .pending:
if let newMinor {
if newMinor == .ready {
diff --git a/TalerWallet1/Localizable.xcstrings
b/TalerWallet1/Localizable.xcstrings
index ce9cbd7..f7a37a5 100755
--- a/TalerWallet1/Localizable.xcstrings
+++ b/TalerWallet1/Localizable.xcstrings
@@ -2113,6 +2113,16 @@
}
}
},
+ "Delete" : {
+ "localizations" : {
+ "de" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Löschen"
+ }
+ }
+ }
+ },
"Demo: get digital cash to experience how to pay with the money of the
future." : {
"localizations" : {
"de" : {
@@ -5380,6 +5390,7 @@
}
},
"Recent %lld transactions" : {
+ "extractionState" : "stale",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -5402,6 +5413,7 @@
}
},
"Recent transaction" : {
+ "comment" : "section header singular",
"localizations" : {
"de" : {
"stringUnit" : {
@@ -5423,6 +5435,17 @@
}
}
},
+ "Recent transactions" : {
+ "comment" : "section header plural",
+ "localizations" : {
+ "de" : {
+ "stringUnit" : {
+ "state" : "translated",
+ "value" : "Aktuelle Umsätze"
+ }
+ }
+ }
+ },
"Recoup" : {
"comment" : "TransactionType",
"localizations" : {
diff --git a/TalerWallet1/Model/Model+Deposit.swift
b/TalerWallet1/Model/Model+Deposit.swift
index bf0c444..f64abb8 100644
--- a/TalerWallet1/Model/Model+Deposit.swift
+++ b/TalerWallet1/Model/Model+Deposit.swift
@@ -65,6 +65,34 @@ extension WalletModel {
return response.wireTypes
}
}
+// MARK: - max Deposit amount
+/// Check if initiating a deposit is possible, check fees
+fileprivate struct AmountResponse: Codable {
+ let effectiveAmount: Amount?
+ let rawAmount: Amount
+}
+fileprivate struct GetMaxDepositAmount: WalletBackendFormattedRequest {
+ typealias Response = AmountResponse
+ func operation() -> String { "getMaxDepositAmount" }
+ func args() -> Args { Args(currency: currency, restrictScope: scope) }
+
+ var currency: String
+ var scope: ScopeInfo
+ struct Args: Encodable {
+ var currency: String
+ var restrictScope: ScopeInfo
+// var depositPaytoUri: String
+ }
+}
+extension WalletModel {
+ @MainActor // M for MainActor
+ func getMaxDepositAmountM(_ currency: String, scope: ScopeInfo,
viewHandles: Bool = false)
+ async throws -> Amount {
+ let request = GetMaxDepositAmount(currency: currency, scope: scope)
+ let response = try await sendRequest(request, ASYNCDELAY, viewHandles:
viewHandles)
+ return response.rawAmount
+ }
+} // getMaxDepositAmountM
// MARK: - Deposit
struct DepositFees: Codable {
let coin: Amount
diff --git a/TalerWallet1/Model/Model+P2P.swift
b/TalerWallet1/Model/Model+P2P.swift
index ac8b71d..c5953e9 100644
--- a/TalerWallet1/Model/Model+P2P.swift
+++ b/TalerWallet1/Model/Model+P2P.swift
@@ -19,27 +19,29 @@ struct PeerContractTerms: Codable {
}
// MARK: - PeerPushDebit
/// Check if initiating a peer push payment is possible, check fees
-struct AmountResponse: Codable {
- let effectiveAmount: Amount
+fileprivate struct AmountResponse: Codable {
+ let effectiveAmount: Amount?
let rawAmount: Amount
}
-fileprivate struct GetMaxPeerPushAmount: WalletBackendFormattedRequest {
+fileprivate struct GetMaxPeerPushDebitAmount: WalletBackendFormattedRequest {
typealias Response = AmountResponse
- func operation() -> String { "GetMaxPeerPushAmount" }
- func args() -> Args { Args(currency: currency) }
+ func operation() -> String { "getMaxPeerPushDebitAmount" }
+ func args() -> Args { Args(currency: currency, restrictScope: scope) }
var currency: String
+ var scope: ScopeInfo
struct Args: Encodable {
var currency: String
+ var restrictScope: ScopeInfo
}
}
extension WalletModel {
- @MainActor // M for MainActor
- func getMaxPeerPushAmountM(_ currency: String, viewHandles: Bool = false)
- async throws -> AmountResponse {
- let request = GetMaxPeerPushAmount(currency: currency)
+ @MainActor // M for MainActor
+ func getMaxPeerPushDebitAmountM(_ currency: String, scope: ScopeInfo,
viewHandles: Bool = false)
+ async throws -> Amount {
+ let request = GetMaxPeerPushDebitAmount(currency: currency, scope:
scope)
let response = try await sendRequest(request, ASYNCDELAY, viewHandles:
viewHandles)
- return response
+ return response.rawAmount
}
} // getMaxPeerPushAmountM
// - - - - - -
diff --git a/TalerWallet1/Model/Model+Transactions.swift
b/TalerWallet1/Model/Model+Transactions.swift
index c8d19df..c584a20 100644
--- a/TalerWallet1/Model/Model+Transactions.swift
+++ b/TalerWallet1/Model/Model+Transactions.swift
@@ -22,22 +22,31 @@ extension WalletModel {
}
// MARK: -
+
+enum TransactionStateFilter: String, Codable {
+ case done
+ case final // done, aborted, expired, ...
+ case nonfinal // pending, dialog, suspended, aborting
+}
+
/// A request to get the transactions in the wallet's history.
fileprivate struct GetTransactions: WalletBackendFormattedRequest {
func operation() -> String { "getTransactions" }
// func operation() -> String { "testingGetSampleTransactions" }
- func args() -> Args { Args(scopeInfo: scopeInfo, currency: currency,
search: search, sort: sort, includeRefreshes: includeRefreshes) }
-
+ func args() -> Args { Args(scopeInfo: scopeInfo, currency: currency,
search: search,
+ sort: sort, filterByState: filterByState,
includeRefreshes: includeRefreshes) }
var scopeInfo: ScopeInfo?
var currency: String?
var search: String?
var sort: String?
+ var filterByState: TransactionStateFilter?
var includeRefreshes: Bool?
struct Args: Encodable {
var scopeInfo: ScopeInfo?
var currency: String?
var search: String?
var sort: String?
+ var filterByState: TransactionStateFilter?
var includeRefreshes: Bool?
}
@@ -104,16 +113,21 @@ struct ResumeTransaction: WalletBackendFormattedRequest {
extension WalletModel {
/// ask wallet-core for its list of transactions filtered by searchString
func transactionsT(_ stack: CallStack, scopeInfo: ScopeInfo, searchString:
String? = nil,
- sort: String = "descending", includeRefreshes: Bool =
false, viewHandles: Bool = false)
+ sort: String = "descending", filterByState:
TransactionStateFilter? = nil,
+ includeRefreshes: Bool = false, viewHandles: Bool = false)
async throws -> [Transaction] {
- let request = GetTransactions(scopeInfo: scopeInfo, currency:
scopeInfo.currency, search: searchString, sort: sort, includeRefreshes:
includeRefreshes)
+ let request = GetTransactions(scopeInfo: scopeInfo, currency:
scopeInfo.currency, search: searchString,
+ sort: sort, filterByState:
filterByState, includeRefreshes: includeRefreshes)
let response = try await sendRequest(request, ASYNCDELAY, viewHandles:
viewHandles)
return response.transactions
}
/// fetch transactions from Wallet-Core. No networking involved
- @MainActor func transactionsMA(_ stack: CallStack, scopeInfo: ScopeInfo,
searchString: String? = nil, sort: String = "descending", viewHandles: Bool =
false)
+ @MainActor func transactionsMA(_ stack: CallStack, scopeInfo: ScopeInfo,
searchString: String? = nil,
+ sort: String = "descending",
filterByState: TransactionStateFilter? = nil,
+ viewHandles: Bool = false)
async throws -> [Transaction] { // M for MainActor
- return try await transactionsT(stack.push(), scopeInfo: scopeInfo,
searchString: searchString, sort: sort, viewHandles: viewHandles)
+ return try await transactionsT(stack.push(), scopeInfo: scopeInfo,
searchString: searchString,
+ sort: sort, filterByState:
filterByState, viewHandles: viewHandles)
}
/// abort the specified transaction from Wallet-Core. No networking
involved
diff --git a/TalerWallet1/Model/WalletModel.swift
b/TalerWallet1/Model/WalletModel.swift
index 8aaa1e2..181ff7d 100644
--- a/TalerWallet1/Model/WalletModel.swift
+++ b/TalerWallet1/Model/WalletModel.swift
@@ -112,7 +112,7 @@ extension WalletModel {
}
/// get the specified transaction from Wallet-Core. No networking involved
@MainActor func getTransactionByIdM(_ transactionId: String, viewHandles:
Bool = false)
- async throws -> Transaction { // M for MainActor
+ async throws -> Transaction { // M for MainActor
return try await getTransactionByIdT(transactionId, viewHandles:
viewHandles) // call GetTransactionById on main thread
}
}
diff --git a/TalerWallet1/Views/Balances/BalanceCellV.swift
b/TalerWallet1/Views/Balances/BalanceCellV.swift
index a668e72..a64e57d 100644
--- a/TalerWallet1/Views/Balances/BalanceCellV.swift
+++ b/TalerWallet1/Views/Balances/BalanceCellV.swift
@@ -28,6 +28,7 @@ struct BalanceCellV: View {
currencyInfo: $currencyInfo,
amount: amount,
isNegative: nil, // don't show the + sign
+ strikethrough: false,
large: true)
.foregroundColor(.primary)
let hLayout = amountV
diff --git a/TalerWallet1/Views/Balances/BalancesListView.swift
b/TalerWallet1/Views/Balances/BalancesListView.swift
index 653efda..a60339f 100644
--- a/TalerWallet1/Views/Balances/BalancesListView.swift
+++ b/TalerWallet1/Views/Balances/BalancesListView.swift
@@ -68,7 +68,7 @@ struct BalancesListView: View {
}
#if REFRESHABLE
.refreshable { // already async
- symLog?.log("refreshing balances")
+ symLog.log("refreshing balances")
let count = await reloadBalances(stack.push("refreshing
balances"), true)
if let count, count > 0 {
NotificationCenter.default.post(name: .BalanceReloaded,
object: nil)
diff --git a/TalerWallet1/Views/Balances/BalancesPendingRowV.swift
b/TalerWallet1/Views/Balances/BalancesPendingRowV.swift
index 59840e8..e7a0c7c 100644
--- a/TalerWallet1/Views/Balances/BalancesPendingRowV.swift
+++ b/TalerWallet1/Views/Balances/BalancesPendingRowV.swift
@@ -64,7 +64,7 @@ struct BalancesPendingRowV: View {
currencyInfo: $currencyInfo,
navTitle: String(localized: "Pending",
comment: "ViewTitle of TransactionList"),
scopeInfo: balance.scopeInfo,
- transactions: pendingTransactions,
+ transactions: $pendingTransactions,
reloadAllAction: reloadPending,
reloadOneAction: reloadOneAction)
}
@@ -81,7 +81,7 @@ struct BalancesPendingRowV: View {
fileprivate struct BalancesPendingRowV_Previews: PreviewProvider {
@MainActor
struct BindingViewContainer: View {
- @State private var pendingTransactions: [Transaction] = []
+ @State private var previewTransactions: [Transaction] = []
@State private var currencyInfoD: CurrencyInfo =
CurrencyInfo.zero(DEMOCURRENCY)
var body: some View {
let flags: [BalanceFlag] = [.incomingConfirmation]
@@ -96,7 +96,7 @@ fileprivate struct BalancesPendingRowV_Previews:
PreviewProvider {
stack: CallStack("Preview"),
currencyInfo: $currencyInfoD,
balance: balance,
- pendingTransactions: $pendingTransactions,
+ pendingTransactions: $previewTransactions,
reloadPending: {stack in },
reloadOneAction: nil)
}
diff --git a/TalerWallet1/Views/Balances/BalancesSectionView.swift
b/TalerWallet1/Views/Balances/BalancesSectionView.swift
index 2054172..baa9f16 100644
--- a/TalerWallet1/Views/Balances/BalancesSectionView.swift
+++ b/TalerWallet1/Views/Balances/BalancesSectionView.swift
@@ -42,8 +42,8 @@ struct BalancesSectionView {
@State private var showSpendingHint = true
@State private var isShowingDetailView = false
- @State private var transactions: [Transaction] = []
@State private var completedTransactions: [Transaction] = []
+ @State private var recentTransactions: [Transaction] = []
@State private var pendingTransactions: [Transaction] = []
@State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN)
@State private var currencyName: String = UNKNOWN
@@ -59,15 +59,32 @@ struct BalancesSectionView {
@State private var sectionID = UUID()
@State private var shownSectionID = UUID() // guaranteed to be different
the first time
- func reloadCompleted(_ stack: CallStack) async -> () {
- if let transactions = try? await model.transactionsT(stack.push(),
scopeInfo: balance.scopeInfo, includeRefreshes: developerMode) {
- completedTransactions =
WalletModel.completedTransactions(transactions)
+ func loadRecent(_ stack: CallStack) async -> () {
+ if let transactions = try? await model.transactionsT(stack.push(),
+ scopeInfo:
balance.scopeInfo,
+// filterByState: .done,
// TODO: .done
+ includeRefreshes: false) {
+ let recent = WalletModel.completedTransactions(transactions)
+ // TODO: only load the MAXRECENT most recent transactions
+ let slice = recent.prefix(MAXRECENT) // already sorted
+ withAnimation { recentTransactions = Array(slice) }
}
}
-
- func reloadPending(_ stack: CallStack) async -> () {
- if let transactions = try? await model.transactionsT(stack.push(),
scopeInfo: balance.scopeInfo, includeRefreshes: developerMode) {
- pendingTransactions = WalletModel.pendingTransactions(transactions)
+ func loadCompleted(_ stack: CallStack) async -> () {
+ if let transactions = try? await model.transactionsT(stack.push(),
+ scopeInfo:
balance.scopeInfo,
+// filterByState: .final,
// TODO: .final
+ includeRefreshes: developerMode) {
+ let completed = WalletModel.completedTransactions(transactions)
+ withAnimation { completedTransactions = completed }
+ }
+ }
+ func loadPending(_ stack: CallStack) async -> () {
+ if let transactions = try? await model.transactionsT(stack.push(),
+ scopeInfo:
balance.scopeInfo,
+ filterByState: .nonfinal,
+ includeRefreshes: developerMode) {
+ withAnimation { pendingTransactions =
WalletModel.pendingTransactions(transactions) }
}
}
}
@@ -87,8 +104,8 @@ extension BalancesSectionView: View {
currencyInfo: $currencyInfo,
navTitle: String(localized: "Transactions",
comment: "ViewTitle of TransactionList"),
scopeInfo: scopeInfo,
- transactions: completedTransactions,
- reloadAllAction: reloadCompleted,
+ transactions: $completedTransactions,
+ reloadAllAction: loadCompleted,
reloadOneAction: reloadOneAction)
}
@@ -133,7 +150,7 @@ extension BalancesSectionView: View {
currencyInfo: $currencyInfo,
balance: balance,
pendingTransactions: $pendingTransactions,
- reloadPending: reloadPending,
+ reloadPending: loadPending,
reloadOneAction: reloadOneAction)
.padding(.leading, ICONLEADING)
}
@@ -182,37 +199,29 @@ extension BalancesSectionView: View {
currencySymbol = currencyInfo.altUnitSymbol ?? currencyName
}
.task(id: shouldReloadBalances + 1_000_000) {
-// if shownSectionID != sectionID {
- symLog.log(".task for BalancesSectionView - reload
Transactions")
- // TODO: only load the MAXRECENT most recent transactions
- if let response = try? await model.transactionsT(stack.push(".task
- reload Transactions"), scopeInfo: scopeInfo, includeRefreshes: developerMode)
{
- transactions = response
- pendingTransactions = WalletModel.pendingTransactions(response)
- completedTransactions =
WalletModel.completedTransactions(response)
- shownSectionID = sectionID
- }
-// } else {
-// symLog.log("task for BalancesSectionView \(sectionID) ❗️
skip reloading Transactions")
-// }
+ symLog.log(".task for BalancesSectionView - load
recent+completed+pending")
+ await loadRecent(stack.push(".task - load recent"))
+ await loadCompleted(stack.push(".task - load completed"))
+ await loadPending(stack.push(".task - load pending"))
}
- let transactionCount = completedTransactions.count
/// if there is only one currency, then show MAXRECENT recent
transactions
- if sectionCount == 1 && transactionCount > 0 {
+ if sectionCount == 1 && recentTransactions.count > 0 {
Section {
- let slice = completedTransactions.prefix(MAXRECENT) //
already sorted
- let threeTransactions = Array(slice)
+ let _ = symLog.log("recent transactions")
TransactionsArraySliceV(symLog: symLog,
stack: stack.push(),
currencyInfo: $currencyInfo,
scopeInfo: scopeInfo,
- transactions: threeTransactions,
+ transactions: $recentTransactions,
+ reloadAllAction: loadRecent,
reloadOneAction: reloadOneAction)
.padding(.leading, ICONLEADING)
} header: {
if !minimalistic {
- let count = transactionCount > MAXRECENT ? MAXRECENT :
transactionCount
- Text(count > 1 ? "Recent \(count) transactions"
- : "Recent transaction")
+ let recentHeader = recentTransactions.count > 1
+ ? String(localized: "Recent transactions", comment:
"section header plural")
+ : String(localized: "Recent transaction", comment:
"section header singular")
+ Text(recentHeader)
.talerFont(.title3)
.foregroundColor(WalletColors().secondary(colorScheme,
colorSchemeContrast))
}
diff --git a/TalerWallet1/Views/Balances/SendRequestV.swift
b/TalerWallet1/Views/Balances/SendRequestV.swift
index 5bf88f8..17d3eb3 100644
--- a/TalerWallet1/Views/Balances/SendRequestV.swift
+++ b/TalerWallet1/Views/Balances/SendRequestV.swift
@@ -61,7 +61,7 @@ struct SendRequestV: View {
let sendDest = LazyView {
SendAmount(stack: stack.push("\(Self.className())()"),
currencyInfo: $currencyInfo,
- amountAvailable: amountAvailable,
+ available: amountAvailable,
amountToTransfer: $amountToTransfer, // with correct
currency
summary: $summary,
scopeInfo: scope,
diff --git a/TalerWallet1/Views/Banking/DepositAmountV.swift
b/TalerWallet1/Views/Banking/DepositAmountV.swift
index f891bd6..82e1338 100644
--- a/TalerWallet1/Views/Banking/DepositAmountV.swift
+++ b/TalerWallet1/Views/Banking/DepositAmountV.swift
@@ -85,9 +85,6 @@ struct DepositAmountV: View {
LoadingView(scopeInfo: nil, message: "Depositing...")
.navigationBarBackButtonHidden(true)
.interactiveDismissDisabled() // can only use "Done"
button to dismiss
-
-// ViewState2.shared.popToRootView
-
} else {
let currency = amountToTransfer.currencyStr
let currencySymbol = currencyInfo.altUnitSymbol ??
currencyInfo.specs.name
diff --git a/TalerWallet1/Views/Banking/ManualWithdrawDone.swift
b/TalerWallet1/Views/Banking/ManualWithdrawDone.swift
index d488e3e..e8f639e 100644
--- a/TalerWallet1/Views/Banking/ManualWithdrawDone.swift
+++ b/TalerWallet1/Views/Banking/ManualWithdrawDone.swift
@@ -51,7 +51,7 @@ struct ManualWithdrawDone: View {
.interactiveDismissDisabled() // can only use "Done"
button to dismiss
// .navigationTitle(navTitle)
.safeAreaInset(edge: .bottom) {
- Button("Done", action: { dismissTop(stack.push()) } )
// ViewState.shared.popToRootView ?
+ Button("Done", action: { dismissTop(stack.push()) } )
.buttonStyle(TalerButtonStyle(type: .prominent))
.padding(.horizontal)
}
diff --git a/TalerWallet1/Views/HelperViews/AmountInputV.swift
b/TalerWallet1/Views/HelperViews/AmountInputV.swift
index d1b4f05..929682c 100644
--- a/TalerWallet1/Views/HelperViews/AmountInputV.swift
+++ b/TalerWallet1/Views/HelperViews/AmountInputV.swift
@@ -34,11 +34,10 @@ struct AmountInputV: View {
let stack: CallStack
@Binding var currencyInfo: CurrencyInfo
- let amountAvailable: Amount? // TODO:
GetMaxPeerPushAmount
+ @Binding var amountAvailable: Amount
let amountLabel: String
@Binding var amountToTransfer: Amount
let wireFee: Amount?
-// let summaryIsEditable: Bool // if true we call
SubjectInputV next
@Binding var summary: String
// @Binding var insufficient: Bool
// @Binding var feeAmount: Amount?
@@ -62,18 +61,18 @@ struct AmountInputV: View {
func checkAvailable(_ coinData: CoinData) -> Flags {
let isZero = amountToTransfer.isZero
- if let amountAvailable {
+ if !amountAvailable.isZero {
do {
let insufficient: Bool
- if let feeAmount {
- if feeIsNegative {
- insufficient = try amountToTransfer > amountAvailable
- } else {
- insufficient = try (amountToTransfer + feeAmount) >
amountAvailable
- }
- } else {
+// if let feeAmount {
+// if feeIsNegative {
+// insufficient = try amountToTransfer > amountAvailable
+// } else {
+// insufficient = try (amountToTransfer + feeAmount) >
amountAvailable
+// }
+// } else {
insufficient = try amountToTransfer > amountAvailable
- }
+// }
let disabled = insufficient || isZero || coinData.invalid ||
coinData.tooMany
return Flags(insufficient: insufficient, disabled: disabled)
} catch {
@@ -86,7 +85,8 @@ struct AmountInputV: View {
var body: some View {
let currency = amountToTransfer.currencyStr
// let insufficientLabel = String(localized: "You don't have enough
\(currency).")
- let available = amountAvailable?.formatted(currencyInfo, isNegative:
false) ?? nil
+ let available = amountAvailable.isZero ? nil
+ :
amountAvailable.formatted(currencyInfo, isNegative: false)
VStack(alignment: .trailing) {
if summary.count > 0 {
Text(summary)
diff --git a/TalerWallet1/Views/HelperViews/AmountRowV.swift
b/TalerWallet1/Views/HelperViews/AmountRowV.swift
index de10ee1..cba1187 100644
--- a/TalerWallet1/Views/HelperViews/AmountRowV.swift
+++ b/TalerWallet1/Views/HelperViews/AmountRowV.swift
@@ -26,6 +26,7 @@ struct AmountRowV: View {
currencyInfo: $currencyInfo,
amount: amount,
isNegative: isNegative,
+ strikethrough: false,
large: large)
.foregroundColor(color)
let verticalV = VStack(alignment: .leading) {
diff --git a/TalerWallet1/Views/HelperViews/AmountV.swift
b/TalerWallet1/Views/HelperViews/AmountV.swift
index e5ecafc..5ed449e 100644
--- a/TalerWallet1/Views/HelperViews/AmountV.swift
+++ b/TalerWallet1/Views/HelperViews/AmountV.swift
@@ -12,7 +12,8 @@ struct AmountV: View {
let stack: CallStack?
@Binding var currencyInfo: CurrencyInfo
let amount: Amount
- let isNegative: Bool? // if true, show a "-" before the amount
+ let isNegative: Bool? // if true, show a "-" before the amount
+ let strikethrough: Bool
let large: Bool // set to false for QR or IBAN
@EnvironmentObject private var controller: Controller
@@ -25,6 +26,7 @@ struct AmountV: View {
: showSign ? "- \(amountFormatted)"
: "+ \(amountFormatted)"
Text(amountStr)
+ .strikethrough(strikethrough, color: .red)
.multilineTextAlignment(.center)
.talerFont(large ? .title : .title2)
// .fontWeight(large ? .medium : .regular) // @available(iOS
16.0, *)
@@ -38,6 +40,15 @@ extension AmountV {
self._currencyInfo = currencyInfo
self.amount = amount
self.isNegative = isNegative
+ self.strikethrough = false
+ self.large = false
+ }
+ init(_ currencyInfo: Binding<CurrencyInfo>, _ amount: Amount, isNegative:
Bool?, strikethrough: Bool) {
+ self.stack = nil
+ self._currencyInfo = currencyInfo
+ self.amount = amount
+ self.isNegative = isNegative
+ self.strikethrough = strikethrough
self.large = false
}
}
diff --git a/TalerWallet1/Views/HelperViews/BarGraph.swift
b/TalerWallet1/Views/HelperViews/BarGraph.swift
index a4418c1..e6e1639 100644
--- a/TalerWallet1/Views/HelperViews/BarGraph.swift
+++ b/TalerWallet1/Views/HelperViews/BarGraph.swift
@@ -74,7 +74,7 @@ struct BarGraph: View {
HStack(alignment: .center, spacing: 1) {
if count > 0 {
- ForEach(Array(zip(slice.indices, slice)), id: \.0) { index,
transaction in
+ ForEach(tenTransactions, id: \.self) {transaction in
let common = transaction.common
let incoming = common.incoming()
let netto = common.amountEffective.value
diff --git a/TalerWallet1/Views/HelperViews/CurrencyField.swift
b/TalerWallet1/Views/HelperViews/CurrencyField.swift
index 2278b4b..c3e9141 100644
--- a/TalerWallet1/Views/HelperViews/CurrencyField.swift
+++ b/TalerWallet1/Views/HelperViews/CurrencyField.swift
@@ -63,12 +63,16 @@ struct CurrencyField: View {
ZStack {
// Text view to display the formatted currency
// Set as priority so CurrencyInputField size doesn't affect parent
- Text(amount.formatted(currencyInfo, isNegative: false))
- .layoutPriority(1)
- // make the textfield use the whole width for tapping inside
to become active
- .frame(maxWidth: .infinity, alignment: .trailing)
-// .background(.clear) this is not the problem of the white
corners
-
+ let text = Text(amount.formatted(currencyInfo, isNegative: false))
+ .layoutPriority(1)
+ // make the textfield use the whole width for tapping inside to
become active
+ .frame(maxWidth: .infinity, alignment: .trailing)
+ .padding(4)
+ text
+ .background(WalletColors().fieldBackground)
+ .cornerRadius(10)
+ .overlay(RoundedRectangle(cornerRadius: 10)
+ .stroke(WalletColors().fieldForeground, lineWidth: 1))
// Input text field to handle UI
currencyFieldRepresentable
// .accessibilityHidden(true)
@@ -126,14 +130,14 @@ struct CurrencyTextfieldRepresentable:
UIViewRepresentable {
textField.delegate = context.coordinator
// Set keyboard type
- textField.keyboardType = .numberPad
+ textField.keyboardType = .asciiCapableNumberPad // numberPad
// Make visual components invisible...
textField.tintColor = .clear
textField.textColor = .clear
textField.backgroundColor = .clear
// ... except for the bezel around the textfield
- textField.borderStyle = .roundedRect
+ textField.borderStyle = .none // .roundedRect
// textField.textFieldStyle(.roundedBorder)
#if DEBUG
diff --git a/TalerWallet1/Views/HelperViews/CurrencyInputView.swift
b/TalerWallet1/Views/HelperViews/CurrencyInputView.swift
index d31ac1c..39634b3 100644
--- a/TalerWallet1/Views/HelperViews/CurrencyInputView.swift
+++ b/TalerWallet1/Views/HelperViews/CurrencyInputView.swift
@@ -87,11 +87,12 @@ struct CurrencyInputView: View {
.frame(maxWidth: .infinity, alignment: .leading)
.talerFont(.title3)
.accessibilityHidden(true)
+ .padding(.bottom, -6)
currencyField
.accessibilityLabel(title)
.frame(maxWidth: .infinity, alignment: .trailing)
.foregroundColor(WalletColors().fieldForeground) // text
color
- .background(WalletColors().fieldBackground)
+// .background(WalletColors().fieldBackground) //
problem: white corners
.talerFont(.title2)
.textFieldStyle(.roundedBorder)
.onTapGesture {
@@ -144,6 +145,7 @@ struct CurrencyInputView: View {
}
}
}
+ .padding(.top, 6)
} // iOS 16+ only
}.onAppear { // make CurrencyField show the keyboard after 0.4
seconds
if hasBeenShown {
diff --git a/TalerWallet1/Views/HelperViews/TransactionButton.swift
b/TalerWallet1/Views/HelperViews/TransactionButton.swift
index d270dc8..32a3560 100755
--- a/TalerWallet1/Views/HelperViews/TransactionButton.swift
+++ b/TalerWallet1/Views/HelperViews/TransactionButton.swift
@@ -57,6 +57,7 @@ struct TransactionButton: View {
let transactionId: String
let command: TxAction
let warning: String?
+ @Binding var didExecute: Bool
let action: (_ transactionId: String, _ viewHandles: Bool) async throws ->
Void
@State private var disabled: Bool = false
@@ -69,6 +70,7 @@ struct TransactionButton: View {
if let _ = try? await action(transactionId, false) {
// symLog.log("\(executed) \(transactionId)")
executed = true // change button text
+ didExecute = true
}
}
}
@@ -91,18 +93,19 @@ struct TransactionButton: View {
}
// MARK: -
#if DEBUG
-struct TransactionButton_Previews: PreviewProvider {
-
- static func action(_ transactionId: String, _ viewHandles: Bool) async
throws {
- print(transactionId)
- }
-
- static var previews: some View {
- List {
- TransactionButton(transactionId: "Button pressed", command: .abort,
- warning: "Are you sure you want to abort this
transaction?",
- action: action)
- }
- }
-}
+//struct TransactionButton_Previews: PreviewProvider {
+//
+// static func action(_ transactionId: String, _ viewHandles: Bool) async
throws {
+// print(transactionId)
+// }
+//
+// static var previews: some View {
+// List {
+// TransactionButton(transactionId: "Button pressed", command:
.abort,
+// warning: "Are you sure you want to abort this
transaction?",
+// didExecute: <#Binding<Bool>#>,
+// action: action)
+// }
+// }
+//}
#endif
diff --git a/TalerWallet1/Views/HelperViews/View+fixedInnerHeight.swift
b/TalerWallet1/Views/HelperViews/View+fixedInnerHeight.swift
index c7654da..14d2b7f 100644
--- a/TalerWallet1/Views/HelperViews/View+fixedInnerHeight.swift
+++ b/TalerWallet1/Views/HelperViews/View+fixedInnerHeight.swift
@@ -31,12 +31,13 @@ extension View {
@available(iOS 16.0, *)
func fixedInnerHeight(_ sheetHeight: Binding<CGFloat>) -> some View {
padding()
- .background {
+ .overlay { // .background doesn't work
GeometryReader { proxy in
Color.clear.preference(key: InnerHeightPreferenceKey.self,
value: proxy.size.height)
}
}
.onPreferenceChange(InnerHeightPreferenceKey.self) { newHeight in
+// print("InnerHeightPreferenceKey \(newHeight)")
sheetHeight.wrappedValue = newHeight
}
.presentationDetents([.height(sheetHeight.wrappedValue)])
diff --git a/TalerWallet1/Views/Overview/OverviewRowV.swift
b/TalerWallet1/Views/Overview/OverviewRowV.swift
index 649a4dd..ac437ad 100644
--- a/TalerWallet1/Views/Overview/OverviewRowV.swift
+++ b/TalerWallet1/Views/Overview/OverviewRowV.swift
@@ -23,7 +23,12 @@ struct CurrenciesCell: View {
/// Renders the Balance button. "Balance" leading, amountStr trailing. If
it doesn't fit in one row then
/// amount (trailing) goes underneath "Balance" (leading).
var body: some View {
- let amountV = AmountV(stack: stack.push(), currencyInfo:
$currencyInfo, amount: amount, isNegative: false, large: true)
+ let amountV = AmountV(stack: stack.push(),
+ currencyInfo: $currencyInfo,
+ amount: amount,
+ isNegative: nil, // don't show the + sign
+ strikethrough: false,
+ large: true)
.foregroundColor(.primary)
let hLayout = amountV
.frame(maxWidth: .infinity, alignment: .trailing)
diff --git a/TalerWallet1/Views/Overview/OverviewSectionV.swift
b/TalerWallet1/Views/Overview/OverviewSectionV.swift
index 0be3e81..c13e21a 100644
--- a/TalerWallet1/Views/Overview/OverviewSectionV.swift
+++ b/TalerWallet1/Views/Overview/OverviewSectionV.swift
@@ -36,8 +36,8 @@ struct OverviewSectionV {
@State private var showSpendingHint = true
@State private var isShowingDetailView = false
- @State private var transactions: [Transaction] = []
@State private var completedTransactions: [Transaction] = []
+ @State private var recentTransactions: [Transaction] = []
@State private var pendingTransactions: [Transaction] = []
@State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN)
@State private var currencyName: String = UNKNOWN
@@ -50,15 +50,32 @@ struct OverviewSectionV {
@State private var sectionID = UUID()
@State private var shownSectionID = UUID() // guaranteed to be different
the first time
- func reloadCompleted(_ stack: CallStack) async -> () {
- if let transactions = try? await model.transactionsT(stack.push(),
scopeInfo: balance.scopeInfo, includeRefreshes: developerMode) {
- completedTransactions =
WalletModel.completedTransactions(transactions)
+ func loadRecent(_ stack: CallStack) async -> () {
+ if let transactions = try? await model.transactionsT(stack.push(),
+ scopeInfo:
balance.scopeInfo,
+// filterByState: .done,
// TODO: .done
+ includeRefreshes: false) {
+ let recent = WalletModel.completedTransactions(transactions)
+ // TODO: only load the MAXRECENT most recent transactions
+ let slice = recent.prefix(MAXRECENT) // already sorted
+ withAnimation { recentTransactions = Array(slice) }
}
}
-
- func reloadPending(_ stack: CallStack) async -> () {
- if let transactions = try? await model.transactionsT(stack.push(),
scopeInfo: balance.scopeInfo, includeRefreshes: developerMode) {
- pendingTransactions = WalletModel.pendingTransactions(transactions)
+ func loadCompleted(_ stack: CallStack) async -> () {
+ if let transactions = try? await model.transactionsT(stack.push(),
+ scopeInfo:
balance.scopeInfo,
+// filterByState: .final,
// TODO: .final
+ includeRefreshes: developerMode) {
+ let completed = WalletModel.completedTransactions(transactions)
+ withAnimation { completedTransactions = completed }
+ }
+ }
+ func loadPending(_ stack: CallStack) async -> () {
+ if let transactions = try? await model.transactionsT(stack.push(),
+ scopeInfo:
balance.scopeInfo,
+ filterByState: .nonfinal,
+ includeRefreshes: developerMode) {
+ withAnimation { pendingTransactions =
WalletModel.pendingTransactions(transactions) }
}
}
}
@@ -88,7 +105,7 @@ extension OverviewSectionV: View {
amountToTransfer: $amountToTransfer, //
does still have the wrong currency
summary: $summary,
completedTransactions: $completedTransactions,
- reloadAllAction: reloadCompleted,
+ reloadAllAction: loadCompleted,
reloadOneAction: reloadOneAction)
if pendingTransactions.count > 0 {
BalancesPendingRowV(//symLog: symLog,
@@ -96,7 +113,7 @@ extension OverviewSectionV: View {
currencyInfo: $currencyInfo,
balance: balance,
pendingTransactions: $pendingTransactions,
- reloadPending: reloadPending,
+ reloadPending: loadPending,
reloadOneAction: reloadOneAction)
.padding(.leading, ICONLEADING)
}
@@ -113,37 +130,30 @@ extension OverviewSectionV: View {
currencySymbol = currencyInfo.altUnitSymbol ?? currencyName
}
.task(id: shouldReloadBalances + 1_000_000) {
-// if shownSectionID != sectionID {
- symLog.log(".task for BalancesSectionView - reload
Transactions")
- // TODO: only load the MAXRECENT most recent transactions
- if let response = try? await model.transactionsT(stack.push(".task
- reload Transactions"), scopeInfo: scopeInfo, includeRefreshes: developerMode)
{
- transactions = response
- pendingTransactions = WalletModel.pendingTransactions(response)
- completedTransactions =
WalletModel.completedTransactions(response)
- shownSectionID = sectionID
- }
-// } else {
-// symLog.log("task for BalancesSectionView \(sectionID) ❗️
skip reloading Transactions")
-// }
+ symLog.log(".task for OverviewSectionV - load
recent+completed+pending")
+ await loadRecent(stack.push(".task - load recent"))
+ await loadCompleted(stack.push(".task - load completed"))
+ await loadPending(stack.push(".task - load pending"))
+ shownSectionID = sectionID
}
- let transactionCount = completedTransactions.count
/// if there is only one currency, then show MAXRECENT recent
transactions
- if sectionCount == 1 && transactionCount > 0 {
+ if sectionCount == 1 && recentTransactions.count > 0 {
Section {
- let slice = completedTransactions.prefix(MAXRECENT) //
already sorted
- let threeTransactions = Array(slice)
+ let _ = symLog.log("recent transactions")
TransactionsArraySliceV(symLog: symLog,
stack: stack.push(),
currencyInfo: $currencyInfo,
scopeInfo: scopeInfo,
- transactions: threeTransactions,
+ transactions: $recentTransactions,
+ reloadAllAction: loadRecent,
reloadOneAction: reloadOneAction)
.padding(.leading, ICONLEADING)
} header: {
if !minimalistic {
- let count = transactionCount > MAXRECENT ? MAXRECENT :
transactionCount
- Text(count > 1 ? "Recent \(count) transactions"
- : "Recent transaction")
+ let recentHeader = recentTransactions.count > 1
+ ? String(localized: "Recent transactions", comment:
"section header plural")
+ : String(localized: "Recent transaction", comment:
"section header singular")
+ Text(recentHeader)
.talerFont(.title3)
.foregroundColor(WalletColors().secondary(colorScheme,
colorSchemeContrast))
}
@@ -192,7 +202,7 @@ fileprivate struct CurrenciesNavigationLinksV: View {
currencyInfo: $currencyInfo,
navTitle: String(localized: "Transactions",
comment: "ViewTitle of TransactionList"),
scopeInfo: scopeInfo,
- transactions: completedTransactions,
+ transactions: $completedTransactions,
reloadAllAction: reloadAllAction,
reloadOneAction: reloadOneAction)
}
diff --git a/TalerWallet1/Views/Peer2peer/P2PReadyV.swift
b/TalerWallet1/Views/Peer2peer/P2PReadyV.swift
index d9eebac..9a5bb09 100644
--- a/TalerWallet1/Views/Peer2peer/P2PReadyV.swift
+++ b/TalerWallet1/Views/Peer2peer/P2PReadyV.swift
@@ -57,7 +57,7 @@ struct P2PReadyV: View {
.navigationBarBackButtonHidden(true)
.interactiveDismissDisabled() // can only use "Done"
button to dismiss
.safeAreaInset(edge: .bottom) {
- Button("Done", action: { dismissTop(stack.push()) } )
// ViewState.shared.popToRootView ?
+ Button("Done", action: { dismissTop(stack.push()) } )
.buttonStyle(TalerButtonStyle(type: .prominent))
.padding(.horizontal)
}
diff --git a/TalerWallet1/Views/Peer2peer/RequestPayment.swift
b/TalerWallet1/Views/Peer2peer/RequestPayment.swift
index 1fdd58b..e27ec1f 100644
--- a/TalerWallet1/Views/Peer2peer/RequestPayment.swift
+++ b/TalerWallet1/Views/Peer2peer/RequestPayment.swift
@@ -28,6 +28,7 @@ struct RequestPayment: View {
@State private var buttonSelected = false
@State private var shortcutSelected = false
@State private var amountShortcut = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
+ @State private var amountZero = Amount.zero(currency: EMPTYSTRING)
// needed for isZero
@State private var exchange: Exchange? = nil
// wg. noFees
private func shortcutAction(_ shortcut: Amount) {
@@ -136,7 +137,7 @@ struct RequestPayment: View {
: String(localized: "Amount to
request:")
AmountInputV(stack: stack.push(),
currencyInfo: $currencyInfo,
- amountAvailable: nil,
+ amountAvailable: $amountZero,
amountLabel: amountLabel,
amountToTransfer: $amountToTransfer,
wireFee: nil,
diff --git a/TalerWallet1/Views/Peer2peer/SendAmount.swift
b/TalerWallet1/Views/Peer2peer/SendAmount.swift
index ccbb5e2..9d0ff0c 100644
--- a/TalerWallet1/Views/Peer2peer/SendAmount.swift
+++ b/TalerWallet1/Views/Peer2peer/SendAmount.swift
@@ -15,7 +15,7 @@ struct SendAmount: View {
let stack: CallStack
@Binding var currencyInfo: CurrencyInfo
- let amountAvailable: Amount // TODO: GetMaxPeerPushAmount
+ let available: Amount
@Binding var amountToTransfer: Amount
@Binding var summary: String
let scopeInfo: ScopeInfo
@@ -35,6 +35,7 @@ struct SendAmount: View {
@State private var buttonSelected = false
@State private var shortcutSelected = false
@State private var amountShortcut = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
+ @State private var amountAvailable = Amount.zero(currency: EMPTYSTRING)
// GetMaxPeerPushAmount
@State private var exchange: Exchange? = nil
// wg. noFees
private func shortcutAction(_ shortcut: Amount) {
@@ -109,11 +110,11 @@ struct SendAmount: View {
let navTitle = String(localized: "NavTitle_Send_Currency",
defaultValue: "Send \(currencySymbol)",
comment: "NavTitle: Send 'currencySymbol'")
- let available = amountAvailable.formatted(currencyInfo, isNegative:
false)
+ let availableStr = amountAvailable.formatted(currencyInfo, isNegative:
false)
// let _ = print("available: \(available)")
let _ = symLog.log("currency: \(currencyInfo.specs.name), available:
\(available)")
let amountVoiceOver = amountToTransfer.formatted(currencyInfo,
isNegative: false)
- let insufficientLabel2 = String(localized: "but you only have
\(available) to send.")
+ let insufficientLabel2 = String(localized: "but you only have
\(availableStr) to send.")
let inputDestination = LazyView {
P2PSubjectV(stack: stack.push(),
@@ -143,7 +144,7 @@ struct SendAmount: View {
: String(localized: "Amount to
send:")
AmountInputV(stack: stack.push(),
currencyInfo: $currencyInfo,
- amountAvailable: amountAvailable,
+ amountAvailable: $amountAvailable,
amountLabel: amountLabel,
amountToTransfer: $amountToTransfer,
wireFee: nil,
@@ -163,6 +164,15 @@ struct SendAmount: View {
// .scrollBounceBehavior(.basedOnSize) needs iOS 16.4
.background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all))
.navigationTitle(navTitle)
+ .task {
+ do {
+ let amount = try await
model.getMaxPeerPushDebitAmountM(amountToTransfer.currencyStr,
+ scope:
scopeInfo, viewHandles: true)
+ amountAvailable = amount
+ } catch {
+ amountAvailable = available
+ }
+ }
.onAppear {
DebugViewC.shared.setViewID(VIEW_P2P_SEND, stack: stack.push())
// if we set >> controller.frontendState = -1 << here, then
becomeFirstResponder won't work!
@@ -232,7 +242,7 @@ fileprivate struct Preview_Content: View {
ageRestrictionOptions: [])
SendAmount(stack: CallStack("Preview"),
currencyInfo: $currencyInfoL,
- amountAvailable: amount,
+ available: amount,
amountToTransfer: $amountToPreview,
summary: $summary,
scopeInfo: currencyInfo.scope,
diff --git a/TalerWallet1/Views/Sheets/Payment/PayTemplateV.swift
b/TalerWallet1/Views/Sheets/Payment/PayTemplateV.swift
index fc3218b..ee73c86 100644
--- a/TalerWallet1/Views/Sheets/Payment/PayTemplateV.swift
+++ b/TalerWallet1/Views/Sheets/Payment/PayTemplateV.swift
@@ -33,6 +33,7 @@ struct PayTemplateV: View {
@State private var amountIsEditable = false
@State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
@State private var amountShortcut = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
+ @State private var amountZero = Amount.zero(currency: EMPTYSTRING)
// needed for isZero
@State private var shortcutSelected = false
@State private var buttonSelected1 = false
@State private var buttonSelected2 = false
@@ -134,8 +135,7 @@ struct PayTemplateV: View {
if amountIsEditable { // template contract amount is not
fixed => let the user input an amount first
let amountInput = AmountInputV(stack: stack.push(),
currencyInfo: $currencyInfo,
-// url: url,
- amountAvailable: nil,
+ amountAvailable: $amountZero,
amountLabel: amountLabel,
amountToTransfer: $amountToTransfer,
wireFee: nil,
diff --git a/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift
b/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift
index 58f1d8a..ae79271 100644
--- a/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift
+++ b/TalerWallet1/Views/Sheets/Refund/RefundURIView.swift
@@ -45,7 +45,7 @@ struct RefundURIView: View {
suspendAction: model.suspendTransaction,
resumeAction: model.resumeTransaction)
.safeAreaInset(edge: .bottom) {
- Button("Done", action: { dismissTop(stack.push()) } )
// ViewState.shared.popToRootView ?
+ Button("Done", action: { dismissTop(stack.push()) } )
.buttonStyle(TalerButtonStyle(type: .prominent))
.padding(.horizontal)
}
diff --git
a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift
b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift
index d783a5d..1e60f2e 100755
--- a/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift
+++ b/TalerWallet1/Views/Sheets/WithdrawBankIntegrated/WithdrawURIView.swift
@@ -29,6 +29,7 @@ struct WithdrawURIView: View {
@State private var amountIsEditable = false
@State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
@State private var amountShortcut = Amount.zero(currency: EMPTYSTRING)
// Update currency when used
+ @State private var amountZero = Amount.zero(currency: EMPTYSTRING)
// needed for isZero
@State private var buttonSelected = false
@State private var shortcutSelected = false
@State private var amountAvailable: Amount? = nil
@@ -143,7 +144,7 @@ struct WithdrawURIView: View {
: String(localized:
"Amount to withdraw:")
AmountInputV(stack: stack.push(),
currencyInfo: $currencyInfo,
- amountAvailable: amountAvailable,
+ amountAvailable: $amountZero,
amountLabel: amountLabel,
amountToTransfer: $amountToTransfer,
wireFee: wireFee,
diff --git a/TalerWallet1/Views/Transactions/TransactionRowView.swift
b/TalerWallet1/Views/Transactions/TransactionRowView.swift
index e4c7c92..8d23cd7 100644
--- a/TalerWallet1/Views/Transactions/TransactionRowView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionRowView.swift
@@ -56,7 +56,8 @@ struct TransactionRowView: View {
let iconBadge = TransactionIconBadge(type: common.type, foreColor:
foreColor,
done: done, incoming: incoming,
shouldConfirm: shouldConfirm, needsKYC:
needsKYC)
- let amountV = AmountV($currencyInfo, common.amountEffective,
isNegative: isZero ? nil : !incoming)
+ let amountV = AmountV($currencyInfo, isZero ? common.amountRaw :
common.amountEffective,
+ isNegative: isZero ? nil : !incoming,
strikethrough: !doneOrPending)
.foregroundColor(foreColor)
let topString = topString()
diff --git a/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
index 65ca027..12e56a2 100755
--- a/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
+++ b/TalerWallet1/Views/Transactions/TransactionSummaryV.swift
@@ -40,6 +40,7 @@ struct TransactionSummaryV: View {
@Environment(\.colorScheme) private var colorScheme
@Environment(\.colorSchemeContrast) private var colorSchemeContrast
+ @Environment(\.presentationMode) var presentationMode:
Binding<PresentationMode>
@AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
#if DEBUG
@AppStorage("developerMode") var developerMode: Bool = true
@@ -47,7 +48,9 @@ struct TransactionSummaryV: View {
@AppStorage("developerMode") var developerMode: Bool = false
#endif
- @State var transaction: Transaction = Transaction(dummyCurrency:
DEMOCURRENCY)
+ @State private var ignoreThis: Bool = false
+ @State private var didDelete: Bool = false
+ @State var transaction = Transaction(dummyCurrency: DEMOCURRENCY)
@State var viewId = UUID()
func loadTransaction() async {
@@ -76,6 +79,15 @@ struct TransactionSummaryV: View {
return false
}
+ @MainActor
+ private func dismiss(_ stack: CallStack) {
+ if hasDone { // if this view is in a sheet then dissmiss the
whole sheet
+ dismissTop(stack.push())
+ } else { // on a NavigationStack just pop
+ presentationMode.wrappedValue.dismiss()
+ }
+ }
+
func checkReload(_ notification: Notification, _ logStr: String = "") {
if let transition = notification.userInfo?[TRANSACTIONTRANSITION] as?
TransactionTransition {
if transition.transactionId == transactionId { // is the
transition for THIS transaction?
@@ -110,11 +122,17 @@ struct TransactionSummaryV: View {
if developerMode {
if transaction.isSuspendable { if let suspendAction {
TransactionButton(transactionId: common.transactionId,
- command: .suspend, warning: nil,
action: suspendAction)
+ command: .suspend,
+ warning: nil,
+ didExecute: $ignoreThis,
+ action: suspendAction)
} }
if transaction.isResumable { if let resumeAction {
TransactionButton(transactionId: common.transactionId,
- command: .resume, warning: nil,
action: resumeAction)
+ command: .resume,
+ warning: nil,
+ didExecute: $ignoreThis,
+ action: resumeAction)
} }
} // Suspend + Resume buttons
Group {
@@ -164,19 +182,31 @@ struct TransactionSummaryV: View {
// warning: nil, action: abortAction)
// } } // Retry button
if transaction.isAbortable { if let abortAction {
- TransactionButton(transactionId: common.transactionId,
command: .abort,
- warning: String(localized: "Are you sure
you want to abort this transaction?"),
- action: abortAction)
+ TransactionButton(transactionId: common.transactionId,
+ command: .abort,
+ warning: String(localized: "Are
you sure you want to abort this transaction?"),
+ didExecute: $ignoreThis,
+ action: abortAction)
} } // Abort button
if transaction.isFailable { if let failAction {
- TransactionButton(transactionId: common.transactionId,
command: .fail,
- warning: String(localized: "Are you sure
you want to abandon this transaction?"),
- action: failAction)
+ TransactionButton(transactionId: common.transactionId,
+ command: .fail,
+ warning: String(localized: "Are
you sure you want to abandon this transaction?"),
+ didExecute: $ignoreThis,
+ action: failAction)
} } // Fail button
if transaction.isDeleteable { if let deleteAction {
- TransactionButton(transactionId: common.transactionId,
command: .delete,
- warning: String(localized: "Are you sure
you want to delete this transaction?"),
- action: deleteAction)
+ TransactionButton(transactionId: common.transactionId,
+ command: .delete,
+ warning: String(localized: "Are
you sure you want to delete this transaction?"),
+ didExecute: $didDelete,
+ action: deleteAction)
+ .onChange(of: didDelete) { wasDeleted in
+ if wasDeleted {
+ symLog.log("wasDeleted -> dismiss view")
+ dismiss(stack)
+ }
+ }
} } // Delete button
}.id(viewId) // change viewId to enforce a draw update
.listStyle(myListStyle.style).anyView
diff --git a/TalerWallet1/Views/Transactions/TransactionsListView.swift
b/TalerWallet1/Views/Transactions/TransactionsListView.swift
index 41469b6..1814bc7 100644
--- a/TalerWallet1/Views/Transactions/TransactionsListView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionsListView.swift
@@ -20,7 +20,8 @@ struct TransactionsListView: View {
let navTitle: String
let scopeInfo: ScopeInfo
- let transactions: [Transaction]
+ @Binding var transactions: [Transaction]
+
let reloadAllAction: (_ stack: CallStack) async -> ()
let reloadOneAction: ((_ transactionId: String, _ viewHandles: Bool) async
throws -> Transaction)
@@ -39,7 +40,8 @@ struct TransactionsListView: View {
stack: stack.push(),
currencyInfo: $currencyInfo,
scopeInfo: scopeInfo,
- transactions: transactions,
+ transactions: $transactions,
+ reloadAllAction: reloadAllAction,
reloadOneAction: reloadOneAction)
.padding(.leading, ICONLEADING)
}
@@ -67,7 +69,7 @@ struct TransactionsListView: View {
.navigationTitle(navTitle)
.accessibilityHint(String(localized: "Transaction list"))
.task {
- symLog.log(".task ")
+ symLog.log("❗️.task List❗️")
await reloadAllAction(stack.push())
}
.overlay {
@@ -87,10 +89,12 @@ struct TransactionsArraySliceV: View {
let stack: CallStack
@Binding var currencyInfo: CurrencyInfo
let scopeInfo: ScopeInfo
- let transactions: [Transaction]
+ @Binding var transactions: [Transaction]
+ let reloadAllAction: (_ stack: CallStack) async -> ()
let reloadOneAction: ((_ transactionId: String, _ viewHandles: Bool) async
throws -> Transaction)
@EnvironmentObject private var model: WalletModel
+
var body: some View {
#if PRINT_CHANGES
let _ = Self._printChanges()
@@ -101,25 +105,38 @@ struct TransactionsArraySliceV: View {
let failAction = model.failTransaction
let suspendAction = model.suspendTransaction
let resumeAction = model.resumeTransaction
- ForEach(Array(zip(transactions.indices, transactions)), id: \.1) {
index, transaction in
- NavigationLink {
- LazyView {
- TransactionSummaryV(stack: stack.push(),
- currencyInfo: $currencyInfo,
- transactionId: transaction.id,
- reloadAction: reloadOneAction,
- navTitle: nil,
- hasDone: false,
- abortAction: abortAction,
- deleteAction: deleteAction,
- failAction: failAction,
- suspendAction: suspendAction,
- resumeAction: resumeAction)
- }
- } label: {
+
+ ForEach(transactions, id: \.self) { transaction in
+ let destination = TransactionSummaryV(stack: stack.push(),
+ currencyInfo: $currencyInfo,
+ transactionId: transaction.id,
+ reloadAction: reloadOneAction,
+ navTitle: nil,
+ hasDone: false,
+ abortAction: abortAction,
+ deleteAction: deleteAction,
+ failAction: failAction,
+ suspendAction: suspendAction,
+ resumeAction: resumeAction)
+ let row = NavigationLink { destination } label: {
TransactionRowView(currencyInfo: $currencyInfo, transaction:
transaction)
+ }.id(transaction.id)
+ if transaction.isDeleteable {
+ row.swipeActions(edge: .trailing) {
+ Button {
+ symLog?.log("deleteAction")
+ Task { // runs on MainActor
+ let _ = try? await
deleteAction(transaction.id, false)
+ await reloadAllAction(stack.push())
+ }
+ } label: {
+ Label("Delete", systemImage: "trash")
+ }
+ .tint(.red)
+ }
+ } else {
+ row
}
- .id(Int(index))
}
}
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
- [taler-taler-ios] branch master updated (e921612 -> 16eefa4),
gnunet <=
- [taler-taler-ios] 03/12: fixedInnerHeight, gnunet, 2024/09/29
- [taler-taler-ios] 02/12: currencyInput, gnunet, 2024/09/29
- [taler-taler-ios] 09/12: filterByState, gnunet, 2024/09/29
- [taler-taler-ios] 01/12: getMaxDepositAmount, getMaxPeerPushDebitAmount, gnunet, 2024/09/29
- [taler-taler-ios] 04/12: cleanup, gnunet, 2024/09/29
- [taler-taler-ios] 06/12: GetMaxPeerPushAmount, gnunet, 2024/09/29
- [taler-taler-ios] 12/12: German localization, gnunet, 2024/09/29
- [taler-taler-ios] 11/12: delete rows (swipeActions), gnunet, 2024/09/29
- [taler-taler-ios] 05/12: dismiss after delete, gnunet, 2024/09/29
- [taler-taler-ios] 07/12: don't beep twice for expirations, gnunet, 2024/09/29