diff --git a/src/status_im/contexts/onboarding/create_password/view.cljs b/src/status_im/contexts/onboarding/create_password/view.cljs index 1c67b24241..6dc624fe24 100644 --- a/src/status_im/contexts/onboarding/create_password/view.cljs +++ b/src/status_im/contexts/onboarding/create_password/view.cljs @@ -219,7 +219,7 @@ {:margin-top top :background :blur :icon-name :i/arrow-left - :on-press #(rf/dispatch [:navigate-back-within-stack :new-to-status]) + :on-press #(rf/dispatch [:navigate-back]) :right-side [{:icon-name :i/info :on-press on-press-info}]}] [password-form] diff --git a/src/status_im/contexts/onboarding/create_profile/view.cljs b/src/status_im/contexts/onboarding/create_profile/view.cljs index 1a6fff4da3..4471b5fc0f 100644 --- a/src/status_im/contexts/onboarding/create_profile/view.cljs +++ b/src/status_im/contexts/onboarding/create_profile/view.cljs @@ -111,7 +111,7 @@ {:margin-top navigation-bar-top :background :blur :icon-name :i/arrow-left - :on-press #(rf/dispatch [:navigate-back-within-stack :new-to-status])}] + :on-press #(rf/dispatch [:navigate-back])}] [rn/scroll-view {:on-layout (fn [event] (let [height (oops/oget event "nativeEvent.layout.height")] diff --git a/src/status_im/contexts/onboarding/enable_notifications/view.cljs b/src/status_im/contexts/onboarding/enable_notifications/view.cljs index f1452f3fc7..68c0a49180 100644 --- a/src/status_im/contexts/onboarding/enable_notifications/view.cljs +++ b/src/status_im/contexts/onboarding/enable_notifications/view.cljs @@ -76,7 +76,7 @@ [quo/page-nav {:background :blur :icon-name :i/arrow-left - :on-press #(rf/dispatch [:navigate-back-within-stack :enable-biometrics])}] + :on-press #(rf/dispatch [:navigate-back])}] [page-title]] (if blacklist/blacklisted? [enable-notifications-simple] diff --git a/src/status_im/contexts/onboarding/enter_seed_phrase/view.cljs b/src/status_im/contexts/onboarding/enter_seed_phrase/view.cljs index eb3deb1f2a..bdb6ed9033 100644 --- a/src/status_im/contexts/onboarding/enter_seed_phrase/view.cljs +++ b/src/status_im/contexts/onboarding/enter_seed_phrase/view.cljs @@ -164,5 +164,5 @@ {:margin-top navigation-bar-top :background :blur :icon-name :i/arrow-left - :on-press #(rf/dispatch [:navigate-back-within-stack :new-to-status])}] + :on-press #(rf/dispatch [:navigate-back])}] [screen]]])) diff --git a/src/status_im/contexts/onboarding/welcome/view.cljs b/src/status_im/contexts/onboarding/welcome/view.cljs index 7be10724f4..fc8ed67b0a 100644 --- a/src/status_im/contexts/onboarding/welcome/view.cljs +++ b/src/status_im/contexts/onboarding/welcome/view.cljs @@ -42,7 +42,7 @@ {:type :no-title :background :blur :icon-name :i/arrow-left - :on-press #(rf/dispatch [:navigate-back-within-stack :enable-notifications])}] + :on-press #(rf/dispatch [:navigate-back])}] [page-title] [rn/image {:style (style/page-illustration (:width window)) diff --git a/src/status_im/contexts/shell/jump_to/events.cljs b/src/status_im/contexts/shell/jump_to/events.cljs index 0d8ce65d06..d3bc7b0f2e 100644 --- a/src/status_im/contexts/shell/jump_to/events.cljs +++ b/src/status_im/contexts/shell/jump_to/events.cljs @@ -149,9 +149,7 @@ (not hidden-screen?) (:current-chat-id db)) (conj [:chat/close]))}) - {:db (-> db - (assoc :view-id go-to-view-id) - (dissoc :modal-view-ids)) + {:db (assoc db :view-id go-to-view-id) :navigate-to go-to-view-id})) (rf/defn shell-navigate-back @@ -161,7 +159,7 @@ current-view-id (:view-id db) community-id (when current-chat-id (get-in db [:chats current-chat-id :community-id]))] - (if (and (not @navigation.state/curr-modal) + (if (and (not (seq @navigation.state/modals)) (shell.utils/shell-navigation? current-view-id) (seq (shell.utils/open-floating-screens))) (merge @@ -176,8 +174,7 @@ 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 - :db (dissoc db :modal-view-ids)}))) + {:navigate-back nil}))) (rf/defn floating-screen-opened {:events [:shell/floating-screen-opened]} diff --git a/src/status_im/contexts/shell/jump_to/view.cljs b/src/status_im/contexts/shell/jump_to/view.cljs index 620a91bbaf..ddfa36f27f 100644 --- a/src/status_im/contexts/shell/jump_to/view.cljs +++ b/src/status_im/contexts/shell/jump_to/view.cljs @@ -15,7 +15,7 @@ (defn navigate-back-handler [] - (when (or @navigation.state/curr-modal + (when (or (seq @navigation.state/modals) (seq (utils/open-floating-screens))) (rf/dispatch [:navigate-back]) true)) diff --git a/src/status_im/contexts/wallet/account/bridge_send/view.cljs b/src/status_im/contexts/wallet/account/bridge_send/view.cljs index 53b90e1a61..5b59a17db9 100644 --- a/src/status_im/contexts/wallet/account/bridge_send/view.cljs +++ b/src/status_im/contexts/wallet/account/bridge_send/view.cljs @@ -15,6 +15,6 @@ :button-one-label (i18n/label :t/confirm-bridge) :button-one-props {:icon-left :i/bridge} :on-navigate-back (fn [] - (rf/dispatch [:navigate-back-within-stack :screen/wallet.bridge-send]))}]]) + (rf/dispatch [:navigate-back]))}]]) (def view (quo.theme/with-theme view-internal)) diff --git a/src/status_im/contexts/wallet/account/bridge_to/view.cljs b/src/status_im/contexts/wallet/account/bridge_to/view.cljs index 9032abbc6e..d1e2fe263d 100644 --- a/src/status_im/contexts/wallet/account/bridge_to/view.cljs +++ b/src/status_im/contexts/wallet/account/bridge_to/view.cljs @@ -48,7 +48,7 @@ {:name (string/upper-case (str (:name token)))})] [rn/view [account-switcher/view - {:on-press #(rf/dispatch [:navigate-back-within-stack :screen/wallet.bridge-to]) + {:on-press #(rf/dispatch [:navigate-back]) :icon-name :i/arrow-left :accessibility-label :top-bar}] [quo/page-top {:title bridge-to-title}] 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 b2d225e688..198696ce4f 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 @@ -53,7 +53,7 @@ :eip1559-enabled true}}] :wallet/wallet-send-suggested-routes {:candidates []} :wallet/wallet-send-selected-networks [] - :navigation/current-screen-id :screen/wallet.send-input-amount + :view-id :screen/wallet.send-input-amount :wallet/wallet-send-to-address "0x04371e2d9d66b82f056bc128064" :profile/currency-symbol "$" :wallet/token-by-symbol {:symbol :eth 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 1b5b50f919..0a4cfdb659 100644 --- a/src/status_im/contexts/wallet/send/input_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/view.cljs @@ -174,7 +174,7 @@ (reagent/flush)))) on-navigate-back on-navigate-back fetch-routes (fn [input-num-value current-limit-amount] - (let [nav-current-screen-id (rf/sub [:navigation/current-screen-id])] + (let [nav-current-screen-id (rf/sub [:view-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 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 1b8c928df4..093fbdb0fd 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,7 @@ (defn- address-input [input-value input-focused?] (fn [] - (let [current-screen-id (rf/sub [:navigation/current-screen-id]) + (let [current-screen-id (rf/sub [:view-id]) scanned-address (rf/sub [:wallet/scanned-address]) send-address (rf/sub [:wallet/wallet-send-to-address]) recipient (rf/sub [:wallet/wallet-send-recipient]) diff --git a/src/status_im/contexts/wallet/send/select_asset/view.cljs b/src/status_im/contexts/wallet/send/select_asset/view.cljs index 54e9e724f6..fe451d5b03 100644 --- a/src/status_im/contexts/wallet/send/select_asset/view.cljs +++ b/src/status_im/contexts/wallet/send/select_asset/view.cljs @@ -63,7 +63,7 @@ search-text (reagent/atom "") on-change-text #(reset! search-text %) on-change-tab #(reset! selected-tab %) - on-close #(rf/dispatch [:navigate-back-within-stack :screen/wallet.select-asset])] + on-close #(rf/dispatch [:navigate-back])] (fn [] [rn/safe-area-view {:style style/container} [account-switcher/view diff --git a/src/status_im/contexts/wallet/send/send_amount/view.cljs b/src/status_im/contexts/wallet/send/send_amount/view.cljs index 03df62d05c..a48332a7d3 100644 --- a/src/status_im/contexts/wallet/send/send_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/send_amount/view.cljs @@ -13,6 +13,6 @@ :on-navigate-back (fn [] (rf/dispatch [:wallet/clean-selected-token]) (rf/dispatch [:wallet/clean-selected-collectible]) - (rf/dispatch [:navigate-back-within-stack :screen/wallet.send-input-amount]))}]) + (rf/dispatch [:navigate-back]))}]) (def view (quo.theme/with-theme view-internal)) 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 ea8a8846da..63c73a8278 100644 --- a/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs +++ b/src/status_im/contexts/wallet/send/transaction_confirmation/view.cljs @@ -238,7 +238,7 @@ (defn- view-internal [_] (let [on-close (fn [] - (rf/dispatch [:navigate-back-within-stack :screen/wallet.transaction-confirmation]) + (rf/dispatch [:navigate-back]) (rf/dispatch [:wallet/clean-suggested-routes]) (rf/dispatch [:wallet/clean-selected-collectible]))] (fn [{:keys [theme]}] diff --git a/src/status_im/navigation/core.cljs b/src/status_im/navigation/core.cljs index a0e9367f51..a2f6e59ac8 100644 --- a/src/status_im/navigation/core.cljs +++ b/src/status_im/navigation/core.cljs @@ -24,28 +24,15 @@ (navigation/reg-app-launched-listener (fn [] (navigation/set-default-options options/default-options) - (reset! state/curr-modal false) + (reset! state/modals []) (reset! state/dissmissing false) (re-frame/dispatch [:bottom-sheet-hidden]) - (if (= @state/root-id :multiaccounts-stack) - (re-frame/dispatch-sync [:set-multiaccount-root]) - (when @state/root-id - (reset! theme/device-theme (rn/get-color-scheme)) - (re-frame/dispatch [:init-root @state/root-id]) - (re-frame/dispatch [:chat/check-last-chat]))) + (when @state/root-id + (reset! theme/device-theme (rn/get-color-scheme)) + (re-frame/dispatch [:init-root @state/root-id]) + (re-frame/dispatch [:chat/check-last-chat])) (rn/hide-splash-screen))) - (navigation/reg-component-did-appear-listener - (fn [view-id] - (let [view-id-with-prefix (keyword (str "screen/" (name view-id))) - view (or (get views/screens view-id) - (get views/screens view-id-with-prefix)) - view-id (:name view)] - (when view - (effects/set-view-id view-id) - (when-not @state/curr-modal - (reset! state/pushed-screen-id view-id)))))) - ;;;; Modal (navigation/reg-button-pressed-listener @@ -62,14 +49,10 @@ (navigation/reg-modal-dismissed-listener (fn [] + (state/navigation-pop-from (last @state/modals)) (if (> (count @state/modals) 1) - (let [new-modals (butlast @state/modals)] - (reset! state/modals (vec new-modals)) - (effects/set-view-id (last new-modals))) - (do - (reset! state/modals []) - (reset! state/curr-modal false) - (effects/set-view-id @state/pushed-screen-id))) + (reset! state/modals (vec (butlast @state/modals))) + (reset! state/modals [])) (let [component @state/dissmissing] (reset! state/dissmissing false) diff --git a/src/status_im/navigation/effects.cljs b/src/status_im/navigation/effects.cljs index 3d265cb807..126fb0c808 100644 --- a/src/status_im/navigation/effects.cljs +++ b/src/status_im/navigation/effects.cljs @@ -27,18 +27,13 @@ (when on-focus (rf/dispatch on-focus))))) -(defn set-view-id - [view-id] - (when (get views/screens view-id) - (rf/dispatch [:set-view-id view-id]))) - (defn- dismiss-all-modals [] - (when @state/curr-modal - (reset! state/curr-modal false) + (when (seq @state/modals) (reset! state/dissmissing true) (doseq [modal @state/modals] (navigation/dismiss-modal (name modal))) + (state/navigation-pop-from (first @state/modals)) (reset! state/modals []))) ;;;; Root @@ -51,7 +46,9 @@ (get roots/themes root-id) root-id]) (reset! state/root-id (or (get-in root [:root :stack :id]) root-id)) - (navigation/set-root root)))) + (navigation/set-root root) + (state/navigation-state-reset [{:id root-id + :type :root}])))) ;;;; Navigate to @@ -64,7 +61,10 @@ {:component {:id component :name component :options (merge (options/root-options {:theme (:theme options)}) - options)}}))) + options)}}) + (state/navigation-state-push {:id component + :type :stack + :parent @state/root-id}))) (rf/reg-fx :navigate-to navigate) @@ -79,43 +79,52 @@ :name component :options (merge (options/root-options {:theme (:theme options)}) - options)}}))) + options)}}) + (state/navigation-state-push {:id component + :type :stack + :parent comp-id}))) (rf/reg-fx :navigate-to-within-stack navigate-to-within-stack) -(rf/reg-fx :navigate-replace-fx - (fn [view-id] - (navigation/pop (name @state/root-id)) - (navigate view-id))) - (defn dismiss-modal ([] (dismiss-modal nil)) ([comp-id] (reset! state/dissmissing true) - (navigation/dismiss-modal (name (or comp-id (last @state/modals)))))) + (navigation/dismiss-modal (name (or comp-id (last @state/modals)))) + (state/navigation-pop-from comp-id))) -(rf/reg-fx :navigate-back - (fn [] - (if @state/curr-modal - (dismiss-modal) - (navigation/pop (name @state/root-id))))) +(defn navigate-back + [] + (when-let [{:keys [type parent id]} (last (state/get-navigation-state))] + (cond + (and (= type :modal) id) + (dismiss-modal id) + (and (= type :stack) parent) + (do + (navigation/pop (name parent)) + (state/navigation-state-pop))))) -(rf/reg-fx :navigate-back-within-stack - (fn [comp-id] - (navigation/pop (name comp-id)))) +(rf/reg-fx :navigate-back navigate-back) + +(rf/reg-fx :navigate-replace-fx + (fn [view-id] + (navigate-back) + (navigate view-id))) (rf/reg-fx :navigate-back-to (fn [comp-id] - (navigation/pop-to (name comp-id)))) + (navigation/pop-to (name comp-id)) + (state/navigation-pop-after comp-id))) (rf/reg-fx :dismiss-modal (fn [comp-id] - (dismiss-modal (name comp-id)))) + (dismiss-modal comp-id))) (defn- pop-to-root [root-id] + (dismiss-all-modals) (navigation/pop-to-root root-id) - (dismiss-all-modals)) + (state/navigation-pop-after root-id)) (rf/reg-fx :pop-to-root-fx pop-to-root) @@ -128,7 +137,6 @@ (if @state/dissmissing (reset! state/dissmissing component) (do - (reset! state/curr-modal true) (swap! state/modals conj component) (navigation/show-modal {:stack {:children [{:component @@ -137,7 +145,9 @@ :options (merge (options/root-options {:theme (:theme options)}) options (when sheet? - options/sheet-options))}}]}}))))) + options/sheet-options))}}]}}))) + (state/navigation-state-push {:id component + :type :modal}))) (rf/reg-fx :open-modal-fx open-modal) diff --git a/src/status_im/navigation/events.cljs b/src/status_im/navigation/events.cljs index 0b7a5514a4..086b8277ab 100644 --- a/src/status_im/navigation/events.cljs +++ b/src/status_im/navigation/events.cljs @@ -24,25 +24,16 @@ :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]} [{:keys [db]} comp-id] - {:db (-> db - (update :modal-view-ids add-view-to-modals (first comp-id)) - (assoc :view-id (first comp-id))) + {:db (assoc db :view-id (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]]})) @@ -50,43 +41,17 @@ (rf/defn dismiss-modal {:events [:dismiss-modal]} [{:keys [db]} comp-id] - {:db (dissoc db :modal-view-ids) - :dismiss-modal comp-id}) + {: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]} - [{: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]} [{: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))))) + {:navigate-back-to comp-id}) (rf/defn pop-to-root {:events [:pop-to-root]} @@ -95,7 +60,6 @@ :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}) @@ -170,6 +134,7 @@ (rf/defn set-view-id {:events [:set-view-id]} [{:keys [db]} view-id] - (let [view-id (if (= view-id :shell-stack) (shell.utils/calculate-view-id) view-id)] - {:db (assoc db :view-id view-id) - :set-view-id-fx view-id})) + (when-not (= view-id (:view-id db)) + (let [view-id (if (= view-id :shell-stack) (shell.utils/calculate-view-id) view-id)] + {:db (assoc db :view-id view-id) + :set-view-id-fx view-id}))) diff --git a/src/status_im/navigation/state.cljs b/src/status_im/navigation/state.cljs index cfa7e6f144..01ecd38757 100644 --- a/src/status_im/navigation/state.cljs +++ b/src/status_im/navigation/state.cljs @@ -1,7 +1,48 @@ -(ns status-im.navigation.state) +(ns status-im.navigation.state + (:require [utils.re-frame :as rf])) (defonce root-id (atom nil)) -(defonce pushed-screen-id (atom nil)) -(defonce curr-modal (atom nil)) (defonce modals (atom [])) (defonce dissmissing (atom false)) + +(defonce ^:private navigation-state (atom [])) + +(defn get-navigation-state + [] + @navigation-state) + +(defn- update-view-id + [] + (when-let [view-id (:id (last (get-navigation-state)))] + (rf/dispatch [:set-view-id view-id]))) + +(defn navigation-state-push + [component] + (swap! navigation-state conj component) + (update-view-id)) + +(defn navigation-state-pop + [] + (reset! navigation-state (vec (butlast @navigation-state))) + (update-view-id)) + +(defn navigation-state-reset + [state] + (reset! navigation-state state) + (update-view-id)) + +(defn- indices-of-predicate-match + [pred coll] + (keep-indexed #(when (pred %2) %1) coll)) + +(defn navigation-pop-from + "Pops all items after match (including match)" + [comp-id] + (when-let [index (first (indices-of-predicate-match #(= comp-id (:id %)) @navigation-state))] + (navigation-state-reset (vec (take index @navigation-state))))) + +(defn navigation-pop-after + "Pops all items after match (excluding match)" + [comp-id] + (when-let [index (first (indices-of-predicate-match #(= comp-id (:id %)) @navigation-state))] + (navigation-state-reset (vec (take (inc index) @navigation-state))))) diff --git a/src/status_im/subs/navigation.cljs b/src/status_im/subs/navigation.cljs deleted file mode 100644 index d17c5b5c10..0000000000 --- a/src/status_im/subs/navigation.cljs +++ /dev/null @@ -1,10 +0,0 @@ -(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 3512a1d09f..f6ae1dd653 100644 --- a/src/status_im/subs/root.cljs +++ b/src/status_im/subs/root.cljs @@ -10,7 +10,6 @@ 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 @@ -26,7 +25,6 @@ ;;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)