From 025c38ae88380e286da1b0df0a34e7458a9e964f Mon Sep 17 00:00:00 2001 From: Brian Sztamfater Date: Thu, 8 Feb 2024 16:29:05 -0300 Subject: [PATCH] fix: address is lost on re-render (#18593) Signed-off-by: Brian Sztamfater --- .../contexts/shell/jump_to/events.cljs | 7 ++- .../contexts/wallet/send/events.cljs | 16 +++--- .../send/input_amount/component_spec.cljs | 3 +- .../wallet/send/input_amount/view.cljs | 19 ++++--- .../wallet/send/select_address/view.cljs | 57 ++++++++++--------- .../send/transaction_confirmation/view.cljs | 5 +- src/status_im/navigation/events.cljs | 46 ++++++++++++--- src/status_im/subs/navigation.cljs | 10 ++++ src/status_im/subs/root.cljs | 2 + 9 files changed, 110 insertions(+), 55 deletions(-) create mode 100644 src/status_im/subs/navigation.cljs diff --git a/src/status_im/contexts/shell/jump_to/events.cljs b/src/status_im/contexts/shell/jump_to/events.cljs index 31214bf88e..0d8ce65d06 100644 --- a/src/status_im/contexts/shell/jump_to/events.cljs +++ b/src/status_im/contexts/shell/jump_to/events.cljs @@ -149,7 +149,9 @@ (not hidden-screen?) (:current-chat-id db)) (conj [:chat/close]))}) - {:db (assoc db :view-id go-to-view-id) + {:db (-> db + (assoc :view-id go-to-view-id) + (dissoc :modal-view-ids)) :navigate-to go-to-view-id})) (rf/defn shell-navigate-back @@ -174,7 +176,8 @@ shell.constants/close-screen-with-slide-to-right-animation))} (when (and current-chat-id community-id) {:dispatch [:shell/add-switcher-card shell.constants/community-screen community-id]})) - {:navigate-back nil}))) + {:navigate-back nil + :db (dissoc db :modal-view-ids)}))) (rf/defn floating-screen-opened {:events [:shell/floating-screen-opened]} diff --git a/src/status_im/contexts/wallet/send/events.cljs b/src/status_im/contexts/wallet/send/events.cljs index 0a58ed2218..a418fea4d6 100644 --- a/src/status_im/contexts/wallet/send/events.cljs +++ b/src/status_im/contexts/wallet/send/events.cljs @@ -52,7 +52,7 @@ {:db (-> db (assoc-in [:wallet :ui :send :send-account-address] address) (update-in [:wallet :ui :send] dissoc :to-address)) - :fx [[:navigate-to-within-stack [:wallet-select-asset stack-id]]]})) + :fx [[:dispatch [:navigate-to-within-stack [:wallet-select-asset stack-id]]]]})) (rf/reg-event-fx :wallet/clean-send-address (fn [{:keys [db]}] @@ -72,10 +72,11 @@ (assoc-in [:wallet :ui :send :to-address] to-address) (assoc-in [:wallet :ui :send :address-prefix] prefix) (assoc-in [:wallet :ui :send :selected-networks] selected-networks)) - :fx [[:navigate-to-within-stack - (if token - [:wallet-send-input-amount stack-id] - [:wallet-select-asset stack-id])]]}))) + :fx [[:dispatch + [:navigate-to-within-stack + (if token + [:wallet-send-input-amount stack-id] + [:wallet-select-asset stack-id])]]]}))) (rf/reg-event-fx :wallet/update-receiver-networks @@ -87,7 +88,8 @@ {:db (-> db (update-in [:wallet :ui :send] dissoc :collectible) (assoc-in [:wallet :ui :send :token] token)) - :fx [[:navigate-to-within-stack [:wallet-send-input-amount stack-id]]]})) + :fx [[:dispatch [:wallet/clean-suggested-routes]] + [:dispatch [:navigate-to-within-stack [:wallet-send-input-amount stack-id]]]]})) (rf/reg-event-fx :wallet/send-select-token-drawer @@ -110,7 +112,7 @@ (rf/reg-event-fx :wallet/send-select-amount (fn [{:keys [db]} [{:keys [amount stack-id]}]] {:db (assoc-in db [:wallet :ui :send :amount] amount) - :fx [[:navigate-to-within-stack [:wallet-transaction-confirmation stack-id]]]})) + :fx [[:dispatch [:navigate-to-within-stack [:wallet-transaction-confirmation stack-id]]]]})) (rf/reg-event-fx :wallet/get-suggested-routes (fn [{:keys [db now]} [amount]] diff --git a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs index 8b64ab64a0..a2ce5e84e2 100644 --- a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs @@ -45,7 +45,8 @@ :wallet/wallet-send-loading-suggested-routes? false :wallet/wallet-send-route {:route []} :wallet/wallet-send-suggested-routes {:candidates []} - :wallet/wallet-send-selected-networks []}) + :wallet/wallet-send-selected-networks [] + :navigation/current-screen-id :wallet-send-input-amount}) (defn- render [component] diff --git a/src/status_im/contexts/wallet/send/input_amount/view.cljs b/src/status_im/contexts/wallet/send/input_amount/view.cljs index b347248db6..7236cdb6b4 100644 --- a/src/status_im/contexts/wallet/send/input_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/view.cljs @@ -135,13 +135,18 @@ (rf/dispatch [:wallet/clean-selected-token]) (rf/dispatch [:navigate-back-within-stack :wallet-send-input-amount])) fetch-routes (fn [input-num-value current-limit-amount] - (rf/dispatch [:wallet/clean-suggested-routes]) - (when-not (or (empty? @input-value) - (<= input-num-value 0) - (> input-num-value current-limit-amount)) - (debounce/debounce-and-dispatch - [:wallet/get-suggested-routes @input-value] - 100))) + (let [current-screen-id (rf/sub [:navigation/current-screen-id])] + ; this check is to prevent effect being triggered when screen is + ; loaded but not being shown to the user (deep in the navigation + ; stack) and avoid undesired behaviors + (when (= current-screen-id :wallet-send-input-amount) + (if-not (or (empty? @input-value) + (<= input-num-value 0) + (> input-num-value current-limit-amount)) + (debounce/debounce-and-dispatch + [:wallet/get-suggested-routes @input-value] + 100) + (rf/dispatch [:wallet/clean-suggested-routes]))))) handle-on-confirm (fn [] (rf/dispatch [:wallet/send-select-amount {:amount @input-value diff --git a/src/status_im/contexts/wallet/send/select_address/view.cljs b/src/status_im/contexts/wallet/send/select_address/view.cljs index 6e865acea2..4d19c38a8e 100644 --- a/src/status_im/contexts/wallet/send/select_address/view.cljs +++ b/src/status_im/contexts/wallet/send/select_address/view.cljs @@ -24,7 +24,8 @@ (defn- address-input [input-value input-focused?] (fn [] - (let [scanned-address (rf/sub [:wallet/scanned-address]) + (let [current-screen-id (rf/sub [:navigation/current-screen-id]) + scanned-address (rf/sub [:wallet/scanned-address]) send-address (rf/sub [:wallet/wallet-send-to-address]) recipient (rf/sub [:wallet/wallet-send-recipient]) recipient-plain-address? (= send-address recipient) @@ -32,29 +33,37 @@ chain-id (rf/sub [:chain-id]) contacts (rf/sub [:contacts/active])] [quo/address-input - {:on-focus #(reset! input-focused? true) - :on-blur #(reset! input-focused? false) - :on-scan (fn [] - (rn/dismiss-keyboard!) - (rf/dispatch [:wallet/clean-scanned-address]) - (rf/dispatch [:open-modal :scan-address])) - :ens-regex constants/regx-ens - :scanned-value (or (when recipient-plain-address? send-address) scanned-address) - :address-regex constants/regx-multichain-address - :on-detect-address #(debounce/debounce-and-dispatch - [:wallet/validate-address %] - 300) - :on-detect-ens (fn [text cb] + {:on-focus #(reset! input-focused? true) + :on-blur #(reset! input-focused? false) + :on-scan (fn [] + (rn/dismiss-keyboard!) + (rf/dispatch [:wallet/clean-scanned-address]) + (rf/dispatch [:open-modal :scan-address])) + :ens-regex constants/regx-ens + :scanned-value (or (when recipient-plain-address? send-address) scanned-address) + :address-regex constants/regx-multichain-address + :on-detect-address #(when (or (= current-screen-id :wallet-select-address) + (= current-screen-id :scan-address)) + ; ^ this check is to prevent effect being triggered when screen is + ; loaded but not being shown to the user (deep in the navigation + ; stack) and avoid undesired behaviors (debounce/debounce-and-dispatch - [:wallet/find-ens text contacts chain-id cb] + [:wallet/validate-address %] 300)) - :on-detect-unclassified #(when valid-ens-or-address? - (rf/dispatch [:wallet/clean-ens-or-address-validation])) - :on-change-text (fn [text] - (when (empty? text) - (rf/dispatch [:wallet/clean-local-suggestions])) - (reset! input-value text)) - :valid-ens-or-address? valid-ens-or-address?}]))) + :on-detect-ens (fn [text cb] + (when (or (= current-screen-id :wallet-select-address) + (= current-screen-id :scan-address)) + ; ^ this check is to prevent effect being triggered when screen + ; is loaded but not being shown to the user (deep in the + ; navigation stack) and avoid undesired behaviors + (debounce/debounce-and-dispatch + [:wallet/find-ens text contacts chain-id cb] + 300))) + :on-change-text (fn [text] + (when (empty? text) + (rf/dispatch [:wallet/clean-local-suggestions])) + (reset! input-value text)) + :valid-ens-or-address? valid-ens-or-address?}]))) (defn- ens-linked-address [{:keys [address networks theme]}] @@ -133,10 +142,6 @@ token (rf/sub [:wallet/wallet-send-token]) valid-ens-or-address? (boolean (rf/sub [:wallet/valid-ens-or-address?])) {:keys [color]} (rf/sub [:wallet/current-viewing-account])] - (rn/use-effect (fn [] - (fn [] - (rf/dispatch [:wallet/clean-scanned-address]) - (rf/dispatch [:wallet/clean-local-suggestions])))) [floating-button-page/view {:footer-container-padding 0 :header [account-switcher/view diff --git a/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs b/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs index 385ee0be6a..3de81ba39c 100644 --- a/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs +++ b/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs @@ -137,10 +137,7 @@ (defn- view-internal [_] - (let [on-close (fn [] - (rf/dispatch [:wallet/clean-suggested-routes]) - (rf/dispatch [:navigate-back-within-stack :wallet-select-asset]))] - + (let [on-close #(rf/dispatch [:navigate-back-within-stack :wallet-select-asset])] (fn [{:keys [theme]}] (let [send-transaction-data (rf/sub [:wallet/wallet-send]) token (:token send-transaction-data) diff --git a/src/status_im/navigation/events.cljs b/src/status_im/navigation/events.cljs index aae59916d4..efcca5347a 100644 --- a/src/status_im/navigation/events.cljs +++ b/src/status_im/navigation/events.cljs @@ -24,38 +24,67 @@ :dispatch-n [[:hide-bottom-sheet]]} (shell.events/shell-navigate-to go-to-view-id screen-params nil nil))) +(defn- add-view-to-modals + [modal-view-ids new-id] + (if (seq modal-view-ids) + (conj modal-view-ids new-id) + modal-view-ids)) + (rf/defn navigate-to-within-stack {:events [:navigate-to-within-stack]} - [_ comp-id] - {:navigate-to-within-stack comp-id}) + [{:keys [db]} comp-id] + {:db (update db :modal-view-ids add-view-to-modals (first comp-id)) + :fx [[:navigate-to-within-stack comp-id]]}) (re-frame/reg-event-fx :open-modal (fn [{:keys [db]} [component screen-params]] {:db (-> db (assoc :view-id component) + (assoc :modal-view-ids [component]) (all-screens-params component screen-params)) :fx [[:dispatch [:hide-bottom-sheet]] [:open-modal-fx component]]})) (rf/defn dismiss-modal {:events [:dismiss-modal]} - [_ comp-id] - {:dismiss-modal comp-id}) + [{:keys [db]} comp-id] + {:db (dissoc db :modal-view-ids) + :dismiss-modal comp-id}) (rf/defn navigate-back {:events [:navigate-back]} [cofx] (shell.events/shell-navigate-back cofx nil)) +(defn- remove-last-view-to-modals + [modal-view-ids] + (if (seq modal-view-ids) + (pop modal-view-ids) + modal-view-ids)) + (rf/defn navigate-back-within-stack {:events [:navigate-back-within-stack]} - [_ comp-id] - {:navigate-back-within-stack comp-id}) + [{:keys [db]} comp-id] + {:db (update db :modal-view-ids remove-last-view-to-modals) + :fx [[:navigate-back-within-stack comp-id]]}) + +(defn- remove-modal-views-until-comp-id + [modal-view-ids comp-id] + (let [comp-id-index (.indexOf (or modal-view-ids []) comp-id) + modal-view-ids (if (> comp-id-index -1) + (subvec modal-view-ids 0 (inc comp-id-index)) + modal-view-ids)] + modal-view-ids)) (rf/defn navigate-back-to {:events [:navigate-back-to]} - [_ comp-id] - {:navigate-back-to comp-id}) + [{:keys [db]} comp-id] + (let [modal-view-ids (remove-modal-views-until-comp-id (:modal-view-ids db) comp-id)] + (assoc {:navigate-back-to comp-id} + :db + (if modal-view-ids + (assoc db :modal-view-ids modal-view-ids) + (dissoc db :modal-view-ids))))) (rf/defn pop-to-root {:events [:pop-to-root]} @@ -64,6 +93,7 @@ :db (-> db (dissoc :shell/floating-screens) (dissoc :shell/loaded-screens) + (dissoc :modal-view-ids) (assoc :view-id (or @shell.state/selected-stack-id :shell))) :effects.shell/pop-to-root nil}) diff --git a/src/status_im/subs/navigation.cljs b/src/status_im/subs/navigation.cljs new file mode 100644 index 0000000000..d17c5b5c10 --- /dev/null +++ b/src/status_im/subs/navigation.cljs @@ -0,0 +1,10 @@ +(ns status-im.subs.navigation + (:require + [re-frame.core :as re-frame])) + +(re-frame/reg-sub + :navigation/current-screen-id + :<- [:view-id] + :<- [:modal-view-ids] + (fn [[view-id modal-view-ids]] + (or (peek modal-view-ids) view-id))) diff --git a/src/status_im/subs/root.cljs b/src/status_im/subs/root.cljs index 3c9faa4fee..15c23e7182 100644 --- a/src/status_im/subs/root.cljs +++ b/src/status_im/subs/root.cljs @@ -7,6 +7,7 @@ status-im.subs.contact status-im.subs.general status-im.subs.messages + status-im.subs.navigation status-im.subs.onboarding status-im.subs.pairing status-im.subs.profile @@ -22,6 +23,7 @@ ;;view (reg-root-key-sub :view-id :view-id) +(reg-root-key-sub :modal-view-ids :modal-view-ids) (reg-root-key-sub :screen-params :navigation/screen-params) (reg-root-key-sub :animation-shared-element-id :animation-shared-element-id)