diff --git a/src/quo/components/drawers/action_drawers/view.cljs b/src/quo/components/drawers/action_drawers/view.cljs index 22786fdb59..0290e8423e 100644 --- a/src/quo/components/drawers/action_drawers/view.cljs +++ b/src/quo/components/drawers/action_drawers/view.cljs @@ -8,10 +8,11 @@ [react-native.core :as rn])) (defn- get-icon-color - [danger? theme] - (if danger? - (colors/theme-colors colors/danger-50 colors/danger-60 theme) - (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))) + [blur? danger? theme] + (cond + danger? (colors/theme-colors colors/danger-50 colors/danger-60 theme) + blur? colors/white-opa-70 + :else (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))) (defn- divider [theme blur?] @@ -51,7 +52,7 @@ :accessible true :style (style/left-icon sub-label)} [icon/icon icon - {:color (or icon-color (get-icon-color danger? theme)) + {:color (or icon-color (get-icon-color blur? danger? theme)) :no-color no-icon-color? :size 20}]]) [rn/view @@ -84,7 +85,7 @@ :accessible true :accessibility-label :right-icon-for-action} [icon/icon right-icon - {:color (get-icon-color danger? theme) + {:color (get-icon-color blur? danger? theme) :size 20}]]) (when (= state :selected) [rn/view {:style style/right-icon} diff --git a/src/quo/components/drawers/drawer_top/view.cljs b/src/quo/components/drawers/drawer_top/view.cljs index 4221be2049..5c5aa98a64 100644 --- a/src/quo/components/drawers/drawer_top/view.cljs +++ b/src/quo/components/drawers/drawer_top/view.cljs @@ -18,7 +18,7 @@ (defn- left-image [{:keys [type customization-color account-avatar-emoji account-avatar-type icon-avatar - profile-picture]}] + profile-picture blur?]}] (case type :account [account-avatar/view {:customization-color customization-color @@ -28,6 +28,7 @@ :keypair [icon-avatar/icon-avatar {:icon icon-avatar :border? true + :blur? blur? :color :neutral}] :default-keypair [user-avatar/user-avatar @@ -213,6 +214,7 @@ [rn/view {:style style/left-container} [left-image {:type type + :blur? blur? :customization-color customization-color :account-avatar-emoji account-avatar-emoji :account-avatar-type account-avatar-type diff --git a/src/quo/components/list_items/account_list_card/view.cljs b/src/quo/components/list_items/account_list_card/view.cljs index e1e6bc8e96..1ac4ca0f8c 100644 --- a/src/quo/components/list_items/account_list_card/view.cljs +++ b/src/quo/components/list_items/account_list_card/view.cljs @@ -31,7 +31,8 @@ :size :paragraph-2} (:name account-props)] [address-text/view - {:networks networks + {:blur? blur? + :networks networks :address (:address account-props) :format :short}]]] (when (= action :icon) diff --git a/src/quo/components/wallet/keypair/view.cljs b/src/quo/components/wallet/keypair/view.cljs index a31e0b3178..d6ab053cf1 100644 --- a/src/quo/components/wallet/keypair/view.cljs +++ b/src/quo/components/wallet/keypair/view.cljs @@ -47,12 +47,13 @@ :accessibility-label :title} [text/text {:weight :semi-bold} (if (= type :default-keypair) (keypair-string full-name) full-name)] - (if (= action :selector) - [selectors/view - {:type :radio - :checked? selected? - :blur? blur? - :customization-color customization-color}] + (case action + :none nil + :selector [selectors/view + {:type :radio + :checked? selected? + :blur? blur? + :customization-color customization-color}] [rn/pressable {:on-press on-options-press} [icon/icon :i/options {:color (if blur? diff --git a/src/quo/components/wallet/missing_keypairs/view.cljs b/src/quo/components/wallet/missing_keypairs/view.cljs index 0e465fdd34..c2fe6ca60f 100644 --- a/src/quo/components/wallet/missing_keypairs/view.cljs +++ b/src/quo/components/wallet/missing_keypairs/view.cljs @@ -11,7 +11,7 @@ [utils.i18n :as i18n])) (defn title-view - [{:keys [keypairs blur? on-import-press]}] + [{:keys [keypairs blur? on-import-press show-import-all?]}] (let [theme (quo.theme/use-theme)] [rn/view {:accessibility-label :title @@ -29,12 +29,13 @@ :style {:color colors/warning-60}} (i18n/label :t/amount-missing-keypairs {:amount (str (count keypairs))})] - [button/button - {:type :outline - :background :blur - :size 24 - :on-press on-import-press} - (i18n/label :t/import)]] + (when show-import-all? + [button/button + {:type :outline + :background :blur + :size 24 + :on-press on-import-press} + (i18n/label :t/import)])] [text/text {:size :paragraph-2 :style (style/subtitle blur? theme)} diff --git a/src/status_im/common/bottom_sheet/style.cljs b/src/status_im/common/bottom_sheet/style.cljs index 5c7e474575..ca83a1fb04 100644 --- a/src/status_im/common/bottom_sheet/style.cljs +++ b/src/status_im/common/bottom_sheet/style.cljs @@ -1,7 +1,6 @@ (ns status-im.common.bottom-sheet.style (:require - [quo.foundations.colors :as colors] - [react-native.platform :as platform])) + [quo.foundations.colors :as colors])) (def ^:private sheet-border-radius 20) @@ -22,11 +21,8 @@ :left 0 :right 0}) -(defn shell-bg - [blur-background] - {:background-color (if blur-background - blur-background - (if platform/ios? colors/white-opa-5 colors/neutral-100-opa-90)) +(def shell-bg + {:background-color colors/bottom-sheet-background-blur :flex 1}) (def shell-bg-container diff --git a/src/status_im/common/bottom_sheet/view.cljs b/src/status_im/common/bottom_sheet/view.cljs index 98fec0f694..a941d9bad0 100644 --- a/src/status_im/common/bottom_sheet/view.cljs +++ b/src/status_im/common/bottom_sheet/view.cljs @@ -63,7 +63,7 @@ (defn view [{:keys [hide? insets]} {:keys [content selected-item padding-bottom-override border-radius on-close shell? - gradient-cover? customization-color hide-handle? blur-radius blur-background] + gradient-cover? customization-color hide-handle? blur-radius] :or {border-radius 12}}] (let [theme (quo.theme/use-theme) {window-height :height} (rn/get-window) @@ -134,7 +134,7 @@ (when shell? [rn/view {:style style/shell-bg-container} [quo/blur - {:style (style/shell-bg blur-background) + {:style style/shell-bg :blur-radius (or blur-radius 20) :blur-amount 32 :blur-type :transparent diff --git a/src/status_im/common/enter_seed_phrase/style.cljs b/src/status_im/common/enter_seed_phrase/style.cljs index 1fb6a9b471..567e7bbd22 100644 --- a/src/status_im/common/enter_seed_phrase/style.cljs +++ b/src/status_im/common/enter_seed_phrase/style.cljs @@ -1,6 +1,5 @@ (ns status-im.common.enter-seed-phrase.style - (:require - [react-native.safe-area :as safe-area])) + (:require [react-native.platform :as platform])) (def full-layout {:flex 1}) @@ -11,6 +10,13 @@ :left 0 :right 0}) +(defn recovery-phrase-container + [{:keys [banner-offset insets keyboard-shown?]}] + {:flex 1 + :padding-bottom (if keyboard-shown? + (when platform/ios? banner-offset) + (:bottom insets))}) + (def form-container {:flex 1 :padding-horizontal 20 @@ -29,9 +35,7 @@ :margin-top 12 :margin-horizontal -20}) -(defn continue-button - [keyboard-shown?] - {:margin-top :auto - :margin-bottom (when-not keyboard-shown? (safe-area/get-bottom))}) +(def continue-button + {:margin-top :auto}) (def keyboard-container {:margin-top :auto}) diff --git a/src/status_im/common/enter_seed_phrase/view.cljs b/src/status_im/common/enter_seed_phrase/view.cljs index 361ec2e619..16ae317a94 100644 --- a/src/status_im/common/enter_seed_phrase/view.cljs +++ b/src/status_im/common/enter_seed_phrase/view.cljs @@ -96,7 +96,7 @@ (take 7))) (defn recovery-phrase-screen - [{:keys [keypair title recovering-keypair? render-controls]}] + [{:keys [banner-offset initial-insets keypair title recovering-keypair? render-controls]}] (reagent/with-let [keyboard-shown? (reagent/atom false) keyboard-show-listener (.addListener rn/keyboard "keyboardDidShow" @@ -114,7 +114,8 @@ seed-phrase (reagent/atom "") on-change-seed-phrase (fn [new-phrase] (when @invalid-seed-phrase? - (reset! invalid-seed-phrase? false) + (reset! invalid-seed-phrase? false)) + (when @incorrect-seed-phrase? (reset! incorrect-seed-phrase? false)) (reset! seed-phrase new-phrase)) on-submit (fn [] @@ -161,7 +162,10 @@ button-disabled? (or error-state? (not (constants/seed-phrase-valid-length word-count)) (not all-words-valid?))] - [:<> + [rn/view + {:style (style/recovery-phrase-container {:insets initial-insets + :banner-offset banner-offset + :keyboard-shown? @keyboard-shown?})} [recovery-phrase-form {:title title :keypair keypair @@ -172,18 +176,18 @@ (if (fn? render-controls) (render-controls {:submit-disabled? button-disabled? :keyboard-shown? @keyboard-shown? - :container-style (style/continue-button @keyboard-shown?) + :container-style style/continue-button :prepare-seed-phrase secure-clean-seed-phrase :focus-input focus-input :seed-phrase (security/mask-data @seed-phrase) :set-incorrect-seed-phrase set-incorrect-seed-phrase}) [quo/button - {:container-style (style/continue-button @keyboard-shown?) + {:container-style style/continue-button :type :primary :disabled? button-disabled? :on-press on-submit} (i18n/label :t/continue)])] - (when @keyboard-shown? + (when (or @keyboard-shown? error-state?) [rn/view {:style style/keyboard-container} [quo/predictive-keyboard {:type suggestions-state @@ -197,7 +201,8 @@ (defn screen [{:keys [initial-insets title keypair navigation-icon recovering-keypair? render-controls]}] - (let [{navigation-bar-top :top} initial-insets] + (let [{navigation-bar-top :top} initial-insets + banner-offset (rf/sub [:alert-banners/top-margin])] [rn/view {:style style/full-layout} [rn/keyboard-avoiding-view {:style style/page-container} [quo/page-nav @@ -210,6 +215,8 @@ {:title title :keypair keypair :render-controls render-controls + :banner-offset banner-offset + :initial-insets initial-insets :recovering-keypair? recovering-keypair?}]]])) (defn view diff --git a/src/status_im/common/scan_qr_code/view.cljs b/src/status_im/common/scan_qr_code/view.cljs index 8993454abf..8b2eb7e7b4 100644 --- a/src/status_im/common/scan_qr_code/view.cljs +++ b/src/status_im/common/scan_qr_code/view.cljs @@ -195,7 +195,7 @@ true) (defn view - [{:keys [title subtitle validate-fn on-success-scan error-message share-button?]}] + [{:keys [title subtitle validate-fn on-success-scan error-message share-button? import-keypair?]}] (let [insets (safe-area/get-insets) qr-code-succeed? (reagent/atom false) qr-view-finder (reagent/atom {}) @@ -233,7 +233,9 @@ :set-qr-code-succeeded (fn [value] (when on-success-scan (on-success-scan value)) - (rf/dispatch [:navigate-back])) + (if import-keypair? + (set-rescan-timeout) + (rf/dispatch [:navigate-back]))) :set-rescan-timeout set-rescan-timeout}]) [rn/view {:style (style/root-container (:top insets))} [header diff --git a/src/status_im/common/standard_authentication/enter_password/view.cljs b/src/status_im/common/standard_authentication/enter_password/view.cljs index d6d2b2c475..398bf78a9a 100644 --- a/src/status_im/common/standard_authentication/enter_password/view.cljs +++ b/src/status_im/common/standard_authentication/enter_password/view.cljs @@ -33,6 +33,7 @@ :size 24}]] [password-input/view {:on-press-biometrics on-press-biometrics + :blur? true :processing processing :error error :default-password password diff --git a/src/status_im/common/standard_authentication/events.cljs b/src/status_im/common/standard_authentication/events.cljs index 5a22fdc662..400eee1970 100644 --- a/src/status_im/common/standard_authentication/events.cljs +++ b/src/status_im/common/standard_authentication/events.cljs @@ -20,7 +20,7 @@ (rf/reg-event-fx :standard-auth/authorize authorize) (defn authorize-with-biometric - [_ [{:keys [on-auth-success on-auth-fail] :as args}]] + [_ [{:keys [on-auth-success on-auth-fail on-close] :as args}]] (let [args-with-biometric-btn (assoc args :on-press-biometric @@ -31,7 +31,10 @@ {:prompt-message (i18n/label :t/biometric-auth-confirm-message) :on-cancel #(rf/dispatch [:standard-auth/authorize-with-password args-with-biometric-btn]) - :on-success #(rf/dispatch [:standard-auth/on-biometric-success on-auth-success]) + :on-success (fn [] + (when (fn? on-close) + (on-close)) + (rf/dispatch [:standard-auth/on-biometric-success on-auth-success])) :on-fail (fn [err] (rf/dispatch [:standard-auth/authorize-with-password args-with-biometric-btn]) diff --git a/src/status_im/common/validation/keypair.cljs b/src/status_im/common/validation/keypair.cljs index 5a71749817..c7f4c0550a 100644 --- a/src/status_im/common/validation/keypair.cljs +++ b/src/status_im/common/validation/keypair.cljs @@ -14,10 +14,12 @@ (> (-> s str string/trim count) constants/key-pair-name-max-length)) (defn validation-keypair-name - [s] + [s existing-keypair-names] (cond (string/blank? s) nil (validators/has-emojis? s) (i18n/label :t/key-name-error-emoji) (validators/has-special-characters? s) (i18n/label :t/key-name-error-special-char) - (keypair-too-short? s) (i18n/label :t/your-key-pair-name-is-too-short) - (keypair-too-long? s) (i18n/label :t/your-key-pair-name-is-too-long))) + (keypair-too-short? s) (i18n/label :t/key-name-error-too-short + {:count constants/key-pair-name-min-length}) + (keypair-too-long? s) (i18n/label :t/your-key-pair-name-is-too-long) + (contains? existing-keypair-names s) (i18n/label :t/key-name-error-taken))) diff --git a/src/status_im/common/validation/keypair_test.cljs b/src/status_im/common/validation/keypair_test.cljs index 08d83c0a65..30a5faa8e1 100644 --- a/src/status_im/common/validation/keypair_test.cljs +++ b/src/status_im/common/validation/keypair_test.cljs @@ -2,6 +2,7 @@ (:require [cljs.test :refer-macros [deftest are]] [status-im.common.validation.keypair :as keypair-validator] + [status-im.constants :as constants] [utils.i18n :as i18n])) (deftest keypair-name-too-short-test @@ -18,10 +19,12 @@ (deftest validation-keypair-name-test (are [arg expected] - (= (keypair-validator/validation-keypair-name arg) expected) + (= (keypair-validator/validation-keypair-name arg #{"Collection"}) expected) nil nil "" nil "name !" (i18n/label :t/key-name-error-special-char) "Hello 😊" (i18n/label :t/key-name-error-emoji) - "abc" (i18n/label :t/your-key-pair-name-is-too-short) + "abc" (i18n/label :t/key-name-error-too-short + {:count constants/key-pair-name-min-length}) + "Collection" (i18n/label :t/key-name-error-taken) (apply str (repeat 25 "a")) (i18n/label :t/your-key-pair-name-is-too-long))) diff --git a/src/status_im/contexts/settings/wallet/events.cljs b/src/status_im/contexts/settings/wallet/events.cljs index 25cdb6c9de..2485fd4a08 100644 --- a/src/status_im/contexts/settings/wallet/events.cljs +++ b/src/status_im/contexts/settings/wallet/events.cljs @@ -92,23 +92,28 @@ (rf/reg-event-fx :wallet/make-keypairs-accounts-fully-operable make-keypairs-accounts-fully-operable) (defn connection-string-for-import-keypair - [{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string]}]] + [{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string on-success]}]] (let [key-uid (get-in db [:profile/profile :key-uid])] {:fx [[:effects.syncing/import-keypairs-keystores {:key-uid key-uid :sha3-pwd sha3-pwd :keypairs-key-uids keypairs-key-uids :connection-string connection-string - :on-success #(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable %]) - :on-fail #(rf/dispatch [:toasts/upsert - {:type :negative - :theme :dark - :text %}])}]]})) + :on-success (fn [key-uids] + (rf/call-continuation on-success) + (rf/dispatch [:wallet/make-keypairs-accounts-fully-operable key-uids])) + :on-fail (fn [error] + (log/error "failed to import missing key pairs with connection string" + {:error error}) + (rf/dispatch [:toasts/upsert + {:type :negative + :theme :dark + :text (i18n/label :t/incorrect-qr-code)}]))}]]})) (rf/reg-event-fx :wallet/connection-string-for-import-keypair connection-string-for-import-keypair) (defn success-keypair-qr-scan - [_ [connection-string keypairs-key-uids]] + [_ [connection-string keypairs-key-uids on-import-success]] {:fx [[:dispatch [:standard-auth/authorize-with-password {:blur? true @@ -120,7 +125,8 @@ [:wallet/connection-string-for-import-keypair {:connection-string connection-string :keypairs-key-uids keypairs-key-uids - :sha3-pwd password}]))}]]]}) + :sha3-pwd password + :on-success on-import-success}]))}]]]}) (rf/reg-event-fx :wallet/success-keypair-qr-scan success-keypair-qr-scan) @@ -146,7 +152,7 @@ {:fx [[:json-rpc/call [{:method "accounts_makePrivateKeyKeypairFullyOperable" :params [(security/safe-unmask-data private-key) - (-> password security/safe-unmask-data native-module/sha3)] + (security/safe-unmask-data password)] :on-success on-success :on-error on-error}]]]}) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs index 622b64c272..6eed006d40 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/actions/view.cljs @@ -41,31 +41,37 @@ [quo/action-drawer [(when has-paired-device (if-not missing-keypair? - [{:icon :i/qr-code + [{:blur? true + :icon :i/qr-code :accessibility-label :show-key-pr-qr :label (i18n/label :t/show-encrypted-qr-of-key-pairs) :on-press on-show-qr}] - [{:icon :i/scan + [{:blur? true + :icon :i/scan :accessibility-label :import-by-scan-qr :label (i18n/label :t/import-by-scanning-encrypted-qr) :on-press on-scan-qr}])) (when (= (:type drawer-props) :keypair) [(when missing-keypair? (case (:type keypair) - :seed {:icon :i/seed + :seed {:blur? true + :icon :i/seed :accessibility-label :import-seed-phrase :label (i18n/label :t/import-by-entering-recovery-phrase) :on-press on-import-seed-phrase} - :key {:icon :i/key + :key {:blur? true + :icon :i/key :accessibility-label :import-private-key :label (i18n/label :t/import-by-entering-private-key) :on-press on-import-private-key} nil)) - {:icon :i/edit + {:blur? true + :icon :i/edit :accessibility-label :rename-key-pair :label (i18n/label :t/rename-key-pair) :on-press on-rename-keypair} - {:icon :i/delete + {:blur? true + :icon :i/delete :accessibility-label :remove-key-pair :add-divider? true :danger? true diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs index 3978f90277..df20708f05 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/missing_keypairs/scan_qr/view.cljs @@ -11,13 +11,16 @@ [] (let [keypairs-key-uids (rf/sub [:get-screen-params]) on-success-scan (rn/use-callback (fn [scanned-text] - (rf/dispatch [:wallet/success-keypair-qr-scan scanned-text - keypairs-key-uids]) + (rf/dispatch [:wallet/success-keypair-qr-scan + scanned-text + keypairs-key-uids + [:navigate-back]]) [keypairs-key-uids]))] [scan-qr-code/view {:title (i18n/label :t/scan-key-pairs-qr-code) :subtitle (i18n/label :t/find-it-in-setting) :share-button? false + :import-keypair? true :validate-fn sync-utils/valid-connection-string? - :error-message (i18n/label :t/invalid-qr) + :error-message (i18n/label :t/invalid-key-pair-qr) :on-success-scan on-success-scan}])) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/style.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/style.cljs index ae4d0edb8a..27e0142baa 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/style.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/style.cljs @@ -4,7 +4,8 @@ {:margin-bottom 8}) (def bottom-action - {:margin-horizontal -20}) + {:margin-horizontal -20 + :margin-vertical -12}) (def error-container {:margin-left 20 diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/view.cljs index 8836d1d06f..15293664f0 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/rename/view.cljs @@ -2,6 +2,7 @@ (:require [clojure.string :as string] [quo.core :as quo] [react-native.core :as rn] + [react-native.safe-area :as safe-area] [status-im.common.floating-button-page.view :as floating-button-page] [status-im.common.validation.keypair :as keypair-validator] [status-im.constants :as constants] @@ -14,19 +15,24 @@ (defn view [] - (let [{:keys [name key-uid]} (rf/sub [:get-screen-params]) + (let [insets (safe-area/get-insets) + {existing-keypair-name :name + :keys [key-uid]} (rf/sub [:get-screen-params]) + existing-keypair-names (rf/sub [:wallet/keypair-names]) customization-color (rf/sub [:profile/customization-color]) - [unsaved-keypair-name set-unsaved-keypair-name] (rn/use-state name) + [unsaved-keypair-name set-unsaved-keypair-name] (rn/use-state existing-keypair-name) [error-msg set-error-msg] (rn/use-state nil) [typing? set-typing?] (rn/use-state false) validate-keypair-name (rn/use-callback (debounce/debounce - (fn [name] + (fn [input-name] (set-error-msg (keypair-validator/validation-keypair-name - name)) + input-name + existing-keypair-names)) (set-typing? false)) - 300)) + 300) + [existing-keypair-names]) on-change-text (rn/use-callback (fn [text] (set-typing? true) (set-unsaved-keypair-name @@ -40,45 +46,57 @@ :keypair-name unsaved-keypair-name}]) [unsaved-keypair-name key-uid])] - [floating-button-page/view - {:header [quo/page-nav - {:icon-name :i/close - :on-press navigate-back - :accessibility-label :top-bar}] - :footer [quo/bottom-actions - {:actions :one-action - :button-one-label (i18n/label :t/save) - :button-one-props {:disabled? (or typing? - (string/blank? unsaved-keypair-name) - (not (string/blank? error-msg))) - :customization-color customization-color - :on-press on-save} - :container-style style/bottom-action}]} - [quo/page-top - {:container-style style/header-container - :title (i18n/label :t/rename-key-pair) - :description :context-tag - :context-tag {:type :icon - :size 24 - :context name - :icon :i/seed-phrase}}] - [quo/input - {:container-style {:margin-horizontal 20} - :placeholder (i18n/label :t/keypair-name-input-placeholder) - :label (i18n/label :t/keypair-name) - :default-value unsaved-keypair-name - :char-limit constants/key-pair-name-max-length - :max-length constants/key-pair-name-max-length - :auto-focus true - :clearable? (not (string/blank? unsaved-keypair-name)) - :on-clear on-clear - :on-change-text on-change-text - :error? (not (string/blank? error-msg))}] - (when-not (string/blank? error-msg) - [quo/info-message - {:type :error - :size :default - :icon :i/info - :container-style style/error-container} - error-msg])])) + [quo/overlay {:type :shell} + [floating-button-page/view + {:footer-container-padding 0 + :blur? true + :header [quo/page-nav + {:margin-top (:top insets) + :icon-name :i/close + :background :blur + :on-press navigate-back + :accessibility-label :top-bar}] + :footer [quo/bottom-actions + {:actions :one-action + :blur? true + :button-one-label (i18n/label :t/save) + :button-one-props {:blur? true + :disabled? (or typing? + (= existing-keypair-name + unsaved-keypair-name) + (string/blank? + unsaved-keypair-name) + (not (string/blank? + error-msg))) + :customization-color customization-color + :on-press on-save} + :container-style style/bottom-action}]} + [quo/page-top + {:container-style style/header-container + :title (i18n/label :t/rename-key-pair) + :description :context-tag + :blur? true + :context-tag {:type :icon + :size 24 + :context existing-keypair-name + :icon :i/seed-phrase}}] + [quo/input + {:blur? true + :container-style {:margin-horizontal 20} + :placeholder (i18n/label :t/keypair-name-input-placeholder) + :label (i18n/label :t/keypair-name) + :default-value unsaved-keypair-name + :char-limit constants/key-pair-name-max-length + :auto-focus true + :clearable? (not (string/blank? unsaved-keypair-name)) + :on-clear on-clear + :on-change-text on-change-text + :error? (not (string/blank? error-msg))}] + (when-not (string/blank? error-msg) + [quo/info-message + {:type :error + :size :default + :icon :i/info + :container-style style/error-container} + error-msg])]])) diff --git a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/view.cljs b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/view.cljs index cf2e8a33b9..97a159a2f7 100644 --- a/src/status_im/contexts/settings/wallet/keypairs_and_accounts/view.cljs +++ b/src/status_im/contexts/settings/wallet/keypairs_and_accounts/view.cljs @@ -1,11 +1,11 @@ (ns status-im.contexts.settings.wallet.keypairs-and-accounts.view (:require [quo.core :as quo] - [quo.foundations.colors :as colors] [quo.theme] [react-native.core :as rn] [react-native.safe-area :as safe-area] [status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view :as actions] [status-im.contexts.settings.wallet.keypairs-and-accounts.style :as style] + [status-im.feature-flags :as ff] [utils.address :as utils] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -17,13 +17,12 @@ (defn on-options-press [{:keys [drawer-props keypair]}] (rf/dispatch [:show-bottom-sheet - {:content (fn [] [actions/view - {:drawer-props drawer-props - :keypair keypair}]) + {:content (fn [] [actions/view + {:drawer-props drawer-props + :keypair keypair}]) - :blur-background colors/bottom-sheet-background-blur - :theme (:theme drawer-props) - :shell? true}])) + :theme (:theme drawer-props) + :shell? true}])) (defn options-drawer-props [{{:keys [name]} :keypair @@ -70,7 +69,7 @@ {:blur? true :status-indicator false :stored :on-device - :action :options + :action (if default-keypair? :none :options) :accounts accounts :customization-color customization-color :container-style style/keypair-container-style @@ -83,17 +82,16 @@ (defn on-missing-keypair-options-press [_event keypair-data] (rf/dispatch [:show-bottom-sheet - {:theme :dark - :shell? true - :blur-background colors/bottom-sheet-background-blur - :content (fn [] [actions/view - {:keypair keypair-data - :drawer-props (options-drawer-props - {:theme :dark - :type :keypair - :stored :missing - :blur? true - :keypair keypair-data})}])}])) + {:theme :dark + :shell? true + :content (fn [] [actions/view + {:keypair keypair-data + :drawer-props (options-drawer-props + {:theme :dark + :type :keypair + :stored :missing + :blur? true + :keypair keypair-data})}])}])) (defn view [] @@ -127,6 +125,7 @@ :header (when (seq missing-keypairs) [quo/missing-keypairs {:blur? true + :show-import-all? (ff/enabled? ::ff/settings.import-all-keypairs) :keypairs missing-keypairs :on-import-press on-import-press :container-style style/missing-keypairs-container-style diff --git a/src/status_im/contexts/settings/wallet/network_settings/view.cljs b/src/status_im/contexts/settings/wallet/network_settings/view.cljs index 8f11afc0af..5058abd8b2 100644 --- a/src/status_im/contexts/settings/wallet/network_settings/view.cljs +++ b/src/status_im/contexts/settings/wallet/network_settings/view.cljs @@ -1,6 +1,5 @@ (ns status-im.contexts.settings.wallet.network-settings.view (:require [quo.core :as quo] - [quo.foundations.colors :as colors] [quo.foundations.resources :as resources] [quo.theme] [react-native.core :as rn] @@ -80,12 +79,11 @@ (defn on-change-testnet [{:keys [enable? blur? theme]}] (rf/dispatch [:show-bottom-sheet - {:content (fn [] [testnet/view - {:enable? enable? - :blur? blur?}]) - :theme theme - :shell? blur? - :blur-background colors/bottom-sheet-background-blur}])) + {:content (fn [] [testnet/view + {:enable? enable? + :blur? blur?}]) + :theme theme + :shell? blur?}])) (defn view [] diff --git a/src/status_im/contexts/settings/wallet/saved_addresses/sheets/address_options/view.cljs b/src/status_im/contexts/settings/wallet/saved_addresses/sheets/address_options/view.cljs index 0fa354a19e..f0dc8e39a0 100644 --- a/src/status_im/contexts/settings/wallet/saved_addresses/sheets/address_options/view.cljs +++ b/src/status_im/contexts/settings/wallet/saved_addresses/sheets/address_options/view.cljs @@ -2,7 +2,6 @@ (:require [clojure.string :as string] [quo.core :as quo] - [quo.foundations.colors :as colors] [react-native.core :as rn] [react-native.platform :as platform] [status-im.constants :as constants] @@ -52,11 +51,10 @@ open-remove-confirmation-sheet (rn/use-callback #(rf/dispatch [:show-bottom-sheet - {:theme :dark - :shell? true - :blur-background colors/bottom-sheet-background-blur - :content (fn [] - [remove-address/view opts])}]) + {:theme :dark + :shell? true + :content (fn [] + [remove-address/view opts])}]) [opts]) open-show-address-qr (rn/use-callback #(rf/dispatch [:open-modal diff --git a/src/status_im/contexts/settings/wallet/wallet_options/view.cljs b/src/status_im/contexts/settings/wallet/wallet_options/view.cljs index 67cbc20d8f..58153e98c5 100644 --- a/src/status_im/contexts/settings/wallet/wallet_options/view.cljs +++ b/src/status_im/contexts/settings/wallet/wallet_options/view.cljs @@ -16,11 +16,10 @@ (defn basic-settings-options [] - [(when (ff/enabled? ::ff/settings.keypairs-and-accounts) - {:title (i18n/label :t/keypairs-and-accounts) - :blur? true - :on-press open-keypairs-and-accounts-settings-modal - :action :arrow}) + [{:title (i18n/label :t/keypairs-and-accounts) + :blur? true + :on-press open-keypairs-and-accounts-settings-modal + :action :arrow} (when (ff/enabled? ::ff/settings.saved-addresses) {:title (i18n/label :t/saved-addresses) :blur? true @@ -74,7 +73,5 @@ [quo/page-top {:title (i18n/label :t/wallet) :title-accessibility-label :wallet-settings-header}] - (when (or (ff/enabled? ::ff/settings.keypairs-and-accounts) - (ff/enabled? ::ff/settings.saved-addresses)) - [basic-settings]) + [basic-settings] [advanced-settings]])) diff --git a/src/status_im/contexts/wallet/effects.cljs b/src/status_im/contexts/wallet/effects.cljs index 8c0fedae29..e2fe3c4147 100644 --- a/src/status_im/contexts/wallet/effects.cljs +++ b/src/status_im/contexts/wallet/effects.cljs @@ -73,7 +73,7 @@ (fn [resolver rejecter] (json-rpc/call {:method "accounts_makeSeedPhraseKeypairFullyOperable" :params [(security/safe-unmask-data mnemonic) - (-> password security/safe-unmask-data native-module/sha3)] + (security/safe-unmask-data password)] :on-error (fn [error] (rejecter (ex-info (str error) {:error error}))) :on-success (fn [value] diff --git a/src/status_im/contexts/wallet/events.cljs b/src/status_im/contexts/wallet/events.cljs index 0ab6654e7e..5b751cf6d2 100644 --- a/src/status_im/contexts/wallet/events.cljs +++ b/src/status_im/contexts/wallet/events.cljs @@ -529,18 +529,17 @@ :wallet/process-keypair-from-backup (fn [{:keys [db]} [{:keys [backedUpKeypair]}]] (let [{:keys [key-uid accounts]} backedUpKeypair - updated-keypairs (assoc-in db - [:wallet :keypairs key-uid] - (data-store/rpc->keypair backedUpKeypair)) - accounts-fx (mapv (fn [{:keys [chat] :as account}] - ;; We exclude the chat account from the profile keypair - ;; for fetching the assets - (when-not chat - [:dispatch - [:wallet/process-account-from-signal - account]])) - accounts)] - {:db (assoc-in db [:wallet :keypairs] updated-keypairs) + accounts-fx + (mapv (fn [{:keys [chat] :as account}] + ;; We exclude the chat account from the profile keypair for fetching the assets + (when-not chat + [:dispatch + [:wallet/process-account-from-signal + account]])) + accounts)] + {:db (assoc-in db + [:wallet :keypairs key-uid] + (data-store/rpc->keypair backedUpKeypair)) :fx accounts-fx}))) (rf/reg-event-fx diff --git a/src/status_im/feature_flags.cljs b/src/status_im/feature_flags.cljs index 48670c02bb..cd83ce2398 100644 --- a/src/status_im/feature_flags.cljs +++ b/src/status_im/feature_flags.cljs @@ -11,10 +11,10 @@ (def ^:private initial-flags {::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED) - ::settings.keypairs-and-accounts (enabled-in-env? - :FLAG_WALLET_SETTINGS_KEYPAIRS_AND_ACCOUNTS_ENABLED) ::settings.saved-addresses (enabled-in-env? :FLAG_WALLET_SETTINGS_SAVED_ADDRESSES_ENABLED) + ::settings.import-all-keypairs (enabled-in-env? + :FLAG_WALLET_SETTINGS_IMPORT_ALL_KEYPAIRS) ::shell.jump-to (enabled-in-env? :ENABLE_JUMP_TO) ::wallet.advanced-sending (enabled-in-env? :FLAG_ADVANCED_SENDING) ::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index 363de5202f..9b83b4441d 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -542,7 +542,7 @@ :component wallet-options/view} {:name :screen/settings.rename-keypair - :options (assoc options/dark-screen :sheet? true) + :options options/transparent-screen-options :component keypair-rename/view} {:name :screen/settings.encrypted-keypair-qr @@ -558,7 +558,7 @@ :component keypairs-and-accounts/view} {:name :screen/settings.scan-keypair-qr - :options options/transparent-modal-screen-options + :options options/transparent-screen-options :component scan-keypair-qr/view} {:name :screen/settings.missing-keypair.import-seed-phrase diff --git a/src/status_im/subs/wallet/wallet.cljs b/src/status_im/subs/wallet/wallet.cljs index b83496e5e3..e481c1c7fb 100644 --- a/src/status_im/subs/wallet/wallet.cljs +++ b/src/status_im/subs/wallet/wallet.cljs @@ -205,6 +205,12 @@ (fn [{:keys [keypairs]}] (vals keypairs))) +(rf/reg-sub + :wallet/keypair-names + :<- [:wallet/keypairs-list] + (fn [keypairs] + (set (map :name keypairs)))) + (rf/reg-sub :wallet/selected-keypair-uid :<- [:wallet/create-account] @@ -244,7 +250,7 @@ size 32}}] (->> accounts (keep (fn [{:keys [path color emoji name address]}] - (when-not (string/starts-with? path constants/path-eip1581) + (when-not (string/starts-with? (str path) constants/path-eip1581) {:account-props {:customization-color color :size size :emoji emoji diff --git a/src/status_im/subs/wallet/wallet_test.cljs b/src/status_im/subs/wallet/wallet_test.cljs index 2989f29adb..546cf798c6 100644 --- a/src/status_im/subs/wallet/wallet_test.cljs +++ b/src/status_im/subs/wallet/wallet_test.cljs @@ -643,18 +643,20 @@ :removed false}) (def profile-key-pair-key-uid "abc") +(def profile-key-pair-name "My Profile") (def seed-phrase-key-pair-key-uid "def") +(def seed-phrase-key-pair-name "My Key Pair") (def profile-keypair {:key-uid profile-key-pair-key-uid - :name "My Profile" + :name profile-key-pair-name :type :profile :lowest-operability :fully :accounts []}) (def seed-phrase-keypair {:key-uid seed-phrase-key-pair-key-uid - :name "My Key Pair" + :name seed-phrase-key-pair-name :type :seed :lowest-operability :no :accounts []}) @@ -676,6 +678,14 @@ (is (= 2 (count result))) (is (match? expected result)))) +(h/deftest-sub :wallet/keypair-names + [sub-name] + (swap! rf-db/app-db assoc-in + [:wallet :keypairs] + {profile-key-pair-key-uid profile-keypair + seed-phrase-key-pair-key-uid seed-phrase-keypair}) + (is (match? #{seed-phrase-key-pair-name profile-key-pair-name} (rf/sub [sub-name])))) + (h/deftest-sub :wallet/settings-keypairs-accounts [sub-name] (testing "returns formatted key-pairs and accounts" diff --git a/translations/en.json b/translations/en.json index f6bb549e2d..143f3a7d0e 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1302,6 +1302,8 @@ "scan-with-status-app": "Scan with the Status app on another device", "scan-key-pairs-qr-code": "Scan key pairs QR code", "invalid-qr": "Oops! This QR doesn’t work with Status", + "invalid-key-pair-qr": "This does not look like a key pair QR code", + "incorrect-qr-code": "This is not the QR code you are looking for", "search": "Search", "search-discover-communities": "Search communities or categories", "secret-keys-confirmation-text": "You will need them to continue to use your Keycard in case you ever lose your phone.", @@ -2639,6 +2641,7 @@ "max": "Max: {{number}}", "your-key-pair-name-is-too-long": "Your key pair name is too long", "your-key-pair-name-is-too-short": "Your key pair name is too short", + "key-name-error-taken": "Key pair name already in use", "key-name-error-length": "Key name too long", "key-name-error-emoji": "Emojis are not allowed", "key-name-error-special-char": "Special characters are not allowed",