Compare commits

...
6 changed files with 186 additions and 77 deletions
@@ -7,6 +7,7 @@
status-im.contexts.shell.jump-to.effects
[status-im.contexts.shell.jump-to.utils :as shell.utils]
[status-im.navigation.state :as navigation.state]
[status-im.navigation.utils :as navigation.utils]
[utils.re-frame :as rf]))
;;;; Events
@@ -149,10 +150,12 @@
(not hidden-screen?)
(:current-chat-id db))
(conj [:chat/close]))})
{:db (-> db
(assoc :view-id go-to-view-id)
(dissoc :modal-view-ids))
:navigate-to go-to-view-id}))
(let [modal-view-ids (navigation.utils/remove-current-modal-stack (:modal-view-ids db))]
{:navigate-to go-to-view-id
:db (cond-> db
true (assoc :view-id go-to-view-id)
(seq modal-view-ids) (assoc :modal-view-ids modal-view-ids)
(not (seq modal-view-ids)) (dissoc :modal-view-ids))})))
(rf/defn shell-navigate-back
{:events [:shell/navigate-back]}
@@ -176,8 +179,11 @@
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)})))
(let [modal-view-ids (navigation.utils/remove-current-modal-stack (:modal-view-ids db))]
{:navigate-back nil
:db (if (seq modal-view-ids)
(assoc db :modal-view-ids modal-view-ids)
(dissoc db :modal-view-ids))}))))
(rf/defn floating-screen-opened
{:events [:shell/floating-screen-opened]}
@@ -23,47 +23,52 @@
(defn- address-input
[input-value input-focused?]
(fn []
(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)
valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])
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 #(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/validate-address %]
300))
: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?}])))
(let [set-value-fn (atom nil)]
(fn []
(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)
valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])
chain-id (rf/sub [:chain-id])
contacts (rf/sub [:contacts/active])]
(when (and @set-value-fn scanned-address)
(@set-value-fn scanned-address)
(reset! set-value-fn nil))
[quo/address-input
{:on-focus #(reset! input-focused? true)
:on-blur #(reset! input-focused? false)
:on-scan (fn [set-value]
(reset! set-value-fn set-value)
(rn/dismiss-keyboard!)
(rf/dispatch [:wallet/clean-scanned-address])
(rf/dispatch [:open-modal :scan-address]))
:ens-regex constants/regx-ens
:default-value (when recipient-plain-address? send-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/validate-address %]
300))
: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]}]
+13 -29
View File
@@ -4,6 +4,7 @@
[status-im.contexts.shell.jump-to.events :as shell.events]
[status-im.contexts.shell.jump-to.state :as shell.state]
[status-im.contexts.shell.jump-to.utils :as shell.utils]
[status-im.navigation.utils :as navigation.utils]
[utils.re-frame :as rf]))
(defn- all-screens-params
@@ -24,23 +25,17 @@
: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 (update db :modal-view-ids add-view-to-modals (first comp-id))
{:db (update db :modal-view-ids navigation.utils/add-view-to-modal-stack (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])
(update :modal-view-ids navigation.utils/add-stack-to-modal-stacks component)
(all-screens-params component screen-params))
:fx [[:dispatch [:hide-bottom-sheet]]
[:open-modal-fx component]]}))
@@ -48,7 +43,7 @@
(rf/defn dismiss-modal
{:events [:dismiss-modal]}
[{:keys [db]} comp-id]
{:db (dissoc db :modal-view-ids)
{:db (update db :modal-view-ids navigation.utils/remove-current-modal-stack)
:dismiss-modal comp-id})
(rf/defn navigate-back
@@ -56,30 +51,17 @@
[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)
{:db (update db :modal-view-ids navigation.utils/remove-last-view-from-current-modal-stack)
: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)]
(let [modal-view-ids (navigation.utils/remove-views-from-modal-stack-until-comp-id (:modal-view-ids db)
comp-id)]
(assoc {:navigate-back-to comp-id}
:db
(if modal-view-ids
@@ -99,13 +81,15 @@
(rf/defn init-root
{:events [:init-root]}
[_ root-id]
{:set-root root-id})
[{:keys [db]} root-id]
{:set-root root-id
:db (dissoc db :modal-view-ids)})
(rf/defn set-stack-root
{:events [:set-stack-root]}
[_ stack root]
{:set-stack-root-fx [stack root]})
[{:keys [db]} stack root]
{:set-stack-root-fx [stack root]
:db (dissoc db :modal-view-ids)})
(rf/defn change-tab
{:events [:navigate-change-tab]}
+44
View File
@@ -0,0 +1,44 @@
(ns status-im.navigation.utils)
(defn add-view-to-modal-stack
[modal-view-ids new-id]
(if-let [current-stack (and (seq modal-view-ids) (last modal-view-ids))]
(let [updated-stack (conj current-stack new-id)
without-last (vec (butlast modal-view-ids))]
(conj without-last updated-stack))
modal-view-ids))
(defn remove-last-view-from-current-modal-stack
[modal-view-ids]
(if (empty? modal-view-ids)
modal-view-ids
(let [last-stack (last modal-view-ids)
updated-last-stack (vec (butlast last-stack))
without-last-stack (vec (butlast modal-view-ids))]
(if (empty? updated-last-stack)
without-last-stack
(conj without-last-stack updated-last-stack)))))
(defn add-stack-to-modal-stacks
[modal-view-ids first-view-id]
(if (seq modal-view-ids)
(conj modal-view-ids [first-view-id])
[[first-view-id]]))
(defn remove-current-modal-stack
[modal-view-ids]
(if (seq modal-view-ids)
(vec (butlast modal-view-ids))
[]))
(defn remove-views-from-modal-stack-until-comp-id
[modal-view-ids comp-id]
(let [found-index (first (keep-indexed (fn [idx stack]
(when (some #{comp-id} stack) idx))
modal-view-ids))]
(if found-index
(let [target-stack (nth modal-view-ids found-index)
comp-id-index (.lastIndexOf target-stack comp-id)
updated-stack (take (inc comp-id-index) target-stack)]
(assoc modal-view-ids found-index updated-stack))
modal-view-ids)))
+67
View File
@@ -0,0 +1,67 @@
(ns status-im.navigation.utils-test
(:require [cljs.test :refer [deftest is testing]]
[status-im.navigation.utils :as utils]))
(deftest test-add-view-to-modal-stack
(testing "Add view ID to an empty modal stack"
(is (= (utils/add-view-to-modal-stack [] 1)
[])))
(testing "Add view ID to a non-empty modal stack"
(is (= (utils/add-view-to-modal-stack [[1 2]] 3)
[[1 2 3]])))
(testing "Add view ID when multiple modal stacks exist"
(is (= (utils/add-view-to-modal-stack [[1 2] [3 4]] 5)
[[1 2] [3 4 5]]))))
(deftest test-remove-last-view-from-current-modal-stack
(testing "Remove last view ID from a single-element stack"
(is (= (utils/remove-last-view-from-current-modal-stack [[1]])
[])))
(testing "Remove last view ID from the current modal stack"
(is (= (utils/remove-last-view-from-current-modal-stack [[1 2 3] [4 5 6]])
[[1 2 3] [4 5]])))
(testing "Handle empty modal stacks"
(is (= (utils/remove-last-view-from-current-modal-stack [])
[])))
(testing "Ensure unchanged stack when nested stack is a single element"
(is (= (utils/remove-last-view-from-current-modal-stack [[1 2] [3]])
[[1 2]]))))
(deftest test-add-stack-to-modal-stacks
(testing "Add a new stack to an empty list of modal stacks"
(is (= (utils/add-stack-to-modal-stacks [] 1)
[[1]])))
(testing "Add a new stack to existing modal stacks"
(is (= (utils/add-stack-to-modal-stacks [[1 2]] 3)
[[1 2] [3]])))
(testing "Add a new stack when existing stacks are varied"
(is (= (utils/add-stack-to-modal-stacks [[1 2] [3 4]] 5)
[[1 2] [3 4] [5]]))))
(deftest test-remove-current-modal-stack
(testing "Remove the only modal stack"
(is (= (utils/remove-current-modal-stack [[1 2]])
[])))
(testing "Remove the last modal stack from multiple"
(is (= (utils/remove-current-modal-stack [[1 2] [3 4] [5 6]])
[[1 2] [3 4]])))
(testing "Handle removal when modal stacks are empty"
(is (= (utils/remove-current-modal-stack [])
[])))
(testing "Ensure unchanged when nested stacks have varied lengths"
(is (= (utils/remove-current-modal-stack [[1] [2 3] [4 5 6]])
[[1] [2 3]]))))
(deftest test-remove-views-from-modal-stack-until-comp-id
(testing "Remove views until comp-id, including multiple occurrences"
(is (= (utils/remove-views-from-modal-stack-until-comp-id [[1 2 3] [4 5 5 6]] 5)
[[1 2 3] [4 5 5]])))
(testing "comp-id at the beginning of a stack"
(is (= (utils/remove-views-from-modal-stack-until-comp-id [[1 2] [3 4] [5 6 7]] 5)
[[1 2] [3 4] [5]])))
(testing "comp-id not found, no removal"
(is (= (utils/remove-views-from-modal-stack-until-comp-id [[1 2 3] [4 5 6]] 7)
[[1 2 3] [4 5 6]])))
(testing "comp-id is the last element in a stack"
(is (= (utils/remove-views-from-modal-stack-until-comp-id [[1 2 3] [4 5 6] [7 8 9]] 9)
[[1 2 3] [4 5 6] [7 8 9]]))))
+4 -1
View File
@@ -7,4 +7,7 @@
:<- [:view-id]
:<- [:modal-view-ids]
(fn [[view-id modal-view-ids]]
(or (peek modal-view-ids) view-id)))
(or (some-> modal-view-ids
last
last)
view-id)))