gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-taler-ios] 06/30: Notifications


From: gnunet
Subject: [taler-taler-ios] 06/30: Notifications
Date: Sun, 19 Nov 2023 23:53:30 +0100

This is an automated email from the git hooks/post-receive script.

marc-stibane pushed a commit to branch master
in repository taler-ios.

commit a914a934b9268d65b8db53ee4d2d1723b47b5f3d
Author: Marc Stibane <marc@taler.net>
AuthorDate: Fri Nov 17 16:46:58 2023 +0100

    Notifications
---
 TalerWallet1/Backend/WalletCore.swift              | 52 ++++++++----
 TalerWallet1/Controllers/PublicConstants.swift     | 10 ++-
 .../Views/Transactions/TransactionDetailView.swift | 92 +++++++++++-----------
 3 files changed, 92 insertions(+), 62 deletions(-)

diff --git a/TalerWallet1/Backend/WalletCore.swift 
b/TalerWallet1/Backend/WalletCore.swift
index 636102f..f2f53cd 100644
--- a/TalerWallet1/Backend/WalletCore.swift
+++ b/TalerWallet1/Backend/WalletCore.swift
@@ -184,26 +184,46 @@ extension WalletCore {
     @MainActor private func handleStateTransition(_ jsonData: Data) throws {
         do {
             let decoded = try JSONDecoder().decode(TransactionTransition.self, 
from: jsonData)
-            if decoded.newTxState != decoded.oldTxState {
-                let components = decoded.transactionId.components(separatedBy: 
":")
-                if components.count >= 3 {  // txn:$txtype:$uid
-                    if let type = TransactionType(rawValue: components[1]) {
-                        guard type != .refresh else { return }
-                        if decoded.newTxState.major == .done {
+            guard decoded.newTxState != decoded.oldTxState else {
+                // TODO: Same state usually means that an error is transmitted
+                logger.info("No State change: \(decoded.transactionId, 
privacy: .private(mask: .hash))")
+                return
+            }
+            let components = decoded.transactionId.components(separatedBy: ":")
+            if components.count >= 3 {  // txn:$txtype:$uid
+                if let type = TransactionType(rawValue: components[1]) {
+                    guard type != .refresh else { return }
+                    switch decoded.newTxState.major {
+                        case .done:
                             logger.info("Done: \(decoded.transactionId, 
privacy: .private(mask: .hash))")
                             Controller.shared.playSound(type.isIncoming ? 2 : 
1)
-                        } else if decoded.newTxState.major == .expired {
+                            postNotification(.TransactionDone,
+                                             userInfo: [TRANSACTIONTRANSITION: 
decoded])
+                        case .expired:
                             logger.log("Expired: \(decoded.transactionId, 
privacy: .private(mask: .hash))")
                             Controller.shared.playSound(0)
-                        }
-                        postNotification(.TransactionStateTransition,
-                                         userInfo: [TRANSACTIONTRANSITION: 
decoded])
-                    }
-                }
-            } else {
-                // TODO: Same state usually means that an error is transmitted
-                logger.info("No State change: \(decoded.transactionId, 
privacy: .private(mask: .hash))")
-            }
+                            postNotification(.TransactionExpired,
+                                             userInfo: [TRANSACTIONTRANSITION: 
decoded])
+                        case .pending:
+                            if let newMinor = decoded.newTxState.minor {
+                                if newMinor == .ready {
+                                    postNotification(.PendingReady,
+                                                     userInfo: 
[TRANSACTIONTRANSITION: decoded])
+                                } else if newMinor == .exchangeWaitReserve     
 // user did confirm on bank website
+                                       || newMinor == .withdrawCoins {         
 // coin-withdrawal has started
+                                    postNotification(.DismissSheet,
+                                                     userInfo: 
[TRANSACTIONTRANSITION: decoded])
+                                } else if newMinor == .kyc {       // user did 
confirm on bank website, but KYC is needed
+                                    postNotification(.KYCrequired,
+                                                     userInfo: 
[TRANSACTIONTRANSITION: decoded])
+                                }
+                            }
+                        default: break
+                    } // switch
+                    postNotification(.TransactionStateTransition,
+                                     userInfo: [TRANSACTIONTRANSITION: 
decoded])
+                } // type
+            } // 3 components
         } catch {       // rethrows
             symLog.log(jsonData)       // TODO: .error
             throw WalletBackendError.deserializationError
diff --git a/TalerWallet1/Controllers/PublicConstants.swift 
b/TalerWallet1/Controllers/PublicConstants.swift
index ddcd126..69da359 100644
--- a/TalerWallet1/Controllers/PublicConstants.swift
+++ b/TalerWallet1/Controllers/PublicConstants.swift
@@ -46,12 +46,20 @@ public let EXCHANGEBASEURL = "exchangeBaseUrl"
 public let TALERURI = "talerUri"
 
 public let TRANSACTIONTRANSITION = "transactionTransition"
+public let TRANSACTIONID = "transactionID"
 
 /// Notifications sent by wallet-core
 extension Notification.Name {
     static let BalanceChange = Notification.Name("balance-change")
-    static let TransactionStateTransition = 
Notification.Name(TransactionTransition.TransitionType.transition.rawValue)
     static let ExchangeAdded = Notification.Name("exchange-added")
+    static let TransactionStateTransition = 
Notification.Name(TransactionTransition.TransitionType.transition.rawValue)
+    static let TransactionDone = Notification.Name("transaction-done")
+    static let TransactionExpired = Notification.Name("transaction-expired")
+    static let PendingReady = Notification.Name("pending-ready")
+    static let WaitReserve = Notification.Name("wait-reserve")
+    static let WithdrawCoins = Notification.Name("withdraw-coins")
+    static let KYCrequired = Notification.Name("kyc-required")
+    static let DismissSheet = Notification.Name("dismiss-sheet")
     static let PendingOperationProcessed = 
Notification.Name("pending-operation-processed")
     static let ReserveNotYetFound = Notification.Name("reserve-not-yet-found")
 //    static let WithdrawalGroupBankConfirmed = 
Notification.Name("withdrawal-group-bank-confirmed")
diff --git a/TalerWallet1/Views/Transactions/TransactionDetailView.swift 
b/TalerWallet1/Views/Transactions/TransactionDetailView.swift
index 31e8780..d714f03 100644
--- a/TalerWallet1/Views/Transactions/TransactionDetailView.swift
+++ b/TalerWallet1/Views/Transactions/TransactionDetailView.swift
@@ -56,6 +56,31 @@ struct TransactionDetailView: View {
         return nil
     }
 
+    func loadTransaction(_ txId: String) async {
+        do {
+            let reloadedTransaction = try await reloadAction(txId)
+            symLog.log("reloaded transaction: 
\(reloadedTransaction.common.txState.major)")
+            withAnimation() { transaction = reloadedTransaction; viewId = 
UUID() }      // redraw
+        } catch {
+            symLog.log(error.localizedDescription)
+            withAnimation() { transaction = Transaction(dummyCurrency: 
DEMOCURRENCY); viewId = UUID() }
+        }
+    }
+
+    @discardableResult
+    func checkDismiss(_ notification: Notification, _ logStr: String = "") -> 
Bool {
+        if let doneAction {
+            if let transition = notification.userInfo?[TRANSACTIONTRANSITION] 
as? TransactionTransition {
+                if transition.transactionId == 
transaction.common.transactionId {       // is the transition for THIS 
transaction?
+                    symLog.log(logStr)
+                    doneAction()        // if this view is in a sheet then 
dissmiss the sheet
+                    return true
+                }
+            }
+        }
+        return false
+    }
+
     var body: some View {
 #if DEBUG
         let _ = Self._printChanges()
@@ -116,45 +141,28 @@ struct TransactionDetailView: View {
                             .padding(.horizontal)
                     }
                 }
-        }.onNotification(.TransactionStateTransition) { notification in
+        }
+        .onNotification(.TransactionExpired) { notification in
+            if checkDismiss(notification, "newTxState.major == expired  => 
dismiss sheet") {
+    // TODO:                  logger.info("newTxState.major == expired  => 
dismiss sheet")
+            }
+        }
+        .onNotification(.TransactionDone) { notification in
+            checkDismiss(notification, "newTxState.major == done  => dismiss 
sheet")
+        }
+        .onNotification(.DismissSheet) { notification in
+            checkDismiss(notification, "exchangeWaitReserve or withdrawCoins  
=> dismiss sheet")
+        }
+        .onNotification(.TransactionStateTransition) { notification in
             if let transition = notification.userInfo?[TRANSACTIONTRANSITION] 
as? TransactionTransition {
                 if transition.transactionId == common.transactionId {       // 
is the transition for THIS transaction?
                     let newMajor = transition.newTxState.major
-                    let newMinor = transition.newTxState.minor
-                    if let doneAction {
-                        if newMajor == .done {
-                            symLog.log("newTxState.major == done  => dismiss 
sheet")
-// TODO:                           logger.info("newTxState.major == done  => 
dismiss sheet")
-                            doneAction()        // if this view is in a sheet 
this action will dissmiss it
-                        } else if newMajor == .expired {
-                            symLog.log("newTxState.major == expired  => 
dismiss sheet")
-// TODO:                           logger.info("newTxState.major == expired  
=> dismiss sheet")
-                            doneAction()        // if this view is in a sheet 
this action will dissmiss it
-                        } else if newMajor == .pending {
-                            if let newMinor {
-                                if newMinor == .exchangeWaitReserve { // user 
did confirm on bank website
-                                    symLog.log("newTxState.minor == 
exchangeWaitReserve => dismiss sheet")
-                                    doneAction()        // if this view is in 
a sheet this action will dissmiss it
-                                } else if newMinor == .withdrawCoins { // 
coin-withdrawal has started
-                                    symLog.log("newTxState.minor == 
withdrawCoins => dismiss sheet")
-                                    doneAction()        // if this view is in 
a sheet this action will dissmiss it
-                                } else {
-                                    symLog.log("ignoring newTxState: 
\(newMajor):\(newMinor)")
-                                }
-                            }
-                        } else {
-                            symLog.log("ignoring newTxState.major: 
\(newMajor)")
-                        }
-                    } else { Task { // runs on MainActor
-                        do {
-                            symLog.log("newState: \(newMajor), reloading 
transaction")
-                            withAnimation() { transaction = 
Transaction(dummyCurrency: DEMOCURRENCY); viewId = UUID() }
-                            let reloadedTransaction = try await 
reloadAction(common.transactionId)
-                            symLog.log("reloaded transaction: 
\(reloadedTransaction.common.txState.major)")
-                            withAnimation() { transaction = 
reloadedTransaction; viewId = UUID() }      // redraw
-                      } catch {
-                          symLog.log(error.localizedDescription)
-                    }}}
+                    Task { // runs on MainActor
+                        // flush the screen first, then reload
+                        withAnimation() { transaction = 
Transaction(dummyCurrency: DEMOCURRENCY); viewId = UUID() }
+                        symLog.log("newState: \(newMajor), reloading 
transaction")
+                        await loadTransaction(common.transactionId)
+                    }
                 }
             } else { // Yikes - should never happen
 // TODO:                logger.warning("Can't get notification.userInfo as 
TransactionTransition")
@@ -163,14 +171,8 @@ struct TransactionDetailView: View {
         }
         .navigationTitle(navTitle ?? navTitle2)
         .task {
-            do {
-                symLog.log("task - load transaction")
-                let reloadedTransaction = try await reloadAction(transactionId)
-                withAnimation() { transaction = reloadedTransaction; viewId = 
UUID() }      // redraw
-            } catch {
-                symLog.log(error)
-                withAnimation() { transaction = Transaction(dummyCurrency: 
DEMOCURRENCY); viewId = UUID() }
-            }
+            symLog.log("task - load transaction")
+            await loadTransaction(transactionId)
         }
         .onAppear {
             symLog.log("onAppear")
@@ -224,7 +226,7 @@ struct TransactionDetailView: View {
                                             }
                                         }
                                     }
-                            }
+                            } // switch
                         } // ManualDetails or Confirm with bank
                         ThreeAmountsSheet(common: common, topAbbrev: 
String(localized: "Chosen:"),
                                         topTitle: String(localized: "Chosen 
amount to withdraw:"),

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]