diff --git a/src/status_im/ens/core.cljs b/src/status_im/ens/core.cljs index d0e2a63bb2..4534c806fc 100644 --- a/src/status_im/ens/core.cljs +++ b/src/status_im/ens/core.cljs @@ -18,7 +18,8 @@ [status-im.utils.money :as money] [status-im.signing.core :as signing] [status-im.multiaccounts.update.core :as multiaccounts.update] - [taoensso.timbre :as log]) + [taoensso.timbre :as log] + [status-im.utils.random :as random]) (:refer-clojure :exclude [name])) (defn fullname [custom-domain? username] @@ -105,26 +106,27 @@ {:routeName :ens-confirmation}]})) (defn- on-resolve-owner - [registry custom-domain? username address public-key response] - (cond + [registry custom-domain? username address public-key response resolve-last-id* resolve-last-id] + (when (= @resolve-last-id* resolve-last-id) + (cond - ;; No address for a stateofus subdomain: it can be registered - (and (= response ens/default-address) (not custom-domain?)) - (re-frame/dispatch [::name-resolved username :available]) + ;; No address for a stateofus subdomain: it can be registered + (and (= response ens/default-address) (not custom-domain?)) + (re-frame/dispatch [::name-resolved username :available]) - ;; if we get an address back, we try to get the public key associated - ;; with the username as well - (= (eip55/address->checksum address) - (eip55/address->checksum response)) - (resolver/pubkey registry (fullname custom-domain? username) - #(re-frame/dispatch [::name-resolved username - (cond - (not public-key) :owned - (= % public-key) :connected - :else :connected-with-different-key)])) + ;; if we get an address back, we try to get the public key associated + ;; with the username as well + (= (eip55/address->checksum address) + (eip55/address->checksum response)) + (resolver/pubkey registry (fullname custom-domain? username) + #(re-frame/dispatch [::name-resolved username + (cond + (not public-key) :owned + (= % public-key) :connected + :else :connected-with-different-key)])) - :else - (re-frame/dispatch [::name-resolved username :taken]))) + :else + (re-frame/dispatch [::name-resolved username :taken])))) (defn registration-cost [chain-id] @@ -174,12 +176,16 @@ :searching) :else :invalid)) +;;NOTE we want to handle only last resolve +(def resolve-last-id (atom nil)) + (fx/defn set-username-candidate {:events [::set-username-candidate]} [{:keys [db]} username] (let [{:keys [custom-domain?]} (:ens/registration db) usernames (into #{} (get-in db [:multiaccount :usernames])) state (state custom-domain? username usernames)] + (reset! resolve-last-id (random/id)) (merge {:db (update db :ens/registration assoc :username username @@ -191,7 +197,9 @@ registry (get ens/ens-registries (ethereum/chain-keyword db))] {::resolve-owner [registry (fullname custom-domain? username) - #(on-resolve-owner registry custom-domain? username address public-key %)]}))))) + #(on-resolve-owner + registry custom-domain? username address public-key % + resolve-last-id @resolve-last-id)]}))))) (fx/defn return-to-ens-main-screen {:events [::got-it-pressed ::cancel-pressed]} diff --git a/src/status_im/ui/screens/browser/views.cljs b/src/status_im/ui/screens/browser/views.cljs index 53f77404c5..d0be093463 100644 --- a/src/status_im/ui/screens/browser/views.cljs +++ b/src/status_im/ui/screens/browser/views.cljs @@ -143,7 +143,9 @@ :render-error web-view-error :on-navigation-state-change #(do (re-frame/dispatch [:set-in [:ens/registration :state] :searching]) - (debounce/debounce [:browser/navigation-state-changed % error?] 500)) + (debounce/debounce-and-dispatch + [:browser/navigation-state-changed % error?] + 500)) :on-bridge-message #(re-frame/dispatch [:browser/bridge-message-received %]) :on-load #(re-frame/dispatch [:browser/loading-started]) :on-error #(re-frame/dispatch [:browser/error-occured]) diff --git a/src/status_im/ui/screens/ens/views.cljs b/src/status_im/ui/screens/ens/views.cljs index 136462641f..d3e999535c 100644 --- a/src/status_im/ui/screens/ens/views.cljs +++ b/src/status_im/ui/screens/ens/views.cljs @@ -118,7 +118,7 @@ (:available :connected :connected-with-different-key :owned) [react/touchable-highlight - {:on-press #(re-frame/dispatch [::ens/input-icon-pressed])} + {:on-press #(debounce/dispatch-and-chill [::ens/input-icon-pressed] 3000)} [icon-wrapper colors/blue [vector-icons/icon :main-icons/arrow-right {:color colors/white}]]] @@ -199,7 +199,7 @@ {:ref #(reset! input-ref %) :on-change-text #(do (re-frame/dispatch [:set-in [:ens/registration :state] :searching]) - (debounce/debounce [::ens/set-username-candidate %] 600)) + (debounce/debounce-and-dispatch [::ens/set-username-candidate %] 600)) :on-submit-editing #(re-frame/dispatch [::ens/input-submitted]) :auto-capitalize :none :auto-complete-type "off" diff --git a/src/status_im/utils/debounce.cljs b/src/status_im/utils/debounce.cljs index c8f4751e7f..68fb31feac 100644 --- a/src/status_im/utils/debounce.cljs +++ b/src/status_im/utils/debounce.cljs @@ -1,11 +1,24 @@ (ns status-im.utils.debounce (:require [re-frame.core :as re-frame])) -(def timeout (atom {})) +(def timeout (atom nil)) -(defn debounce [event time] +(defn debounce-and-dispatch + "Dispatches event only if there were no calls of this function in period of *time* ms" + [event time] (when @timeout (js/clearTimeout @timeout)) (reset! timeout (js/setTimeout #(re-frame/dispatch event) time))) (defn clear [] - (when @timeout (js/clearTimeout @timeout))) \ No newline at end of file + (when @timeout (js/clearTimeout @timeout))) + +(def chill? (atom false)) + +(defn dispatch-and-chill + "Dispateches event and ignores next calls in period of *time* ms" + [event time] + (when-not @chill? + (reset! chill? true) + (js/setTimeout #(reset! chill? false) time) + (re-frame/dispatch event))) +