taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit 820783b5be6156eb5441917af632282d359d4c14
parent aca4f65273e295805b5e456b016a864c4eab0513
Author: Marc Stibane <marc@taler.net>
Date:   Sun, 19 Nov 2023 18:52:54 +0100

cleanup P2P

Diffstat:
MTalerWallet.xcodeproj/project.pbxproj | 30++++++++++++------------------
MTalerWallet1/Controllers/DebugViewC.swift | 10+++++-----
ATalerWallet1/Views/Peer2peer/P2PReadyV.swift | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ATalerWallet1/Views/Peer2peer/P2PSubjectV.swift | 121+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MTalerWallet1/Views/Peer2peer/RequestPayment.swift | 4++--
DTalerWallet1/Views/Peer2peer/RequestPurpose.swift | 109-------------------------------------------------------------------------------
MTalerWallet1/Views/Peer2peer/SendAmount.swift | 4++--
DTalerWallet1/Views/Peer2peer/SendDoneV.swift | 105-------------------------------------------------------------------------------
DTalerWallet1/Views/Peer2peer/SendPurpose.swift | 130-------------------------------------------------------------------------------
9 files changed, 253 insertions(+), 371 deletions(-)

diff --git a/TalerWallet.xcodeproj/project.pbxproj b/TalerWallet.xcodeproj/project.pbxproj @@ -62,12 +62,11 @@ 4E3EAE422A990778009F1BE8 /* KeyboardResponder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EAD117529F672FA008EDD0B /* KeyboardResponder.swift */; }; 4E3EAE432A990778009F1BE8 /* TransactionRowView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095302989CBFE0043A8A1 /* TransactionRowView.swift */; }; 4E3EAE442A990778009F1BE8 /* PublicConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EA1ABBD29A3833A008821EA /* PublicConstants.swift */; }; - 4E3EAE452A990778009F1BE8 /* SendDoneV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB3136029FEE79B007D68BC /* SendDoneV.swift */; }; + 4E3EAE452A990778009F1BE8 /* P2PReadyV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB3136029FEE79B007D68BC /* P2PReadyV.swift */; }; 4E3EAE462A990778009F1BE8 /* TextFieldAlert.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095482989CBFE0043A8A1 /* TextFieldAlert.swift */; }; 4E3EAE472A990778009F1BE8 /* QuiteSomeCoins.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA82AC2A3F580500E5F39A /* QuiteSomeCoins.swift */; }; 4E3EAE482A990778009F1BE8 /* PayTemplateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA56402A7FF5200084948B /* PayTemplateView.swift */; }; 4E3EAE492A990778009F1BE8 /* ManualWithdrawDone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB431662A1E55C700C5690E /* ManualWithdrawDone.swift */; }; - 4E3EAE4A2A990778009F1BE8 /* RequestPurpose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E9320462A164BC700A87B0E /* RequestPurpose.swift */; }; 4E3EAE4B2A990778009F1BE8 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E753A072A0B6A5F002D9328 /* ShareSheet.swift */; }; 4E3EAE4C2A990778009F1BE8 /* AmountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095492989CBFE0043A8A1 /* AmountView.swift */; }; 4E3EAE4D2A990778009F1BE8 /* P2pAcceptDone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E3B4BC22A42252300CC88B8 /* P2pAcceptDone.swift */; }; @@ -100,7 +99,7 @@ 4E3EAE6A2A990778009F1BE8 /* ThreeAmountsV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ED2F94A2A278F5100453B40 /* ThreeAmountsV.swift */; }; 4E3EAE6B2A990778009F1BE8 /* Model+Withdraw.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0953D2989CBFE0043A8A1 /* Model+Withdraw.swift */; }; 4E3EAE6C2A990778009F1BE8 /* ExchangeSectionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EC90C772A1B528B0071DC58 /* ExchangeSectionView.swift */; }; - 4E3EAE6D2A990778009F1BE8 /* SendPurpose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E7940DD29FC307C00A9AEA1 /* SendPurpose.swift */; }; + 4E3EAE6D2A990778009F1BE8 /* P2PSubjectV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E7940DD29FC307C00A9AEA1 /* P2PSubjectV.swift */; }; 4E3EAE6E2A990778009F1BE8 /* Model+P2P.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4ECB627F2A0BA6DF004ABBB7 /* Model+P2P.swift */; }; 4E3EAE6F2A990778009F1BE8 /* TalerStrings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095072989CB7C0043A8A1 /* TalerStrings.swift */; }; 4E3EAE702A990778009F1BE8 /* CurrencyInputView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EA551242A2C923600FEC9A8 /* CurrencyInputView.swift */; }; @@ -155,7 +154,7 @@ 4E6EDD872A363D8D0031D520 /* ListStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E6EDD862A363D8D0031D520 /* ListStyle.swift */; }; 4E753A062A0952F8002D9328 /* DebugViewC.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E753A052A0952F7002D9328 /* DebugViewC.swift */; }; 4E753A082A0B6A5F002D9328 /* ShareSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E753A072A0B6A5F002D9328 /* ShareSheet.swift */; }; - 4E7940DE29FC307C00A9AEA1 /* SendPurpose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E7940DD29FC307C00A9AEA1 /* SendPurpose.swift */; }; + 4E7940DE29FC307C00A9AEA1 /* P2PSubjectV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E7940DD29FC307C00A9AEA1 /* P2PSubjectV.swift */; }; 4E87C8732A31CB7F001C6406 /* TransactionsEmptyView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E87C8722A31CB7F001C6406 /* TransactionsEmptyView.swift */; }; 4E87C8752A34B411001C6406 /* IncompleteRowV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E87C8742A34B411001C6406 /* IncompleteRowV.swift */; }; 4E8C17202A6509BB005B2392 /* Atkinson-Hyperlegible-Regular-102.otf in Resources */ = {isa = PBXBuildFile; fileRef = 4E8C171C2A6509BB005B2392 /* Atkinson-Hyperlegible-Regular-102.otf */; }; @@ -165,7 +164,6 @@ 4E8E25332A1CD39700A27BFA /* EqualIconWidthDomain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E8E25322A1CD39700A27BFA /* EqualIconWidthDomain.swift */; }; 4E9320432A14F6EA00A87B0E /* WalletColors.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E9320422A14F6EA00A87B0E /* WalletColors.swift */; }; 4E9320452A1645B600A87B0E /* RequestPayment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E9320442A1645B600A87B0E /* RequestPayment.swift */; }; - 4E9320472A164BC700A87B0E /* RequestPurpose.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E9320462A164BC700A87B0E /* RequestPurpose.swift */; }; 4E9796902A3765ED006F73BC /* AgePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E97968F2A3765ED006F73BC /* AgePicker.swift */; }; 4E983C292ADBDD3500FA9CC5 /* SingleAxisGeometryReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E983C282ADBDD3500FA9CC5 /* SingleAxisGeometryReader.swift */; }; 4E983C2A2ADBDD3500FA9CC5 /* SingleAxisGeometryReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4E983C282ADBDD3500FA9CC5 /* SingleAxisGeometryReader.swift */; }; @@ -223,7 +221,7 @@ 4EB0956C2989CBFE0043A8A1 /* AmountView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB095492989CBFE0043A8A1 /* AmountView.swift */; }; 4EB0956D2989CBFE0043A8A1 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0954A2989CBFE0043A8A1 /* LoadingView.swift */; }; 4EB0956E2989CBFE0043A8A1 /* Model+Pending.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB0954C2989CBFE0043A8A1 /* Model+Pending.swift */; }; - 4EB3136129FEE79B007D68BC /* SendDoneV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB3136029FEE79B007D68BC /* SendDoneV.swift */; }; + 4EB3136129FEE79B007D68BC /* P2PReadyV.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB3136029FEE79B007D68BC /* P2PReadyV.swift */; }; 4EB431672A1E55C700C5690E /* ManualWithdrawDone.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EB431662A1E55C700C5690E /* ManualWithdrawDone.swift */; }; 4EBA563F2A7FD9390084948B /* SuperScriptDigits.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA563E2A7FD9390084948B /* SuperScriptDigits.swift */; }; 4EBA56412A7FF5200084948B /* PayTemplateView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4EBA56402A7FF5200084948B /* PayTemplateView.swift */; }; @@ -329,7 +327,7 @@ 4E753A042A08E720002D9328 /* transactions.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = transactions.json; sourceTree = "<group>"; }; 4E753A052A0952F7002D9328 /* DebugViewC.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DebugViewC.swift; sourceTree = "<group>"; }; 4E753A072A0B6A5F002D9328 /* ShareSheet.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ShareSheet.swift; sourceTree = "<group>"; }; - 4E7940DD29FC307C00A9AEA1 /* SendPurpose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendPurpose.swift; sourceTree = "<group>"; }; + 4E7940DD29FC307C00A9AEA1 /* P2PSubjectV.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = P2PSubjectV.swift; sourceTree = "<group>"; }; 4E7CFD372A532CE100CBAFF3 /* WhatToTest.en-US.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = "WhatToTest.en-US.txt"; sourceTree = "<group>"; }; 4E87C8722A31CB7F001C6406 /* TransactionsEmptyView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TransactionsEmptyView.swift; sourceTree = "<group>"; }; 4E87C8742A34B411001C6406 /* IncompleteRowV.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IncompleteRowV.swift; sourceTree = "<group>"; }; @@ -340,7 +338,6 @@ 4E8E25322A1CD39700A27BFA /* EqualIconWidthDomain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EqualIconWidthDomain.swift; sourceTree = "<group>"; }; 4E9320422A14F6EA00A87B0E /* WalletColors.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WalletColors.swift; sourceTree = "<group>"; }; 4E9320442A1645B600A87B0E /* RequestPayment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestPayment.swift; sourceTree = "<group>"; }; - 4E9320462A164BC700A87B0E /* RequestPurpose.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RequestPurpose.swift; sourceTree = "<group>"; }; 4E97968F2A3765ED006F73BC /* AgePicker.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AgePicker.swift; sourceTree = "<group>"; }; 4E983C282ADBDD3500FA9CC5 /* SingleAxisGeometryReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SingleAxisGeometryReader.swift; sourceTree = "<group>"; }; 4E983C2B2ADC416800FA9CC5 /* View+fitsSideBySide.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "View+fitsSideBySide.swift"; sourceTree = "<group>"; }; @@ -396,7 +393,7 @@ 4EB095492989CBFE0043A8A1 /* AmountView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AmountView.swift; sourceTree = "<group>"; }; 4EB0954A2989CBFE0043A8A1 /* LoadingView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = "<group>"; }; 4EB0954C2989CBFE0043A8A1 /* Model+Pending.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Model+Pending.swift"; sourceTree = "<group>"; }; - 4EB3136029FEE79B007D68BC /* SendDoneV.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendDoneV.swift; sourceTree = "<group>"; }; + 4EB3136029FEE79B007D68BC /* P2PReadyV.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = P2PReadyV.swift; sourceTree = "<group>"; }; 4EB431662A1E55C700C5690E /* ManualWithdrawDone.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManualWithdrawDone.swift; sourceTree = "<group>"; }; 4EBA563E2A7FD9390084948B /* SuperScriptDigits.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuperScriptDigits.swift; sourceTree = "<group>"; }; 4EBA56402A7FF5200084948B /* PayTemplateView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PayTemplateView.swift; sourceTree = "<group>"; }; @@ -764,10 +761,9 @@ isa = PBXGroup; children = ( 4E40E0BD29F25ABB00B85369 /* SendAmount.swift */, - 4E7940DD29FC307C00A9AEA1 /* SendPurpose.swift */, - 4EB3136029FEE79B007D68BC /* SendDoneV.swift */, 4E9320442A1645B600A87B0E /* RequestPayment.swift */, - 4E9320462A164BC700A87B0E /* RequestPurpose.swift */, + 4E7940DD29FC307C00A9AEA1 /* P2PSubjectV.swift */, + 4EB3136029FEE79B007D68BC /* P2PReadyV.swift */, ); path = Peer2peer; sourceTree = "<group>"; @@ -1077,12 +1073,11 @@ 4E3EAE422A990778009F1BE8 /* KeyboardResponder.swift in Sources */, 4E3EAE432A990778009F1BE8 /* TransactionRowView.swift in Sources */, 4E3EAE442A990778009F1BE8 /* PublicConstants.swift in Sources */, - 4E3EAE452A990778009F1BE8 /* SendDoneV.swift in Sources */, + 4E3EAE452A990778009F1BE8 /* P2PReadyV.swift in Sources */, 4E3EAE462A990778009F1BE8 /* TextFieldAlert.swift in Sources */, 4E3EAE472A990778009F1BE8 /* QuiteSomeCoins.swift in Sources */, 4E3EAE482A990778009F1BE8 /* PayTemplateView.swift in Sources */, 4E3EAE492A990778009F1BE8 /* ManualWithdrawDone.swift in Sources */, - 4E3EAE4A2A990778009F1BE8 /* RequestPurpose.swift in Sources */, 4E3EAE4B2A990778009F1BE8 /* ShareSheet.swift in Sources */, 4EC4008F2AE8019700DF72C7 /* ExchangeRowView.swift in Sources */, 4E3EAE4C2A990778009F1BE8 /* AmountView.swift in Sources */, @@ -1121,7 +1116,7 @@ 4E3EAE6A2A990778009F1BE8 /* ThreeAmountsV.swift in Sources */, 4E3EAE6B2A990778009F1BE8 /* Model+Withdraw.swift in Sources */, 4E3EAE6C2A990778009F1BE8 /* ExchangeSectionView.swift in Sources */, - 4E3EAE6D2A990778009F1BE8 /* SendPurpose.swift in Sources */, + 4E3EAE6D2A990778009F1BE8 /* P2PSubjectV.swift in Sources */, 4E3EAE6E2A990778009F1BE8 /* Model+P2P.swift in Sources */, 4E3EAE6F2A990778009F1BE8 /* TalerStrings.swift in Sources */, 4E3EAE702A990778009F1BE8 /* CurrencyInputView.swift in Sources */, @@ -1184,12 +1179,11 @@ 4EAD117629F672FA008EDD0B /* KeyboardResponder.swift in Sources */, 4EB095572989CBFE0043A8A1 /* TransactionRowView.swift in Sources */, 4EA1ABBE29A3833A008821EA /* PublicConstants.swift in Sources */, - 4EB3136129FEE79B007D68BC /* SendDoneV.swift in Sources */, + 4EB3136129FEE79B007D68BC /* P2PReadyV.swift in Sources */, 4EB0956B2989CBFE0043A8A1 /* TextFieldAlert.swift in Sources */, 4EBA82AD2A3F580500E5F39A /* QuiteSomeCoins.swift in Sources */, 4EBA56412A7FF5200084948B /* PayTemplateView.swift in Sources */, 4EB431672A1E55C700C5690E /* ManualWithdrawDone.swift in Sources */, - 4E9320472A164BC700A87B0E /* RequestPurpose.swift in Sources */, 4E753A082A0B6A5F002D9328 /* ShareSheet.swift in Sources */, 4EC400902AE8019700DF72C7 /* ExchangeRowView.swift in Sources */, 4EB0956C2989CBFE0043A8A1 /* AmountView.swift in Sources */, @@ -1228,7 +1222,7 @@ 4ED2F94B2A278F5100453B40 /* ThreeAmountsV.swift in Sources */, 4EB095622989CBFE0043A8A1 /* Model+Withdraw.swift in Sources */, 4EC90C782A1B528B0071DC58 /* ExchangeSectionView.swift in Sources */, - 4E7940DE29FC307C00A9AEA1 /* SendPurpose.swift in Sources */, + 4E7940DE29FC307C00A9AEA1 /* P2PSubjectV.swift in Sources */, 4ECB62802A0BA6DF004ABBB7 /* Model+P2P.swift in Sources */, 4EB0950A2989CB7C0043A8A1 /* TalerStrings.swift in Sources */, 4EA551252A2C923600FEC9A8 /* CurrencyInputView.swift in Sources */, diff --git a/TalerWallet1/Controllers/DebugViewC.swift b/TalerWallet1/Controllers/DebugViewC.swift @@ -52,15 +52,15 @@ public let VIEW_DEPOSIT_ACCEPT = VIEW_DEPOSIT + 2 // 42 // MARK: P2P Send Coins (from Balances) // push debit to another wallet ==> shows QR code to be scanned / link to be sent by mail or messenger -public let VIEW_SEND_P2P = VIEW_DEPOSIT + 10 // 50 Send Coins +public let VIEW_P2P_SEND = VIEW_DEPOSIT + 10 // 50 Send Coins //public let VIEW_SEND_TOS // - user already accepted the ToS at withdrawal, invoice or receive -public let VIEW_SEND_PURPOSE = VIEW_SEND_P2P + 2 // 52 Send Purpose +public let VIEW_P2P_SUBJECT = VIEW_P2P_SEND + 2 // 52 Send / Request Subject +public let VIEW_P2P_READY = VIEW_P2P_SEND + 3 // 53 Send / Request Ready // MARK: P2P Private Receive (from Balances) // pull credit from another wallet ==> shows QR code to be scanned / link to be sent by mail or messenger -public let VIEW_REQUEST_P2P = VIEW_SEND_P2P + 10 // 60 Request Amount -public let VIEW_REQUEST_TOS = VIEW_REQUEST_P2P + 1 // 61 Request ToS -public let VIEW_REQUEST_PURPOSE = VIEW_REQUEST_TOS + 1 // 62 Request Purpose +public let VIEW_P2P_REQUEST = VIEW_P2P_SEND + 10 // 60 Request Amount +public let VIEW_P2P_TOS = VIEW_P2P_REQUEST + 1 // 61 Request ToS // MARK: P2P Business Invoice (from Balances) // TBD diff --git a/TalerWallet1/Views/Peer2peer/P2PReadyV.swift b/TalerWallet1/Views/Peer2peer/P2PReadyV.swift @@ -0,0 +1,111 @@ +/* + * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * See LICENSE.md + */ +import SwiftUI +import taler_swift +import SymLog + +// Called when initiating a P2P transaction: Send coins or Send Request(Invoice) +struct P2PReadyV: View { + private let symLog = SymLogV() + let stack: CallStack + let amountToSend: Amount? + let amountToReceive: Amount? + let summary: String + let expireDays: UInt + @Binding var transactionStarted: Bool + + @EnvironmentObject private var model: WalletModel +#if DEBUG + @AppStorage("developerMode") var developerMode: Bool = true +#else + @AppStorage("developerMode") var developerMode: Bool = false +#endif + @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic + + let navTitle = String(localized: "P2P Ready") + @State private var transactionId: String? = nil + + func reloadOneAction(_ transactionId: String) async throws -> Transaction { + return try await model.getTransactionByIdT(transactionId) + } + + var body: some View { +#if DEBUG + let _ = Self._printChanges() + let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear +#endif + ScrollView { VStack { + if let transactionId { + TransactionDetailView(stack: stack.push(), + transactionId: transactionId, + reloadAction: reloadOneAction, + navTitle: navTitle, + doneAction: ViewState.shared.popToRootView, + abortAction: nil, + deleteAction: nil, + failAction: nil, + suspendAction: nil, + resumeAction: nil) + .navigationBarBackButtonHidden(true) + .interactiveDismissDisabled() // can only use "Done" button to dismiss + } else { + WithdrawProgressView(message: "Loading...") + } + } } // ScrollVStack + .navigationTitle(navTitle) + .onAppear { + DebugViewC.shared.setViewID(VIEW_P2P_READY, stack: stack.push()) +// print("❗️ P2PReadyV onAppear") + } + .onDisappear { +// print("❗️ P2PReadyV onDisappear") + } + .task { + symLog.log(".task") + do { + guard transactionStarted == false else { +// TODO: logger.warning("Try to start P2P a second time") + symLog.log("Yikes❗️ Try to start P2P a second time") + return + } + transactionStarted = true + let timestamp = developerMode ? Timestamp.inSomeMinutes(expireDays > 20 ? (24*60) + : expireDays > 5 ? 60 : 3) + : Timestamp.inSomeDays(expireDays) + if let amountToSend { + let terms = PeerContractTerms(amount: amountToSend, + summary: summary, + purse_expiration: timestamp) + // TODO: let user choose baseURL + let response = try await model.initiatePeerPushDebitM(nil, terms: terms) + // will switch from WithdrawProgressView to TransactionDetailView + transactionId = response.transactionId + } else if let amountToReceive { + let terms = PeerContractTerms(amount: amountToReceive, + summary: summary, + purse_expiration: timestamp) + // TODO: let user choose baseURL + let response = try await model.initiatePeerPullCreditM(nil, terms: terms) + // will switch from WithdrawProgressView to TransactionDetailView + transactionId = response.transactionId + } else { fatalError() } + } catch { // TODO: error + symLog.log(error.localizedDescription) + } + } // task + } +} +// MARK: - +//struct SendNow_Previews: PreviewProvider { +// static var previews: some View { +// Group { +// SendDoneV(stack: CallStack("Preview"), +// amountToSend: Amount(currency: LONGCURRENCY, cent: 480), +// amountToReceive: nil, +// summary: "some subject/purpose", +// expireDays: 0) +// } +// } +//} diff --git a/TalerWallet1/Views/Peer2peer/P2PSubjectV.swift b/TalerWallet1/Views/Peer2peer/P2PSubjectV.swift @@ -0,0 +1,121 @@ +/* + * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. + * See LICENSE.md + */ +import SwiftUI +import taler_swift +import SymLog + +struct P2PSubjectV: View { + private let symLog = SymLogV(0) + let stack: CallStack + + let amountToSend: Amount? + let amountToReceive: Amount? +// let amountToTransfer: Amount + let navTitle: String + let buttonTitle: String + let feeLabel: String + let currencyInfo: CurrencyInfo + @Binding var summary: String + @Binding var expireDays: UInt + + @AppStorage("iconOnly") var iconOnly: Bool = false + + @State private var transactionStarted: Bool = false + @FocusState private var isFocused: Bool + + var body: some View { +#if DEBUG + let _ = Self._printChanges() + let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear +#endif + ScrollView { VStack (alignment: .leading, spacing: 6) { + if feeLabel.count > 0 { + HStack { + Spacer() + Text(feeLabel) + .foregroundColor(.red) + .accessibilityFont(.body) + } + } + if !iconOnly { + Text("Enter subject:") // Purpose + .accessibilityFont(.title3) + .accessibilityAddTraits(.isHeader) + .accessibilityRemoveTraits(.isStaticText) + .padding(.top) + } + Group { if #available(iOS 16.0, *) { + TextField(iconOnly ? "Subject" : EMPTYSTRING, text: $summary, axis: .vertical) + .focused($isFocused) + .lineLimit(2...) + } else { + TextField("Subject", text: $summary) + .focused($isFocused) +// .lineLimit(2...5) // lineLimit' is only available in iOS 16.0 or newer + } } // Group for iOS16+ & iOS15 + .accessibilityFont(.title2) + .foregroundColor(WalletColors().fieldForeground) // text color + .background(WalletColors().fieldBackground) + .textFieldStyle(.roundedBorder) + .onAppear { + symLog.log("dispatching kbd...") + DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { + isFocused = true // make first responder - raise keybord + symLog.log("...kbd isFocused") + } + } + HStack{ + Spacer() + Text(verbatim: "\(summary.count)/100") + .accessibilityFont(.body) + .accessibilityValue("\(summary.count) characters of 100") + } // maximum 100 characters + + // TODO: compute max Expiration day from peerPushCheck to disable 30 (and even 7) + SelectDays(selected: $expireDays, maxExpiration: THIRTYDAYS) + .disabled(false) + .padding(.bottom) + + let disabled = (expireDays == 0) || (summary.count < 1) // TODO: check amountAvailable + NavigationLink(destination: LazyView { + P2PReadyV(stack: stack.push(), + amountToSend: amountToSend, + amountToReceive: amountToReceive, + summary: summary, + expireDays: expireDays, + transactionStarted: $transactionStarted) + }) { + Text(buttonTitle) + } + .buttonStyle(TalerButtonStyle(type: .prominent)) + .disabled(disabled) + .accessibilityHint(disabled ? "enabled when subject and expiration are set" : EMPTYSTRING) + }.padding(.horizontal) } // ScrollVStack + .navigationTitle(navTitle) + .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) + .onAppear { + DebugViewC.shared.setViewID(VIEW_P2P_SUBJECT, stack: stack.push()) +// print("❗️ P2PSubjectV onAppear") + } + .onDisappear { +// print("❗️ P2PSubjectV onDisappear") + } + } +} +// MARK: - +#if DEBUG +//struct SendPurpose_Previews: PreviewProvider { +// static var previews: some View { +// @State var summary: String = "" +// @State var expireDays: UInt = 0 +// let amount = Amount(currency: LONGCURRENCY, integer: 10, fraction: 0) +// SendPurpose(amountAvailable: amount, +// amountToTransfer: 543, +// fee: "0,43", +// summary: $summary, +// expireDays: $expireDays) +// } +//} +#endif diff --git a/TalerWallet1/Views/Peer2peer/RequestPayment.swift b/TalerWallet1/Views/Peer2peer/RequestPayment.swift @@ -56,7 +56,7 @@ struct RequestPayment: View { let disabled = amountToTransfer.isZero || someCoins.invalid || someCoins.tooMany NavigationLink(destination: LazyView { - SendPurpose(stack: stack.push(), + P2PSubjectV(stack: stack.push(), amountToSend: nil, amountToReceive: amountToTransfer, navTitle: navTitle2, @@ -75,7 +75,7 @@ struct RequestPayment: View { .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) .navigationTitle(navTitle) .onAppear { - DebugViewC.shared.setViewID(VIEW_REQUEST_P2P, stack: stack.push()) + DebugViewC.shared.setViewID(VIEW_P2P_REQUEST, stack: stack.push()) symLog.log("❗️Yikes \(navTitle) onAppear") } .onDisappear { diff --git a/TalerWallet1/Views/Peer2peer/RequestPurpose.swift b/TalerWallet1/Views/Peer2peer/RequestPurpose.swift @@ -1,109 +0,0 @@ -/* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. - * See LICENSE.md - */ -import SwiftUI -import taler_swift -import SymLog - -struct RequestPurpose: View { - private let symLog = SymLogV(0) - let stack: CallStack - - let amountToTransfer: Amount - let fee: Amount? - @Binding var summary: String - @Binding var expireDays: UInt - - @EnvironmentObject private var controller: Controller - @AppStorage("iconOnly") var iconOnly: Bool = false - let navTitle = String(localized: "NavTitle_Request_Subject", - defaultValue: "Request", comment: "NavTitle for entering the subject for Request-Payment") - - @State private var transactionStarted: Bool = false - @FocusState private var isFocused: Bool - - var body: some View { - let currencyInfo = controller.info(for: amountToTransfer.currencyStr, controller.currencyTicker) - ScrollView { VStack (spacing: 6) { - Text(amountToTransfer.string(currencyInfo)) - if let fee { - let feeStr = fee.string(currencyInfo) - Text("+ \(feeStr) payment fee") - .foregroundColor(.red) - } - VStack(alignment: .leading, spacing: 6) { - if !iconOnly { - Text("Subject:") - .accessibilityFont(.title3) - .padding(.top) - } - TextField("Subject", text: $summary) - .accessibilityFont(.title) - .foregroundColor(WalletColors().fieldForeground) // text color - .background(WalletColors().fieldBackground) - .textFieldStyle(.roundedBorder) - .focused($isFocused) - .onAppear { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { - isFocused = true // make first responder - raise keybord - } - } - - HStack{ - Spacer() - Text(verbatim: "\(summary.count)/100") - } // maximum 100 characters - - SelectDays(selected: $expireDays, maxExpiration: THIRTYDAYS) - .disabled(false) - .padding(.bottom) - - let disabled = (expireDays == 0) || (summary.count < 1) - NavigationLink(destination: LazyView { - SendDoneV(stack: stack.push(), - amountToSend: nil, - amountToReceive: amountToTransfer, - summary: summary, - expireDays: expireDays, - transactionStarted: $transactionStarted) - }) { - Text("Request \(amountToTransfer.readableDescription)") // TODO: formatter -// .accessibilityFont(buttonFont) - } - .buttonStyle(TalerButtonStyle(type: .prominent)) - .disabled(disabled) - .accessibilityHint(disabled ? "enabled when subject and expiration are set" : EMPTYSTRING) - - Spacer() - } - .frame(maxWidth: .infinity, alignment: .leading) - .padding(.horizontal) - } } // ScrollVStack - .navigationTitle(navTitle) - .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) - .onAppear { - DebugViewC.shared.setViewID(VIEW_REQUEST_PURPOSE, stack: stack.push()) -// print("❗️ RequestPurpose onAppear") - } - .onDisappear { -// print("❗️ RequestPurpose onDisappear") - } - } - -} -// MARK: - -#if DEBUG -//struct RequestPurpose_Previews: PreviewProvider { -// static var previews: some View { -// let scopeInfo = ScopeInfo(type: .exchange, exchangeBaseUrl: DEMOEXCHANGE, currency: LONGCURRENCY) -// @State var summary: String = "pUrPoSe" -// @State var expireDays: UInt = 0 -// RequestPurpose(scopeInfo: scopeInfo, -// amountToReceive: 5, -// fee: "fee", -// summary: $summary, -// expireDays: $expireDays) -// } -//} -#endif diff --git a/TalerWallet1/Views/Peer2peer/SendAmount.swift b/TalerWallet1/Views/Peer2peer/SendAmount.swift @@ -78,7 +78,7 @@ struct SendAmount: View { .padding(4) NavigationLink(destination: LazyView { - SendPurpose(stack: stack.push(), + P2PSubjectV(stack: stack.push(), amountToSend: amountToTransfer, amountToReceive: nil, navTitle: navTitle2, @@ -97,7 +97,7 @@ struct SendAmount: View { .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) .navigationTitle(navTitle) .onAppear { - DebugViewC.shared.setViewID(VIEW_SEND_P2P, stack: stack.push()) + DebugViewC.shared.setViewID(VIEW_P2P_SEND, stack: stack.push()) symLog.log("❗️Yikes SendAmount onAppear") } .onDisappear { diff --git a/TalerWallet1/Views/Peer2peer/SendDoneV.swift b/TalerWallet1/Views/Peer2peer/SendDoneV.swift @@ -1,105 +0,0 @@ -/* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. - * See LICENSE.md - */ -import SwiftUI -import taler_swift -import SymLog - -// Called when initiating a P2P transaction: Send coins or Send Request(Invoice) -struct SendDoneV: View { - private let symLog = SymLogV() - let stack: CallStack - let amountToSend: Amount? - let amountToReceive: Amount? - let summary: String - let expireDays: UInt - @Binding var transactionStarted: Bool - - @EnvironmentObject private var model: WalletModel -#if DEBUG - @AppStorage("developerMode") var developerMode: Bool = true -#else - @AppStorage("developerMode") var developerMode: Bool = false -#endif - @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic - - let navTitle = String(localized: "P2P Ready") - @State private var transactionId: String? = nil - - func reloadOneAction(_ transactionId: String) async throws -> Transaction { - return try await model.getTransactionByIdT(transactionId) - } - - var body: some View { -#if DEBUG - let _ = Self._printChanges() - let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear -#endif - ScrollView { VStack { - if let transactionId { - TransactionDetailView(stack: stack.push(), - transactionId: transactionId, - reloadAction: reloadOneAction, - navTitle: navTitle, - doneAction: ViewState.shared.popToRootView, - abortAction: nil, - deleteAction: nil, - failAction: nil, - suspendAction: nil, - resumeAction: nil) - .navigationBarBackButtonHidden(true) - .interactiveDismissDisabled() // can only use "Done" button to dismiss - } else { - WithdrawProgressView(message: "Loading...") - } - } } // ScrollVStack -// .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) - .navigationTitle(navTitle) - .task { - symLog.log(".task") - do { - guard transactionStarted == false else { -// TODO: logger.warning("Try to start P2P a second time") - symLog.log("Yikes❗️ Try to start P2P a second time") - return - } - transactionStarted = true - let timestamp = developerMode ? Timestamp.inSomeMinutes(expireDays > 20 ? (24*60) - : expireDays > 5 ? 60 : 3) - : Timestamp.inSomeDays(expireDays) - if let amountToSend { - let terms = PeerContractTerms(amount: amountToSend, - summary: summary, - purse_expiration: timestamp) - // TODO: let user choose baseURL - let response = try await model.initiatePeerPushDebitM(nil, terms: terms) - // will switch from WithdrawProgressView to TransactionDetailView - transactionId = response.transactionId - } else if let amountToReceive { - let terms = PeerContractTerms(amount: amountToReceive, - summary: summary, - purse_expiration: timestamp) - // TODO: let user choose baseURL - let response = try await model.initiatePeerPullCreditM(nil, terms: terms) - // will switch from WithdrawProgressView to TransactionDetailView - transactionId = response.transactionId - } else { fatalError() } - } catch { // TODO: error - symLog.log(error.localizedDescription) - } - } // task - } -} -// MARK: - -//struct SendNow_Previews: PreviewProvider { -// static var previews: some View { -// Group { -// SendDoneV(stack: CallStack("Preview"), -// amountToSend: Amount(currency: LONGCURRENCY, cent: 480), -// amountToReceive: nil, -// summary: "some subject/purpose", -// expireDays: 0) -// } -// } -//} diff --git a/TalerWallet1/Views/Peer2peer/SendPurpose.swift b/TalerWallet1/Views/Peer2peer/SendPurpose.swift @@ -1,130 +0,0 @@ -/* - * This file is part of GNU Taler, ©2022-23 Taler Systems S.A. - * See LICENSE.md - */ -import SwiftUI -import taler_swift -import SymLog - -struct SendPurpose: View { - private let symLog = SymLogV(0) - let stack: CallStack - - let amountToSend: Amount? - let amountToReceive: Amount? -// let amountToTransfer: Amount - let navTitle: String - let buttonTitle: String - let feeLabel: String - let currencyInfo: CurrencyInfo - @Binding var summary: String - @Binding var expireDays: UInt - - @AppStorage("iconOnly") var iconOnly: Bool = false - - @State private var transactionStarted: Bool = false - @FocusState private var isFocused: Bool - - var body: some View { -#if DEBUG - let _ = Self._printChanges() - let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear -#endif - ScrollView { VStack (alignment: .leading, spacing: 6) { - if feeLabel.count > 0 { - HStack { - Spacer() - Text(feeLabel) - .foregroundColor(.red) - .accessibilityFont(.body) - } - } - if !iconOnly { - Text("Enter subject:") // Purpose - .accessibilityFont(.title3) - .accessibilityAddTraits(.isHeader) - .accessibilityRemoveTraits(.isStaticText) - .padding(.top) - } - Group { if #available(iOS 16.0, *) { - TextField(iconOnly ? "Subject" : EMPTYSTRING, text: $summary, axis: .vertical) - .focused($isFocused) - .lineLimit(2...) - } else { - TextField("Subject", text: $summary) - .focused($isFocused) -// .lineLimit(2...5) // lineLimit' is only available in iOS 16.0 or newer - } } // Group for iOS16+ & iOS15 - .accessibilityFont(.title2) - .foregroundColor(WalletColors().fieldForeground) // text color - .background(WalletColors().fieldBackground) - .textFieldStyle(.roundedBorder) - .onAppear { - symLog.log("dispatching kbd...") - DispatchQueue.main.asyncAfter(deadline: .now() + 0.4) { - isFocused = true // make first responder - raise keybord - symLog.log("...kbd isFocused") - } - } - HStack{ - Spacer() - Text(verbatim: "\(summary.count)/100") - .accessibilityFont(.body) - .accessibilityValue("\(summary.count) characters of 100") - } // maximum 100 characters - - // TODO: compute max Expiration day from peerPushCheck to disable 30 (and even 7) - SelectDays(selected: $expireDays, maxExpiration: THIRTYDAYS) - .disabled(false) - .padding(.bottom) - - let disabled = (expireDays == 0) || (summary.count < 1) // TODO: check amountAvailable - NavigationLink(destination: LazyView { - SendDoneV(stack: stack.push(), - amountToSend: amountToSend, - amountToReceive: amountToReceive, - summary: summary, - expireDays: expireDays, - transactionStarted: $transactionStarted) - }) { - Text(buttonTitle) - } - .buttonStyle(TalerButtonStyle(type: .prominent)) - .disabled(disabled) - .accessibilityHint(disabled ? "enabled when subject and expiration are set" : EMPTYSTRING) - }.padding(.horizontal) } // ScrollVStack - .navigationTitle(navTitle) - .background(WalletColors().backgroundColor.edgesIgnoringSafeArea(.all)) - .onAppear { - DebugViewC.shared.setViewID(VIEW_SEND_PURPOSE, stack: stack.push()) -// print("❗️ SendPurpose onAppear") - } - .onDisappear { -// print("❗️ SendPurpose onDisappear") - } - .task { - symLog.log(".task") - do { - - } catch { // TODO: error - symLog.log(error.localizedDescription) - } - } - } - -} -// MARK: - -#if DEBUG -//struct SendPurpose_Previews: PreviewProvider { -// static var previews: some View { -// @State var summary: String = "" -// @State var expireDays: UInt = 0 -// let amount = Amount(currency: LONGCURRENCY, integer: 10, fraction: 0) -// SendPurpose(amountAvailable: amount, -// amountToTransfer: 543, -// fee: "0,43", -// summary: $summary, -// expireDays: $expireDays) -// } -//} -#endif