commit 9ec3d69b203c31c48d49e9d9df7786a8b5f4046c
parent f6393725982d29898a539b8c12a6cab95a1957b5
Author: Marc Stibane <marc@taler.net>
Date: Sat, 20 Jul 2024 19:11:23 +0200
BalanceRowView -> SendRequestV
Diffstat:
3 files changed, 142 insertions(+), 157 deletions(-)
diff --git a/TalerWallet.xcodeproj/project.pbxproj b/TalerWallet.xcodeproj/project.pbxproj
@@ -111,7 +111,7 @@
4E3EAE712A990778009F1BE8 /* URL+id+iban.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E363CBB2A237E0900D7E98C /* URL+id+iban.swift */; };
4E3EAE722A990778009F1BE8 /* RequestPayment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E9320442A1645B600A87B0E /* RequestPayment.swift */; };
4E3EAE732A990778009F1BE8 /* SettingsItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095262989CBFE0043A8A1 /* SettingsItem.swift */; };
- 4E3EAE742A990778009F1BE8 /* BalanceRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095362989CBFE0043A8A1 /* BalanceRowView.swift */; };
+ 4E3EAE742A990778009F1BE8 /* SendRequestV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095362989CBFE0043A8A1 /* SendRequestV.swift */; };
4E3EAE752A990778009F1BE8 /* DebugViewC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E753A052A0952F7002D9328 /* DebugViewC.swift */; };
4E3EAE772A990778009F1BE8 /* AnyCodable in Frameworks */ = {isa = PBXBuildFile; productRef = 4E3EAE162A990778009F1BE8 /* AnyCodable */; };
4E3EAE782A990778009F1BE8 /* SymLog in Frameworks */ = {isa = PBXBuildFile; productRef = 4E3EAE182A990778009F1BE8 /* SymLog */; };
@@ -223,7 +223,7 @@
4EB095582989CBFE0043A8A1 /* TransactionSummaryV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095312989CBFE0043A8A1 /* TransactionSummaryV.swift */; };
4EB095592989CBFE0043A8A1 /* Model+Transactions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095322989CBFE0043A8A1 /* Model+Transactions.swift */; };
4EB0955A2989CBFE0043A8A1 /* URLSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095332989CBFE0043A8A1 /* URLSheet.swift */; };
- 4EB0955C2989CBFE0043A8A1 /* BalanceRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095362989CBFE0043A8A1 /* BalanceRowView.swift */; };
+ 4EB0955C2989CBFE0043A8A1 /* SendRequestV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095362989CBFE0043A8A1 /* SendRequestV.swift */; };
4EB0955D2989CBFE0043A8A1 /* BalancesListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095372989CBFE0043A8A1 /* BalancesListView.swift */; };
4EB0955E2989CBFE0043A8A1 /* PendingRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095382989CBFE0043A8A1 /* PendingRowView.swift */; };
4EB0955F2989CBFE0043A8A1 /* WalletEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095392989CBFE0043A8A1 /* WalletEmptyView.swift */; };
@@ -440,7 +440,7 @@
4EB095312989CBFE0043A8A1 /* TransactionSummaryV.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionSummaryV.swift; sourceTree = "<group>"; };
4EB095322989CBFE0043A8A1 /* Model+Transactions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Model+Transactions.swift"; sourceTree = "<group>"; };
4EB095332989CBFE0043A8A1 /* URLSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSheet.swift; sourceTree = "<group>"; };
- 4EB095362989CBFE0043A8A1 /* BalanceRowView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BalanceRowView.swift; sourceTree = "<group>"; };
+ 4EB095362989CBFE0043A8A1 /* SendRequestV.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendRequestV.swift; sourceTree = "<group>"; };
4EB095372989CBFE0043A8A1 /* BalancesListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BalancesListView.swift; sourceTree = "<group>"; };
4EB095382989CBFE0043A8A1 /* PendingRowView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PendingRowView.swift; sourceTree = "<group>"; };
4EB095392989CBFE0043A8A1 /* WalletEmptyView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletEmptyView.swift; sourceTree = "<group>"; };
@@ -800,7 +800,7 @@
4EB0953A2989CBFE0043A8A1 /* BalancesSectionView.swift */,
4E77976E2C4BEA4E005D6ECB /* BalanceCellV.swift */,
4E448AB62C4A4109007D5C92 /* BalancesPendingRowV.swift */,
- 4EB095362989CBFE0043A8A1 /* BalanceRowView.swift */,
+ 4EB095362989CBFE0043A8A1 /* SendRequestV.swift */,
4EB065432A4CD1A80039B91D /* TwoRowButtons.swift */,
4EB095382989CBFE0043A8A1 /* PendingRowView.swift */,
);
@@ -1284,7 +1284,7 @@
4EDBDCD92AB787CB00925C02 /* CallStack.swift in Sources */,
4E3EAE722A990778009F1BE8 /* RequestPayment.swift in Sources */,
4E3EAE732A990778009F1BE8 /* SettingsItem.swift in Sources */,
- 4E3EAE742A990778009F1BE8 /* BalanceRowView.swift in Sources */,
+ 4E3EAE742A990778009F1BE8 /* SendRequestV.swift in Sources */,
4E3EAEA82AA70157009F1BE8 /* Binding+onChange.swift in Sources */,
4E3EAE752A990778009F1BE8 /* DebugViewC.swift in Sources */,
);
@@ -1412,7 +1412,7 @@
4EDBDCDA2AB787CB00925C02 /* CallStack.swift in Sources */,
4E9320452A1645B600A87B0E /* RequestPayment.swift in Sources */,
4EB095502989CBFE0043A8A1 /* SettingsItem.swift in Sources */,
- 4EB0955C2989CBFE0043A8A1 /* BalanceRowView.swift in Sources */,
+ 4EB0955C2989CBFE0043A8A1 /* SendRequestV.swift in Sources */,
4E3EAEA92AA70157009F1BE8 /* Binding+onChange.swift in Sources */,
4E753A062A0952F8002D9328 /* DebugViewC.swift in Sources */,
);
diff --git a/TalerWallet1/Views/Balances/BalanceRowView.swift b/TalerWallet1/Views/Balances/BalanceRowView.swift
@@ -1,151 +0,0 @@
-/*
- * This file is part of GNU Taler, ©2022-24 Taler Systems S.A.
- * See LICENSE.md
- */
-/**
- * @author Marc Stibane
- */
-import SwiftUI
-import taler_swift
-
-struct BalanceCell: View {
- let stack: CallStack?
- let amount: Amount
- let sizeCategory: ContentSizeCategory
- let rowAction: () -> Void
- let balanceDest: LazyView<TransactionsListView>?
-
- @Environment(\.colorScheme) private var colorScheme
- @Environment(\.colorSchemeContrast) private var colorSchemeContrast
- @AppStorage("minimalistic") var minimalistic: Bool = false
-
- /// Renders the Balance button. "Balance" leading, amountStr trailing. If it doesn't fit in one row then
- /// amount (trailing) goes underneath "Balance" (leading).
- var body: some View {
- let amountV = AmountV(stack: stack?.push("AmountV"), amount: amount, isNegative: false, large: true)
- .foregroundColor(.primary)
- let hLayout = amountV
- .frame(maxWidth: .infinity, alignment: .trailing)
- let balanceCell = Group {
- if minimalistic {
- hLayout
- } else {
- let balanceText = Text("Balance:", comment: "Main view")
- .talerFont(.title2)
- .foregroundColor(WalletColors().secondary(colorScheme, colorSchemeContrast))
- let vLayout = VStack(alignment: .leading, spacing: 0) {
- balanceText
- hLayout
- }
-
- if #available(iOS 16.0, *) {
- ViewThatFits(in: .horizontal) {
- HStack(spacing: HSPACING) {
- balanceText
- hLayout
- }
- vLayout
- }
- } else { vLayout } // view for iOS 15
- }
- }
- NavigationLink { balanceDest } label: {
- balanceCell
- .accessibilityElement(children: .combine)
- .accessibilityHint(String(localized: "Will go to main transactions list."))
-// .accessibilityLabel(balanceTitleStr + " " + amountStr) // TODO: CurrencyFormatter!
- }
- }
-}
-
-
-/// This view shows the currency row in a currency section, and two action buttons below
-/// Balance: amount
-/// [Send Money] [Request Payment]
-struct BalanceRowView: View {
- let stack: CallStack
- let currencyName: String
- let amount: Amount
- let sendAction: () -> Void
- let recvAction: () -> Void
- let rowAction: () -> Void
- let balanceDest: LazyView<TransactionsListView>?
-
- @Environment(\.sizeCategory) var sizeCategory
- @EnvironmentObject private var controller: Controller
- @AppStorage("minimalistic") var minimalistic: Bool = false
- @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
-
- var body: some View {
- let sendTitle0 = String(localized: "SendButton_Short", defaultValue: "Send",
- comment: "Abbreviation of button `Send (currency)´")
- let sendTitle1 = String(localized: "SendButton_Full", defaultValue: "Send\t\(currencyName)",
- comment: "`Send (currency)´ in Balances - must have ONE \\t and ONE %@")
-
- let requestTitle0 = String(localized: "RequestButton_Short", defaultValue: "Request",
- comment: "Abbreviation of button `Request (currency)´")
- let requestTitle1 = String(localized: "RequestButton_Full", defaultValue: "Request\t\(currencyName)",
- comment: "`Request (currency)´ in Balances - must have ONE \\t and ONE %@")
- VStack (alignment: .trailing, spacing: 6) {
- BalanceCell(stack: stack.push("BalanceCell"),
- amount: amount,
- sizeCategory: sizeCategory,
- rowAction: rowAction,
- balanceDest: balanceDest)
-// .border(.red)
-
- let sendTitle = minimalistic ? sendTitle0 : sendTitle1
- let requTitle = minimalistic ? requestTitle0 : requestTitle1
- let twoRowButtons = TwoRowButtons(stack: stack.push(),
- sendTitle: sendTitle,
- sendType: .peerPushDebit,
- sendA11y: sendTitle.tabbed(oneLine: true),
- recvTitle: requTitle,
- recvType: .peerPullCredit,
- recvA11y: requTitle.tabbed(oneLine: true),
- fitsSideBySide: false,
- lineLimit: 5,
- sendDisabled: amount.isZero,
- sendAction: sendAction,
- recvAction: recvAction)
- if #available(iOS 16.0, *) {
- ViewThatFits(in: .horizontal) {
- HStack(spacing: HSPACING) {
- twoRowButtons.makeCopy(fitsSideBySide: true)
- }
-// .border(.red)
- VStack { twoRowButtons }
-// .border(.red)
- }
- } else { // view for iOS 15
- VStack { twoRowButtons }
- }
- }
- }
-}
-// MARK: -
-#if DEBUG
-struct BalanceRowView_Previews: PreviewProvider {
- @MainActor
- struct StateContainer: View {
- var body: some View {
- let test = Amount(currency: TESTCURRENCY, cent: 123)
- let demo = Amount(currency: DEMOCURRENCY, cent: 123456)
-
- List {
- Section {
- BalanceRowView(stack: CallStack("Preview"), currencyName: DEMOCURRENCY, amount: demo,
- sendAction: {}, recvAction: {}, rowAction: {}, balanceDest: nil)
- }
- BalanceRowView(stack: CallStack("Preview"), currencyName: TESTCURRENCY, amount: test,
- sendAction: {}, recvAction: {}, rowAction: {}, balanceDest: nil)
- }
- }
- }
-
- static var previews: some View {
- StateContainer()
-// .environment(\.sizeCategory, .extraExtraLarge) Canvas Device Settings
- }
-}
-#endif
diff --git a/TalerWallet1/Views/Balances/SendRequestV.swift b/TalerWallet1/Views/Balances/SendRequestV.swift
@@ -0,0 +1,136 @@
+/*
+ * This file is part of GNU Taler, ©2022-24 Taler Systems S.A.
+ * See LICENSE.md
+ */
+/**
+ * @author Marc Stibane
+ */
+import SwiftUI
+import taler_swift
+import SymLog
+
+struct SendRequestV: View {
+ private let symLog = SymLogV(0)
+ let stack: CallStack
+ let currencyInfo: CurrencyInfo
+ let amountAvailable: Amount
+ // let currency: String // this is the currency to be used
+ @Binding var amountToTransfer: Amount // does still have the wrong currency
+ @Binding var summary: String
+ let cameraAction: () -> Void
+
+ @EnvironmentObject private var model: WalletModel
+ @AppStorage("minimalistic") var minimalistic: Bool = false
+ @State private var buttonSelected: Int? = nil
+
+ func selectAndUpdate(_ button: Int) {
+ let scope = currencyInfo.scope
+ let currency = scope.currency
+ amountToTransfer.setCurrency(currency)
+ buttonSelected = button // will trigger NavigationLink
+ // after user tapped a button, while navigation animation runs, contact Exchange to update Fees
+ if let url = scope.url {
+ Task { // runs on MainActor
+ do {
+ // TODO: try await model.updateExchange(scopeInfo: scope)
+ try await model.updateExchange(exchangeBaseUrl: url)
+ } catch { // TODO: error handling - couldn't updateExchange
+ symLog.log("error: \(error)")
+ }
+ }
+ }
+ }
+
+ private static func className() -> String {"\(self)"}
+
+ var body: some View {
+ let scope = currencyInfo.scope
+ let currencyName = currencyInfo.specs.name
+ let sendTitle0 = String(localized: "SendButton_Short", defaultValue: "Send",
+ comment: "Abbreviation of button `Send (currency)´")
+ let sendTitle1 = String(localized: "SendButton_Full", defaultValue: "Send\t\(currencyName)",
+ comment: "`Send (currency)´ in Balances - must have ONE \\t and ONE %@")
+ let sendTitle = minimalistic ? sendTitle0 : sendTitle1
+
+ let requTitle0 = String(localized: "RequestButton_Short", defaultValue: "Request",
+ comment: "Abbreviation of button `Request (currency)´")
+ let requTitle1 = String(localized: "RequestButton_Full", defaultValue: "Request\t\(currencyName)",
+ comment: "`Request (currency)´ in Balances - must have ONE \\t and ONE %@")
+ let requTitle = minimalistic ? requTitle0 : requTitle1
+ let sendDest = LazyView {
+ SendAmount(stack: stack.push("\(Self.className())()"),
+ currencyInfo: currencyInfo,
+ amountAvailable: amountAvailable,
+ amountToTransfer: $amountToTransfer, // with correct currency
+ summary: $summary,
+ scopeInfo: scope,
+ cameraAction: cameraAction)
+ }
+ let requestDest = LazyView {
+ RequestPayment(stack: stack.push("\(Self.className())()"),
+ amountToTransfer: $amountToTransfer, // with correct currency
+ summary: $summary,
+ scopeInfo: scope,
+ cameraAction: cameraAction)
+ }
+ let disableSend = amountAvailable.isZero //?? false
+ let twoRowButtons = TwoRowButtons(stack: stack.push(),
+ sendTitle: sendTitle,
+ sendType: .peerPushDebit,
+ sendA11y: sendTitle1.tabbed(oneLine: true),
+ recvTitle: requTitle,
+ recvType: .peerPullCredit,
+ recvA11y: requTitle1.tabbed(oneLine: true),
+ fitsSideBySide: false,
+ lineLimit: 5,
+ sendDisabled: disableSend,
+ sendAction: { selectAndUpdate(1) },
+ recvAction: { selectAndUpdate(2) })
+ Group {
+ if #available(iOS 16.0, *) {
+ ViewThatFits(in: .horizontal) {
+ HStack(spacing: HSPACING) {
+ twoRowButtons.makeCopy(fitsSideBySide: true)
+ }
+// .border(.red)
+ VStack { twoRowButtons }
+// .border(.red)
+ }
+ } else { // view for iOS 15
+ VStack { twoRowButtons }
+ }
+ }
+ .background( Group {
+ NavigationLink(destination: sendDest, tag: 1, selection: $buttonSelected)
+ { EmptyView() }.frame(width: 0).opacity(0).hidden()
+ NavigationLink(destination: requestDest, tag: 2, selection: $buttonSelected)
+ { EmptyView() }.frame(width: 0).opacity(0).hidden()
+ })
+ }
+}
+// MARK: -
+#if false
+struct SendRequestV_Previews: PreviewProvider {
+ @MainActor
+ struct StateContainer: View {
+ var body: some View {
+ let test = Amount(currency: TESTCURRENCY, cent: 123)
+ let demo = Amount(currency: DEMOCURRENCY, cent: 123456)
+
+ List {
+ Section {
+ SendRequestV(stack: CallStack("Preview"), currencyName: DEMOCURRENCY, amount: demo,
+ sendAction: {}, recvAction: {}, rowAction: {}, balanceDest: nil)
+ }
+ SendRequestV(stack: CallStack("Preview"), currencyName: TESTCURRENCY, amount: test,
+ sendAction: {}, recvAction: {}, rowAction: {}, balanceDest: nil)
+ }
+ }
+ }
+
+ static var previews: some View {
+ StateContainer()
+// .environment(\.sizeCategory, .extraExtraLarge) Canvas Device Settings
+ }
+}
+#endif