From 08ff2edb0be798e5499c8c90024dd01b6d55865b Mon Sep 17 00:00:00 2001 From: Jonathan Rainville Date: Fri, 17 Apr 2020 15:11:00 -0400 Subject: [PATCH] Show ENS name only when confirmed fix: only save the ENS username when the TX is confirmed feat: show when ens registration are in progress, done or errored feat: implement new design for the ENS registration Signed-off-by: Andrea Maria Piana --- src/status_im/ens/core.cljs | 52 +++++++++++++------ src/status_im/ethereum/transactions/core.cljs | 36 ++++++++++++- src/status_im/subs.cljs | 11 ++-- src/status_im/ui/screens/ens/views.cljs | 32 +++++++++--- translations/en.json | 3 ++ 5 files changed, 105 insertions(+), 29 deletions(-) diff --git a/src/status_im/ens/core.cljs b/src/status_im/ens/core.cljs index c8b77f529b..21d2485454 100644 --- a/src/status_im/ens/core.cljs +++ b/src/status_im/ens/core.cljs @@ -22,6 +22,36 @@ username (stateofus/subdomain username))) +(fx/defn update-ens-tx-state + {:events [:update-ens-tx-state]} + [{:keys [db]} new-state username custom-domain? tx-hash] + {:db (assoc-in db [:ens/registrations tx-hash] {:state new-state + :username username + :custom-domain? custom-domain?})}) + +(fx/defn redirect-to-ens-summary + {:events [::redirect-to-ens-summary]} + [cofx] + ;; we reset navigation so that navigate back doesn't return + ;; into the registration flow + (navigation/navigate-reset cofx + {:index 1 + :key :profile-stack + :routes [{:name :my-profile} + {:name :ens-confirmation}]})) + +(fx/defn update-ens-tx-state-and-redirect + {:events [:update-ens-tx-state-and-redirect]} + [cofx new-state username custom-domain? tx-hash] + (fx/merge cofx + (update-ens-tx-state new-state username custom-domain? tx-hash) + (redirect-to-ens-summary))) + +(fx/defn clear-ens-registration + {:events [:clear-ens-registration]} + [{:keys [db]} tx-hash] + {:db (update db :ens/registrations dissoc tx-hash)}) + (re-frame/reg-fx ::resolve-address (fn [[registry name cb]] @@ -62,19 +92,20 @@ {:contract resolver-contract :method "setPubkey(bytes32,bytes32,bytes32)" :params [namehash x y] - :on-result [::save-username custom-domain? username] + :on-result [::save-username custom-domain? username true] :on-error [::on-registration-failure]}))) (fx/defn save-username {:events [::save-username]} - [{:keys [db] :as cofx} custom-domain? username] + [{:keys [db] :as cofx} custom-domain? username redirectToSummary] (let [name (fullname custom-domain? username) names (get-in db [:multiaccount :usernames] []) new-names (conj names name)] (fx/merge cofx (multiaccounts.update/multiaccount-update :usernames new-names - {:on-success #(re-frame/dispatch [::username-saved])}) + (when redirectToSummary + {:on-success #(re-frame/dispatch [::redirect-to-ens-summary])})) (when (empty? names) (multiaccounts.update/multiaccount-update :preferred-name name {}))))) @@ -93,21 +124,10 @@ (ens/resolver registry-contract ens-name #(re-frame/dispatch [::resolver-found %])) :connected - (save-username cofx custom-domain? username) + (save-username cofx custom-domain? username true) ;; for other states, we do nothing nil))) -(fx/defn username-saved - {:events [::username-saved]} - [{:keys [db] :as cofx}] - ;; we reset navigation so that navigate back doesn't return - ;; into the registration flow - (navigation/navigate-reset cofx - {:index 1 - :key :profile-stack - :routes [{:name :my-profile} - {:name :ens-confirmation}]})) - (defn- on-resolve-owner [registry custom-domain? username address public-key response resolve-last-id* resolve-last-id] (when (= @resolve-last-id* resolve-last-id) @@ -157,7 +177,7 @@ (money/unit->token amount 18) (abi-spec/encode "register(bytes32,address,bytes32,bytes32)" [(ethereum/sha3 username) address x y])] - :on-result [::save-username custom-domain? username] + :on-result [:update-ens-tx-state-and-redirect :submitted username custom-domain?] :on-error [::on-registration-failure]}))) (defn- valid-custom-domain? [username] diff --git a/src/status_im/ethereum/transactions/core.cljs b/src/status_im/ethereum/transactions/core.cljs index 10d2d48301..42740389cd 100644 --- a/src/status_im/ethereum/transactions/core.cljs +++ b/src/status_im/ethereum/transactions/core.cljs @@ -4,6 +4,7 @@ [status-im.ethereum.eip55 :as eip55] [status-im.ethereum.encode :as encode] [status-im.ethereum.json-rpc :as json-rpc] + [status-im.ens.core :as ens] [status-im.utils.fx :as fx] [status-im.wallet.core :as wallet] [taoensso.timbre :as log] @@ -205,8 +206,7 @@ [{:keys [db]} address] {:db (assoc-in db [:wallet :fetching address :all-fetched?] true)}) -(fx/defn new-transfers - {:events [::new-transfers]} +(fx/defn handle-new-transfer [{:keys [db] :as cofx} transfers {:keys [address limit]}] (log/debug "[transfers] new-transfers" "address" address @@ -234,6 +234,38 @@ (conj (tx-history-end-reached checksum)))] (apply fx/merge cofx (tx-fetching-ended [checksum]) effects))) +(fx/defn check-ens-transactions + [{:keys [db] :as cofx} transfers] + (let [set-of-transactions-hash (reduce (fn [acc {:keys [hash]}] (conj acc hash)) #{} transfers) + registrations (filter + (fn [[hash {:keys [state]}]] + (and + (or (= state :dismissed) (= state :submitted)) + (contains? set-of-transactions-hash hash))) + (get db :ens/registrations)) + fxs (map (fn [[hash {:keys [username custom-domain?]}]] + (let [transfer (first (filter (fn [transfer] (let [transfer-hash (get transfer :hash)] (= transfer-hash hash))) transfers)) + type (get transfer :type) + transaction-success (get transfer :transfer)] + (cond + (= transaction-success true) + (fx/merge cofx + (ens/clear-ens-registration hash) + (ens/save-username custom-domain? username false)) + (= type :failed) + (ens/update-ens-tx-state :failure username custom-domain? hash) + :else + nil))) + registrations)] + (apply fx/merge cofx fxs))) + +(fx/defn new-transfers + {:events [::new-transfers]} + [cofx transfers params] + (fx/merge cofx + (handle-new-transfer transfers params) + (check-ens-transactions transfers))) + (fx/defn tx-fetching-failed {:events [::tx-fetching-failed]} [cofx error address] diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index 03c5ecce6d..bc41900a5b 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -166,6 +166,7 @@ ;;ens (reg-root-key-sub :ens/registration :ens/registration) +(reg-root-key-sub :ens/registrations :ens/registrations) (reg-root-key-sub :ens/names :ens/names) ;;signing @@ -2024,10 +2025,12 @@ :<- [:multiaccount/usernames] :<- [:multiaccount] :<- [:ens/preferred-name] - (fn [[names multiaccount preferred-name]] - {:names names - :multiaccount multiaccount - :preferred-name preferred-name})) + :<- [:ens/registrations] + (fn [[names multiaccount preferred-name registrations]] + {:names names + :multiaccount multiaccount + :preferred-name preferred-name + :registrations registrations})) ;;SIGNING ============================================================================================================= diff --git a/src/status_im/ui/screens/ens/views.cljs b/src/status_im/ui/screens/ens/views.cljs index 8498841906..6ea1cd0b91 100644 --- a/src/status_im/ui/screens/ens/views.cljs +++ b/src/status_im/ui/screens/ens/views.cljs @@ -597,12 +597,14 @@ [button {:on-press #(re-frame/dispatch [::ens/get-started-pressed]) :label (i18n/label :t/get-started)}]]])) -(defn- name-item [{:keys [name action]}] +(defn- name-item [{:keys [name action subtitle]}] (let [stateofus-username (stateofus/username name) s (or stateofus-username name)] [list-item/list-item {:title s - :subtitle (when stateofus-username stateofus/domain) + :subtitle (if subtitle + subtitle + (when stateofus-username stateofus/domain)) :on-press action :icon :main-icons/username}])) @@ -627,12 +629,25 @@ [name-item {:name name :hide-chevron? true :action action}]] [radio/radio (= name preferred-name)]]]))]]]]) +(views/defview in-progress-registrations [registrations] + [react/view {:style {:margin-top 8}} + (for [[hash {:keys [state username]}] registrations + :when (or (= state :submitted) (= state :failure))] + ^{:key hash} + [name-item {:name username + :action (when-not (= state :submitted) + #(re-frame/dispatch [:clear-ens-registration hash])) + :subtitle (case state + :submitted (i18n/label :t/ens-registration-in-progress) + :failure (i18n/label :t/ens-registration-failure) + nil)}])]) + (views/defview my-name [] (views/letsubs [contact-name [:multiaccount/preferred-name]] (when-not (string/blank? contact-name) (chat.utils/format-author (str "@" contact-name) message.style/message-author-name-container)))) -(defn- registered [names {:keys [preferred-name] :as account} _] +(views/defview registered [names {:keys [preferred-name] :as account} _ registrations] [react/view {:style {:flex 1}} [react/scroll-view [react/view {:style {:margin-top 8}} @@ -644,12 +659,15 @@ [react/view {:style {:margin-top 22 :margin-bottom 8}} [react/text {:style {:color colors/gray :margin-horizontal 16}} (i18n/label :t/ens-your-usernames)] + (when registrations + [in-progress-registrations registrations]) (if (seq names) [react/view {:style {:margin-top 8}} (for [name names] ^{:key name} [name-item {:name name :action #(re-frame/dispatch [::ens/navigate-to-name name])}])] - [react/text {:style {:color colors/gray :font-size 15}} + [react/text {:style {:color colors/gray :font-size 15 + :margin-horizontal 16}} (i18n/label :t/ens-no-usernames)])] [react/view {:style {:padding-vertical 22 :border-color colors/gray-lighter :border-top-width 1}} (when (> (count names) 1) @@ -678,9 +696,9 @@ [message/text-message message]]])]]) (views/defview main [] - (views/letsubs [{:keys [names multiaccount show?]} [:ens.main/screen]] + (views/letsubs [{:keys [names multiaccount show? registrations]} [:ens.main/screen]] [react/keyboard-avoiding-view {:style {:flex 1}} [topbar/topbar {:title :t/ens-usernames}] - (if (seq names) - [registered names multiaccount show?] + (if (or (seq names) registrations) + [registered names multiaccount show? registrations] [welcome])])) diff --git a/translations/en.json b/translations/en.json index 4adda72338..afa1b20d6b 100644 --- a/translations/en.json +++ b/translations/en.json @@ -349,6 +349,9 @@ "ens-powered-by": "Powered by Ethereum Name Services", "ens-primary-username": "Primary username", "ens-register": "Register", + "ens-registration-in-progress": "Registration in progress...", + "ens-registration-failure": "Registration failed", + "ens-dismiss-message": "Click here to dismiss", "ens-registration-failed": "To register the username, please try again.", "ens-registration-failed-title": "Transaction failed", "ens-release-username": "Release username",