From dc587e493f01ef702e96fe254db9099e9155f4d7 Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Thu, 7 Dec 2023 09:43:36 +0400 Subject: [PATCH] Wallet: generate new keypair UI (#18045) * feat: new keypair flow ui --- .../contexts/wallet/common/temp.cljs | 4 + .../backup_recovery_phrase/style.cljs | 65 +++++++++++++ .../backup_recovery_phrase/view.cljs | 95 +++++++++++++++++++ .../create_account/select_keypair/view.cljs | 21 +++- src/status_im2/navigation/screens.cljs | 6 ++ translations/en.json | 19 +++- 6 files changed, 206 insertions(+), 4 deletions(-) create mode 100644 src/status_im2/contexts/wallet/create_account/backup_recovery_phrase/style.cljs create mode 100644 src/status_im2/contexts/wallet/create_account/backup_recovery_phrase/view.cljs diff --git a/src/status_im2/contexts/wallet/common/temp.cljs b/src/status_im2/contexts/wallet/common/temp.cljs index ad4f6c2082..691e159a16 100644 --- a/src/status_im2/contexts/wallet/common/temp.cljs +++ b/src/status_im2/contexts/wallet/common/temp.cljs @@ -107,3 +107,7 @@ :networks networks-list :state :default :customization-color :blue}]) + +(def secret-phrase + ["witch" "collapse" "practice" "feed" "shame" "open" "lion" + "collapse" "umbrella" "fabric" "sadness" "obligue"]) diff --git a/src/status_im2/contexts/wallet/create_account/backup_recovery_phrase/style.cljs b/src/status_im2/contexts/wallet/create_account/backup_recovery_phrase/style.cljs new file mode 100644 index 0000000000..5cda62a059 --- /dev/null +++ b/src/status_im2/contexts/wallet/create_account/backup_recovery_phrase/style.cljs @@ -0,0 +1,65 @@ +(ns status-im2.contexts.wallet.create-account.backup-recovery-phrase.style + (:require + [quo.foundations.colors :as colors] + [quo.theme :as quo.theme] + [react-native.platform :as platform])) + +(def header-container + {:margin-horizontal 20 + :margin-vertical 12}) + +(defn seed-phrase-container + [theme] + {:margin-horizontal 20 + :padding-horizontal 12 + :border-width 1 + :border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme) + :border-radius 16 + :background-color (colors/theme-colors colors/white colors/neutral-80-opa-40 theme) + :flex-direction :row}) + +(def word-item + {:align-items :center + :flex-direction :row}) + +(defn separator + [theme] + {:margin-vertical 12 + :margin-horizontal 12 + :border-width (when platform/ios? 1) + :border-right-width (when platform/android? 1) + :border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme) + :border-style :dashed}) + +(def step-item + {:flex-direction :row + :margin-vertical 8 + :align-items :center}) + +(def blur-container + {:position :absolute + :left 0 + :right 0 + :top 0 + :bottom 0 + :border-radius 16 + :overflow :hidden}) + +(defn blur + [theme] + {:style {:flex 1} + :blur-radius 20 + :blur-type (quo.theme/theme-value :light :dark theme) + :blur-amount 20}) + +(def slide-button + {:position :absolute + :bottom 12 + :left 0 + :right 0}) + +(defn description-text + [theme] + {:margin-horizontal 40 + :text-align :center + :color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)}) diff --git a/src/status_im2/contexts/wallet/create_account/backup_recovery_phrase/view.cljs b/src/status_im2/contexts/wallet/create_account/backup_recovery_phrase/view.cljs new file mode 100644 index 0000000000..62da279257 --- /dev/null +++ b/src/status_im2/contexts/wallet/create_account/backup_recovery_phrase/view.cljs @@ -0,0 +1,95 @@ +(ns status-im2.contexts.wallet.create-account.backup-recovery-phrase.view + (:require + [quo.core :as quo] + [quo.theme :as quo.theme] + [react-native.blur :as blur] + [react-native.core :as rn] + [reagent.core :as reagent] + [status-im2.contexts.wallet.common.temp :as temp] + [status-im2.contexts.wallet.create-account.backup-recovery-phrase.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn- word-item + [item index _ increment] + [rn/view {:style style/word-item} + [quo/counter {:type :grey} (+ index increment)] + [quo/text {:style {:margin-left 4}} item]]) + +(defn- words-column + [words first-half?] + [rn/flat-list + {:style {:padding-vertical 8} + :data (if first-half? (subvec words 0 6) (subvec words 6)) + :separator [rn/view {:style {:height 12}}] + :render-fn word-item + :render-data (if first-half? 1 7) + :scroll-enabled false}]) + +(defn- step-item + [item index _ checked?] + [rn/view {:style style/step-item} + [quo/selectors + {:type :checkbox + :on-change #(swap! checked? assoc (keyword (str index)) %)}] + [quo/text {:style {:margin-left 12}} (i18n/label item)]]) + +(defn- view-internal + [{:keys [theme]}] + (let [step-labels [:t/backup-step-1 :t/backup-step-2 :t/backup-step-3 + :t/backup-step-4] + checked? (reagent/atom + {:0 false + :1 false + :2 false + :3 false}) + revealed? (reagent/atom false) + {:keys [customization-color]} (rf/sub [:profile/profile])] + (fn [] + [rn/view {:style {:flex 1}} + [quo/page-nav + {:icon-name :i/close + :on-press #(rf/dispatch [:navigate-back]) + :accessibility-label :top-bar}] + [quo/text-combinations + {:container-style style/header-container + :title (i18n/label :t/backup-recovery-phrase) + :description (i18n/label :t/backup-recovery-phrase-description)}] + [rn/view {:style (style/seed-phrase-container theme)} + [words-column temp/secret-phrase true] + [rn/view {:style (style/separator theme)}] + [words-column temp/secret-phrase false] + (when-not @revealed? + [rn/view {:style style/blur-container} + [blur/view (style/blur theme)]])] + (when-not @revealed? + [rn/view + {:style {:padding-horizontal 20 + :padding-top 20}} + [quo/text + {:weight :semi-bold + :style {:margin-bottom 8}} (i18n/label :t/how-to-backup)] + [rn/flat-list + {:data step-labels + :render-fn step-item + :render-data checked? + :scroll-enabled false}]]) + (if @revealed? + [rn/view {:style style/slide-button} + [quo/bottom-actions + {:button-one-label (i18n/label :t/i-have-written) + :button-one-props {:disabled? (some false? (vals @checked?)) + :customization-color customization-color + :on-press #(js/alert "To be implemented")}}] + [quo/text + {:size :paragraph-2 + :style (style/description-text theme)} + (i18n/label :t/next-you-will)]] + [quo/bottom-actions + {:button-one-label (i18n/label :t/reveal-phrase) + :button-one-props {:disabled? (some false? (vals @checked?)) + :customization-color customization-color + :on-press #(reset! revealed? true)} + :container-style style/slide-button}])]))) + +(def view (quo.theme/with-theme view-internal)) diff --git a/src/status_im2/contexts/wallet/create_account/select_keypair/view.cljs b/src/status_im2/contexts/wallet/create_account/select_keypair/view.cljs index 346c52d078..e749908555 100644 --- a/src/status_im2/contexts/wallet/create_account/select_keypair/view.cljs +++ b/src/status_im2/contexts/wallet/create_account/select_keypair/view.cljs @@ -8,6 +8,24 @@ [utils.i18n :as i18n] [utils.re-frame :as rf])) +(defn keypair-options + [] + [quo/action-drawer + [[{:icon :i/add + :accessibility-label :generate-new-keypair + :label (i18n/label :t/generate-new-keypair) + :on-press #(rf/dispatch [:navigate-to :wallet-backup-recovery-phrase])} + {:icon :i/seed + :accessibility-label :import-using-phrase + :label (i18n/label :t/import-using-phrase) + :add-divider? true} + {:icon :i/keycard-card + :accessibility-label :import-from-keycard + :label (i18n/label :t/import-from-keycard)} + {:icon :i/key + :accessibility-label :import-private-key + :label (i18n/label :t/import-private-key)}]]]) + (def accounts [{:account-props {:customization-color :turquoise :size 32 @@ -38,7 +56,8 @@ :title (i18n/label :t/keypairs) :description (i18n/label :t/keypairs-description) :button-icon :i/add - :button-on-press #(js/alert "not implemented") + :button-on-press #(rf/dispatch [:show-bottom-sheet + {:content keypair-options}]) :customization-color customization-color}] [quo/keypair (merge diff --git a/src/status_im2/navigation/screens.cljs b/src/status_im2/navigation/screens.cljs index 4cea065c2a..52c2a5e34c 100644 --- a/src/status_im2/navigation/screens.cljs +++ b/src/status_im2/navigation/screens.cljs @@ -46,6 +46,8 @@ [status-im2.contexts.wallet.add-address-to-watch.confirm-address.view :as confirm-address-to-watch] [status-im2.contexts.wallet.add-address-to-watch.view :as add-address-to-watch] [status-im2.contexts.wallet.collectible.view :as wallet-collectible] + [status-im2.contexts.wallet.create-account.backup-recovery-phrase.view :as + wallet-backup-recovery-phrase] [status-im2.contexts.wallet.create-account.edit-derivation-path.view :as wallet-edit-derivation-path] [status-im2.contexts.wallet.create-account.select-keypair.view :as wallet-select-keypair] [status-im2.contexts.wallet.create-account.view :as wallet-create-account] @@ -297,6 +299,10 @@ :options {:insets {:top? true}} :component wallet-create-account/view} + {:name :wallet-backup-recovery-phrase + :options {:insets {:top? true :bottom? true}} + :component wallet-backup-recovery-phrase/view} + {:name :wallet-saved-addresses :component wallet-saved-addresses/view} diff --git a/translations/en.json b/translations/en.json index 439332f87e..4b8705ccb1 100644 --- a/translations/en.json +++ b/translations/en.json @@ -63,7 +63,6 @@ "back": "Back", "back-up-seed-phrase": "Back up seed phrase", "back-up-your-seed-phrase": "Back up your seed phrase", - "backup-recovery-phrase": "Back up seed phrase", "balance": "Balance", "begin-set-up": "Begin setup", "biometric-auth-android-sensor-desc": "Touch sensor", @@ -2406,9 +2405,23 @@ "send-limit": "Max: {{limit}}", "searching-for-activity": "Searching for activity...", "this-address-has-no-activity": "This address has no activity", - "this-address-has-activity": "This address has activity", "details": "Details", "est-time": "Est. time", "user-gets": "{{name}} gets", - "slide-to-send": "Slide to send" + "slide-to-send": "Slide to send", + "this-address-has-activity": "This address has activity", + "generate-new-keypair": "Generate new keypair", + "import-using-phrase": "Import using recovery phrase", + "import-from-keycard": "Import from Keycard", + "import-private-key": "Import private key", + "backup-recovery-phrase": "Backup recovery phrase", + "backup-recovery-phrase-description": "Save in a secure place that only you control, these 12 words give access to all of your funds.", + "how-to-backup": "How to backup your recovery phrase", + "backup-step-1": "Find pen and paper", + "backup-step-2": "Write down your recovery phrase", + "backup-step-3": "Find a place to store it", + "backup-step-4": "I know I can only see it once", + "reveal-phrase": "Reveal phrase", + "i-have-written": "I have written it down on paper", + "next-you-will": "Next, you will be asked to confirm the position of certain words in your recovery phrase" }