From ee1b16a9ec07b4cdaa6d55f367678f66dcb40270 Mon Sep 17 00:00:00 2001 From: Brian Sztamfater Date: Tue, 5 Nov 2024 20:31:44 -0300 Subject: [PATCH] feat(wallet): simplify send flow ux Signed-off-by: Brian Sztamfater --- .../contexts/wallet/common/wizard/events.cljs | 16 +--- .../contexts/wallet/common/wizard/utils.cljs | 14 ++++ .../contexts/wallet/send/events.cljs | 80 +++++++++++++------ .../wallet/sheets/network_selection/view.cljs | 27 +++++-- src/status_im/subs/wallet/send.cljs | 36 ++++++++- 5 files changed, 125 insertions(+), 48 deletions(-) create mode 100644 src/status_im/contexts/wallet/common/wizard/utils.cljs diff --git a/src/status_im/contexts/wallet/common/wizard/events.cljs b/src/status_im/contexts/wallet/common/wizard/events.cljs index a6312f80e5..fcc9609a4a 100644 --- a/src/status_im/contexts/wallet/common/wizard/events.cljs +++ b/src/status_im/contexts/wallet/common/wizard/events.cljs @@ -1,23 +1,11 @@ (ns status-im.contexts.wallet.common.wizard.events - (:require [status-im.contexts.wallet.bridge.flow-config :as wallet-bridge-flow] - [status-im.contexts.wallet.send.flow-config :as wallet-send-flow] + (:require [status-im.contexts.wallet.common.wizard.utils :as wizard-utils] [utils.re-frame :as rf])) -(defn- wizard-find-next-screen - [db flow-id current-screen] - (let [flow-config (case flow-id - :wallet-send-flow wallet-send-flow/steps - :wallet-bridge-flow wallet-bridge-flow/steps - nil)] - (first (filter (fn [{:keys [skip-step? screen-id]}] - (and (not= screen-id current-screen) - (not (and (fn? skip-step?) (skip-step? db))))) - flow-config)))) - (rf/reg-event-fx :wallet/wizard-navigate-forward (fn [{:keys [db]} [{:keys [current-screen flow-id start-flow?]}]] - (let [next-screen (wizard-find-next-screen db flow-id current-screen)] + (let [next-screen (wizard-utils/wizard-find-next-screen db flow-id current-screen)] {:fx [[:dispatch (if start-flow? [:open-modal (:screen-id next-screen)] diff --git a/src/status_im/contexts/wallet/common/wizard/utils.cljs b/src/status_im/contexts/wallet/common/wizard/utils.cljs new file mode 100644 index 0000000000..4b17c26a07 --- /dev/null +++ b/src/status_im/contexts/wallet/common/wizard/utils.cljs @@ -0,0 +1,14 @@ +(ns status-im.contexts.wallet.common.wizard.utils + (:require [status-im.contexts.wallet.bridge.flow-config :as wallet-bridge-flow] + [status-im.contexts.wallet.send.flow-config :as wallet-send-flow])) + +(defn wizard-find-next-screen + [db flow-id current-screen] + (let [flow-config (case flow-id + :wallet-send-flow wallet-send-flow/steps + :wallet-bridge-flow wallet-bridge-flow/steps + nil)] + (first (filter (fn [{:keys [skip-step? screen-id]}] + (and (not= screen-id current-screen) + (not (and (fn? skip-step?) (skip-step? db))))) + flow-config)))) diff --git a/src/status_im/contexts/wallet/send/events.cljs b/src/status_im/contexts/wallet/send/events.cljs index 48b98852ff..bf502b879e 100644 --- a/src/status_im/contexts/wallet/send/events.cljs +++ b/src/status_im/contexts/wallet/send/events.cljs @@ -6,6 +6,7 @@ [status-im.contexts.wallet.collectible.utils :as collectible.utils] [status-im.contexts.wallet.common.utils :as utils] [status-im.contexts.wallet.common.utils.networks :as network-utils] + [status-im.contexts.wallet.common.wizard.utils :as wizard-utils] [status-im.contexts.wallet.data-store :as data-store] [status-im.contexts.wallet.send.utils :as send-utils] [taoensso.timbre :as log] @@ -13,7 +14,8 @@ [utils.hex :as utils.hex] [utils.money :as utils.money] [utils.number] - [utils.re-frame :as rf])) + [utils.re-frame :as rf] + [status-im.contexts.wallet.sheets.network-selection.view :as network-selection])) (rf/reg-event-fx :wallet/clean-send-data (fn [{:keys [db]}] @@ -184,7 +186,8 @@ (rf/reg-event-fx :wallet/set-token-to-send - (fn [{:keys [db]} [{:keys [token-symbol token stack-id start-flow? owners]} entry-point]] + (fn [{:keys [db]} + [{:keys [token-symbol token network stack-id start-flow? owners] :as params} entry-point]] ;; `token` is a map extracted from the sender, but in the wallet home page we don't know the ;; sender yet, so we only provide the `token-symbol`, later in ;; `:wallet/select-from-account` the `token` key will be set. @@ -202,14 +205,17 @@ test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?]) network-details (-> (get-in db [:wallet :networks (if test-networks-enabled? :test :prod)]) - (network-utils/sorted-networks-with-details))] + (network-utils/sorted-networks-with-details)) + next-screen (:screen-id (wizard-utils/wizard-find-next-screen db + :wallet-send-flow + stack-id))] + (println next-screen "432432342") (when (or token-data token-symbol) {:db (cond-> db - :always (update-in [:wallet :ui :send] + network (update-in [:wallet :ui :send] #(-> % (dissoc :collectible :tx-type) - (assoc :token-not-supported-in-receiver-networks? - unsupported-token?))) + (assoc :network network))) token-symbol (assoc-in [:wallet :ui :send :token-symbol] token-symbol) token-data (update-in [:wallet :ui :send] #(assoc % @@ -221,17 +227,29 @@ :token-display-name (:symbol token-data))) unique-owner (assoc-in [:wallet :current-viewing-account-address] unique-owner) entry-point (assoc-in [:wallet :ui :send :entry-point] entry-point)) - :fx [[:dispatch [:wallet/stop-and-clean-suggested-routes]] - [:dispatch - ;; ^:flush-dom allows us to make sure the re-frame DB state is always synced - ;; before the navigation occurs, so the new screen is always rendered with - ;; the DB state set by this event. By adding the metadata we are omitting - ;; a 1-frame blink when the screen is mounted. - ^:flush-dom - [:wallet/wizard-navigate-forward - {:current-screen stack-id - :start-flow? start-flow? - :flow-id :wallet-send-flow}]]]})))) + :fx (if (or (= next-screen :screen/wallet.select-from) (some? network)) + [[:dispatch [:wallet/stop-and-clean-suggested-routes]] + [:dispatch + ;; ^:flush-dom allows us to make sure the re-frame DB state is always synced + ;; before the navigation occurs, so the new screen is always rendered with + ;; the DB state set by this event. By adding the metadata we are omitting + ;; a 1-frame blink when the screen is mounted. + ^:flush-dom + [:wallet/wizard-navigate-forward + {:current-screen stack-id + :start-flow? start-flow? + :flow-id :wallet-send-flow}]]] + [[:dispatch + [:show-bottom-sheet + {:content (fn [] + [network-selection/view + {:token-symbol (or token-symbol (:symbol token-data)) + :source :send + :on-select-network (fn [network] + (rf/dispatch [:hide-bottom-sheet]) + (rf/dispatch + [:wallet/set-token-to-send + (assoc params :network network)]))}])}]]])})))) (rf/reg-event-fx :wallet/edit-token-to-send @@ -705,7 +723,7 @@ (rf/reg-event-fx :wallet/select-from-account - (fn [{db :db} [{:keys [address stack-id network-details start-flow?]}]] + (fn [{db :db} [{:keys [address stack-id network-details network start-flow?] :as params}]] (let [{:keys [token-symbol tx-type]} (-> db :wallet :ui :send) token (when token-symbol @@ -725,14 +743,28 @@ :wallet-bridge-flow :wallet-send-flow)] {:db (cond-> db + network (assoc-in [:wallet :ui :send :network] network) token-symbol (assoc-in [:wallet :ui :send :token] token) bridge-tx? (assoc-in [:wallet :ui :send :to-address] address)) - :fx [[:dispatch [:wallet/switch-current-viewing-account address]] - [:dispatch - [:wallet/wizard-navigate-forward - {:current-screen stack-id - :start-flow? start-flow? - :flow-id flow-id}]]]}))) + :fx (if (some? network) + [[:dispatch [:wallet/switch-current-viewing-account address]] + [:dispatch + [:wallet/wizard-navigate-forward + {:current-screen stack-id + :start-flow? start-flow? + :flow-id flow-id}]]] + [[:dispatch [:wallet/switch-current-viewing-account address]] + [:dispatch + [:show-bottom-sheet + {:content (fn [] + [network-selection/view + {:token-symbol (or token-symbol (:symbol token)) + :source :send + :on-select-network (fn [network] + (rf/dispatch [:hide-bottom-sheet]) + (rf/dispatch + [:wallet/select-from-account + (assoc params :network network)]))}])}]]])}))) (rf/reg-event-fx :wallet/transaction-confirmation-navigate-back diff --git a/src/status_im/contexts/wallet/sheets/network_selection/view.cljs b/src/status_im/contexts/wallet/sheets/network_selection/view.cljs index 3b4ed178ac..946f64d03c 100644 --- a/src/status_im/contexts/wallet/sheets/network_selection/view.cljs +++ b/src/status_im/contexts/wallet/sheets/network_selection/view.cljs @@ -8,12 +8,17 @@ [utils.re-frame :as rf])) (defn- network-item - [{:keys [network on-select-network]}] + [{:keys [network on-select-network]} _ _ {:keys [source]}] (let [{:keys [network-name - chain-id]} network + chain-id]} network {balance-in-crypto :crypto - balance-in-fiat :fiat} (rf/sub [:wallet/swap-asset-to-pay-network-balance chain-id]) - mainnet? (= network-name constants/mainnet-network-name)] + balance-in-fiat :fiat} (case source + :swap + (rf/sub [:wallet/swap-asset-to-pay-network-balance chain-id]) + :send + (rf/sub [:wallet/send-token-network-balance chain-id])) + mainnet? + (= network-name constants/mainnet-network-name)] [quo/network-list {:label (name network-name) :network-image (quo.resources/get-network network-name) @@ -23,10 +28,14 @@ :container-style (style/network-list-container mainnet?)}])) (defn view - [{:keys [on-select-network]}] - (let [token-symbol (rf/sub [:wallet/swap-asset-to-pay-token-symbol]) - {mainnet-network :mainnet-network - layer-2-networks :layer-2-networks} (rf/sub [:wallet/swap-asset-to-pay-networks]) + [{:keys [token-symbol on-select-network source] + :or {source :swap}}] + (let [{mainnet-network :mainnet-network + layer-2-networks :layer-2-networks} (case source + :swap + (rf/sub [:wallet/swap-asset-to-pay-networks]) + :send + (rf/sub [:wallet/send-token-grouped-networks])) render-fn (rn/use-callback (fn [network] [network-item {:network network @@ -46,10 +55,12 @@ (when mainnet-network [network-item {:network mainnet-network + :source source :on-select-network on-select-network}]) [quo/divider-label {:container-style style/divider-label} (i18n/label :t/layer-2)] [rn/flat-list {:data (vec layer-2-networks) + :render-data {:source source} :render-fn render-fn :scroll-enabled false}]])) diff --git a/src/status_im/subs/wallet/send.cljs b/src/status_im/subs/wallet/send.cljs index 0458839c76..56ce93ecfc 100644 --- a/src/status_im/subs/wallet/send.cljs +++ b/src/status_im/subs/wallet/send.cljs @@ -2,7 +2,7 @@ (:require [re-frame.core :as rf] [status-im.constants :as constants] - [status-im.contexts.wallet.common.activity-tab.constants :as activity-constants] + [status-im.contexts.wallet.common.activity-tab.constants :as activity-tab-constants] [status-im.contexts.wallet.common.utils :as common-utils] [status-im.contexts.wallet.send.utils :as send-utils] [utils.money :as money] @@ -77,7 +77,7 @@ (->> address-activity (sort :timestamp) (keep (fn [{:keys [activity-type recipient]}] - (when (= activity-constants/wallet-activity-type-send activity-type) + (when (= activity-tab-constants/wallet-activity-type-send activity-type) recipient))) (distinct))))) @@ -172,3 +172,35 @@ (= (:chain-id network) bridge-to-chain-id) network)) networks)))) + +(rf/reg-sub + :wallet/send-token-grouped-networks + :<- [:wallet/wallet-send-token] + (fn [token] + (let [{token-networks :networks} token + grouped-networks (group-by :layer + token-networks) + mainnet-network (first (get grouped-networks constants/layer-1-network)) + layer-2-networks (get grouped-networks constants/layer-2-network)] + {:mainnet-network mainnet-network + :layer-2-networks layer-2-networks}))) + +(rf/reg-sub + :wallet/send-token-network-balance + :<- [:wallet/wallet-send-token] + :<- [:profile/currency] + :<- [:profile/currency-symbol] + (fn [[token currency currency-symbol] [_ chain-id]] + (let [{:keys [balances-per-chain + decimals]} token + balance-for-chain (get balances-per-chain chain-id) + total-balance (money/token->unit (:raw-balance balance-for-chain) decimals) + fiat-value (common-utils/calculate-token-fiat-value + {:currency currency + :balance total-balance + :token token}) + crypto-formatted (common-utils/get-standard-crypto-format token total-balance) + fiat-formatted (common-utils/fiat-formatted-for-ui currency-symbol + fiat-value)] + {:crypto (str crypto-formatted " " (:symbol token)) + :fiat fiat-formatted})))