Add screen for key-pairs and accounts inside wallet settings (#19912)
* chore: add "key pairs and accounts" label * chore: feature flag wallet-settings * tidy: extact navigate-back function into static defn * wip: add initial keypairs and accounts list view to wallet settings * tweak: wire-up initial action menu for key-pairs * tidy: extract key-pair container styles into style namespace * tweak: fix dark background for key-pair and account settings * tidy: refactor on-press handler for key-pair options * fix: move feature-flag usage to settings screen instead of settings items definition * tidy: remove unneeded key props * tidy: clean up de-structuring and passing of props * tidy: use keep with when expressions instead of filter and map expressions * tidy: rename the wallet-settings feature flag * tweak: rename and add feature-flags for mobile wallet settings * tweak: use scrollview for feature-flags and add spacing between feature-flag groups * tweak: adjust the way feature-flags are displayed in groups * tidy: remove unneeded prop * tidy: use bottom-inset for padding key-pair and accounts list * tidy: change `filterv` to `filter` * tidy: use subscription for building account-props * tidy: use subscription to build the entire keypair-account * tweak: use key-pair type to determine default key-pair * tidy: rename component to settings-category-view * tidy: use assoc instead of merge * tidy: extract function from subscription * test: add tests for formatting key-pairs and accounts for wallet settings * tweak: use `match?` instead of `=` * tidy: use `swap!` without anonymous functions
This commit is contained in:
parent
c40853456b
commit
4f0a49f7bf
|
@ -1,5 +1,6 @@
|
|||
(ns status-im.contexts.preview.feature-flags.style)
|
||||
|
||||
(def container
|
||||
{:flex 1
|
||||
:margin-left 20})
|
||||
{:flex 1
|
||||
:margin-left 20
|
||||
:margin-bottom 20})
|
||||
|
|
|
@ -18,23 +18,25 @@
|
|||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side [{:icon-name :i/rotate
|
||||
:on-press #(ff/reset-flags)}]}]
|
||||
(doall
|
||||
(for [context-name ff/feature-flags-categories
|
||||
:let [context-flags (filter (fn [[k]]
|
||||
(string/includes? (str k) context-name))
|
||||
(ff/feature-flags))]]
|
||||
^{:key (str context-name)}
|
||||
[rn/view {:style style/container}
|
||||
[quo/text
|
||||
context-name]
|
||||
(doall
|
||||
(for [i (range (count context-flags))
|
||||
:let [[flag] (nth context-flags i)]]
|
||||
^{:key (str context-name flag i)}
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[quo/selectors
|
||||
{:type :toggle
|
||||
:checked? (ff/enabled? flag)
|
||||
:container-style {:margin-right 8}
|
||||
:on-change #(ff/toggle flag)}]
|
||||
[quo/text (second (string/split (name flag) "."))]]))]))])
|
||||
[rn/scroll-view
|
||||
(doall
|
||||
(for [context-name ff/feature-flags-categories
|
||||
:let [context-flags (filter (fn [[k]]
|
||||
(= context-name
|
||||
(first (string/split (str (name k)) "."))))
|
||||
(ff/feature-flags))]]
|
||||
^{:key (str context-name)}
|
||||
[rn/view {:style style/container}
|
||||
[quo/text
|
||||
context-name]
|
||||
(doall
|
||||
(for [i (range (count context-flags))
|
||||
:let [[flag] (nth context-flags i)]]
|
||||
^{:key (str context-name flag i)}
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[quo/selectors
|
||||
{:type :toggle
|
||||
:checked? (ff/enabled? flag)
|
||||
:container-style {:margin-right 8}
|
||||
:on-change #(ff/toggle flag)}]
|
||||
[quo/text (second (string/split (name flag) "."))]]))]))]])
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.contexts.profile.settings.list-items
|
||||
(:require [status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.config :as config]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
@ -34,12 +35,13 @@
|
|||
:image :icon
|
||||
:blur? true
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/wallet)
|
||||
:on-press #(rf/dispatch [:open-modal :screen/settings.wallet])
|
||||
:image-props :i/wallet
|
||||
:image :icon
|
||||
:blur? true
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/wallet)
|
||||
:on-press #(rf/dispatch [:open-modal :screen/settings.wallet])
|
||||
:image-props :i/wallet
|
||||
:image :icon
|
||||
:blur? true
|
||||
:action :arrow
|
||||
:feature-flag ::ff/settings.wallet-settings}
|
||||
(when config/show-not-implemented-features?
|
||||
{:title (i18n/label :t/dapps)
|
||||
:on-press not-implemented/alert
|
||||
|
|
|
@ -9,18 +9,24 @@
|
|||
[status-im.contexts.profile.settings.list-items :as settings.items]
|
||||
[status-im.contexts.profile.settings.style :as style]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- settings-item-view
|
||||
(defn show-settings-item?
|
||||
[{:keys [feature-flag]}]
|
||||
(or (ff/enabled? feature-flag)
|
||||
(nil? feature-flag)))
|
||||
|
||||
(defn- settings-category-view
|
||||
[data]
|
||||
[rf/delay-render
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:container-style {:padding-bottom 12}
|
||||
:blur? true
|
||||
:data data}]])
|
||||
:data (filter show-settings-item? data)}]])
|
||||
|
||||
(defn scroll-handler
|
||||
[event scroll-y]
|
||||
|
@ -52,8 +58,7 @@
|
|||
on-scroll (rn/use-callback #(scroll-handler % scroll-y))]
|
||||
[quo/overlay {:type :shell}
|
||||
[rn/view
|
||||
{:key :header
|
||||
:style (style/navigation-wrapper {:customization-color customization-color
|
||||
{:style (style/navigation-wrapper {:customization-color customization-color
|
||||
:inset (:top insets)
|
||||
:theme theme})}
|
||||
[quo/page-nav
|
||||
|
@ -72,11 +77,10 @@
|
|||
{:options {:message (:universal-profile-url
|
||||
profile)}}])}]}]]
|
||||
[rn/flat-list
|
||||
{:key :list
|
||||
:header [settings.header/view {:scroll-y scroll-y}]
|
||||
{:header [settings.header/view {:scroll-y scroll-y}]
|
||||
:data (settings.items/items (boolean (:mnemonic profile)))
|
||||
:shows-vertical-scroll-indicator false
|
||||
:render-fn settings-item-view
|
||||
:render-fn settings-category-view
|
||||
:get-item-layout get-item-layout
|
||||
:footer [footer insets logout-press]
|
||||
:scroll-event-throttle 16
|
||||
|
@ -84,8 +88,7 @@
|
|||
:bounces false
|
||||
:over-scroll-mode :never}]
|
||||
[quo/floating-shell-button
|
||||
{:key :shell
|
||||
:jump-to
|
||||
{:jump-to
|
||||
{:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
|
||||
:customization-color customization-color
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view
|
||||
(:require [quo.core :as quo]))
|
||||
|
||||
(defn view
|
||||
[props]
|
||||
[quo/drawer-top props])
|
|
@ -0,0 +1,18 @@
|
|||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.style)
|
||||
|
||||
(def title-container
|
||||
{:padding-horizontal 20
|
||||
:margin-vertical 12})
|
||||
|
||||
(defn page-wrapper
|
||||
[top-inset]
|
||||
{:padding-top top-inset
|
||||
:flex 1})
|
||||
|
||||
(defn list-container
|
||||
[bottom-inset]
|
||||
{:padding-bottom bottom-inset})
|
||||
|
||||
(def keypair-container-style
|
||||
{:margin-horizontal 20
|
||||
:margin-vertical 8})
|
|
@ -0,0 +1,89 @@
|
|||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.view
|
||||
(:require [quo.core :as quo]
|
||||
[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]
|
||||
[utils.address :as utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn on-options-press
|
||||
[{:keys [theme]
|
||||
:as props}]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [actions/view props])
|
||||
:theme theme}]))
|
||||
|
||||
(defn- keypair
|
||||
[{keypair-type :type
|
||||
:keys [accounts name]}
|
||||
_ _
|
||||
{:keys [profile-picture compressed-key customization-color]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
default-keypair? (= keypair-type :profile)
|
||||
shortened-key (when default-keypair?
|
||||
(utils/get-shortened-compressed-key compressed-key))
|
||||
on-press (rn/use-callback
|
||||
(fn []
|
||||
(on-options-press
|
||||
(cond-> {:theme theme
|
||||
:blur? true
|
||||
:title name}
|
||||
default-keypair?
|
||||
(assoc :type :default-keypair
|
||||
:description shortened-key
|
||||
:customization-color customization-color
|
||||
:profile-picture profile-picture)
|
||||
(not default-keypair?)
|
||||
(assoc :type :keypair
|
||||
:icon-avatar :i/seed))))
|
||||
[customization-color default-keypair? name
|
||||
profile-picture shortened-key theme])]
|
||||
[quo/keypair
|
||||
{:blur? false
|
||||
:status-indicator false
|
||||
:stored :on-device
|
||||
:action :options
|
||||
:accounts accounts
|
||||
:customization-color customization-color
|
||||
:container-style style/keypair-container-style
|
||||
:profile-picture (when default-keypair? profile-picture)
|
||||
:type (if default-keypair? :default-keypair :other)
|
||||
:on-options-press on-press
|
||||
:details {:full-name name
|
||||
:address shortened-key}}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [insets (safe-area/get-insets)
|
||||
compressed-key (rf/sub [:profile/compressed-key])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
quo-keypairs-accounts (rf/sub [:wallet/settings-keypairs-accounts])]
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:container-style (style/page-wrapper (:top insets))}
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back}]
|
||||
[rn/view {:style style/title-container}
|
||||
[quo/standard-title
|
||||
{:title (i18n/label :t/keypairs-and-accounts)
|
||||
:accessibility-label :keypairs-and-accounts-header
|
||||
:customization-color customization-color}]]
|
||||
[rn/view {:style {:flex 1}}
|
||||
[rn/flat-list
|
||||
{:data quo-keypairs-accounts
|
||||
:render-fn keypair
|
||||
:render-data {:profile-picture profile-picture
|
||||
:compressed-key compressed-key
|
||||
:customization-color customization-color}
|
||||
:content-container-style (style/list-container (:bottom insets))}]]]))
|
|
@ -1,8 +1,8 @@
|
|||
(ns status-im.contexts.settings.wallet.wallet-options.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.contexts.settings.wallet.wallet-options.style :as style]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
@ -10,9 +10,18 @@
|
|||
[]
|
||||
(rf/dispatch [:open-modal :screen/settings.saved-addresses]))
|
||||
|
||||
(defn open-keypairs-and-accounts-settings-modal
|
||||
[]
|
||||
(rf/dispatch [:open-modal :screen/settings.keypairs-and-accounts]))
|
||||
|
||||
(defn gen-basic-settings-options
|
||||
[]
|
||||
[{:title (i18n/label :t/saved-addresses)
|
||||
[(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/saved-addresses)
|
||||
:blur? true
|
||||
:on-press open-saved-addresses-settings-modal
|
||||
:action :arrow}])
|
||||
|
@ -26,11 +35,13 @@
|
|||
:blur? true
|
||||
:list-type :settings}])
|
||||
|
||||
(defn navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [inset-top (safe-area/get-top)
|
||||
navigate-back (rn/use-callback
|
||||
#(rf/dispatch [:navigate-back]))]
|
||||
(let [inset-top (safe-area/get-top)]
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:container-style (style/page-wrapper inset-top)}
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
|
||||
(def ^:private initial-flags
|
||||
{::community.edit-account-selection (enabled-in-env? :FLAG_EDIT_ACCOUNT_SELECTION_ENABLED)
|
||||
::settings.wallet-settings (enabled-in-env? :FLAG_WALLET_SETTINGS_ENABLED)
|
||||
::settings.keypairs-and-accounts (enabled-in-env?
|
||||
:FLAG_WALLET_SETTINGS_KEYPAIRS_AND_ACCOUNTS_ENABLED)
|
||||
::wallet.activities (enabled-in-env? :FLAG_WALLET_ACTIVITY_ENABLED)
|
||||
::wallet.assets-modal-hide (enabled-in-env? :FLAG_ASSETS_MODAL_HIDE)
|
||||
::wallet.assets-modal-manage-tokens (enabled-in-env? :FLAG_ASSETS_MODAL_MANAGE_TOKENS)
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
[status-im.contexts.profile.settings.screens.password.change-password.view :as change-password]
|
||||
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
|
||||
[status-im.contexts.profile.settings.view :as settings]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.view :as saved-addresses-settings]
|
||||
[status-im.contexts.settings.wallet.wallet-options.view :as wallet-options]
|
||||
[status-im.contexts.shell.activity-center.view :as activity-center]
|
||||
|
@ -501,6 +502,12 @@
|
|||
:options options/transparent-modal-screen-options
|
||||
:component saved-addresses-settings/view}
|
||||
|
||||
{:name :screen/settings.keypairs-and-accounts
|
||||
:options (merge
|
||||
options/transparent-modal-screen-options
|
||||
options/dark-screen)
|
||||
:component keypairs-and-accounts/view}
|
||||
|
||||
{:name :screen/settings-messages
|
||||
:options options/transparent-modal-screen-options
|
||||
:component settings.messages/view}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
(ns status-im.subs.wallet.wallet
|
||||
(:require [clojure.string :as string]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.subs.wallet.add-account.address-to-watch]
|
||||
|
@ -158,6 +159,34 @@
|
|||
:goerli-enabled? goerli-enabled?})
|
||||
selected-networks))))
|
||||
|
||||
(defn- format-settings-keypair-accounts
|
||||
[accounts
|
||||
{:keys [networks size]
|
||||
:or {networks []
|
||||
size 32}}]
|
||||
(->> accounts
|
||||
(keep (fn [{:keys [path customization-color emoji name address]}]
|
||||
(when-not (string/starts-with? path constants/path-eip1581)
|
||||
{:account-props {:customization-color customization-color
|
||||
:size size
|
||||
:emoji emoji
|
||||
:type :default
|
||||
:name name
|
||||
:address address}
|
||||
:networks networks
|
||||
:state :default
|
||||
:action :none})))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/settings-keypairs-accounts
|
||||
:<- [:wallet/keypairs]
|
||||
(fn [keypairs [_ format-options]]
|
||||
(->> keypairs
|
||||
(map (fn [{:keys [accounts name type]}]
|
||||
{:type (keyword type)
|
||||
:name name
|
||||
:accounts (format-settings-keypair-accounts accounts format-options)})))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/derivation-path-state
|
||||
:<- [:wallet/create-account]
|
||||
|
|
|
@ -554,6 +554,109 @@
|
|||
(= keypairs
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
(def chat-account
|
||||
{:path "m/43'/60'/1581'/0'/0"
|
||||
:emoji ""
|
||||
:key-uid "abc"
|
||||
:address "address-1"
|
||||
:color-id ""
|
||||
:wallet false
|
||||
:name "My Profile"
|
||||
:type "generated"
|
||||
:chat true
|
||||
:customization-color :blue
|
||||
:hidden false
|
||||
:removed false})
|
||||
|
||||
(def wallet-account
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:emoji "🤡"
|
||||
:key-uid "abc"
|
||||
:address "address-2"
|
||||
:wallet true
|
||||
:name "My Account"
|
||||
:type "generated"
|
||||
:chat false
|
||||
:customization-color :primary
|
||||
:hidden false
|
||||
:removed false})
|
||||
|
||||
(def keypairs-accounts
|
||||
{:key-uid "abc"
|
||||
:name "My Profile"
|
||||
:type "profile"
|
||||
:accounts []})
|
||||
|
||||
(h/deftest-sub :wallet/settings-keypairs-accounts
|
||||
[sub-name]
|
||||
(testing "returns formatted key-pairs and accounts"
|
||||
(swap! rf-db/app-db
|
||||
assoc-in
|
||||
[:wallet :keypairs]
|
||||
[(assoc keypairs-accounts
|
||||
:accounts
|
||||
[wallet-account])])
|
||||
|
||||
(let [{:keys [customization-color name address emoji]} wallet-account]
|
||||
(is
|
||||
(match? [{:name (:name keypairs-accounts)
|
||||
:type (keyword (:type keypairs-accounts))
|
||||
:accounts [{:account-props {:customization-color customization-color
|
||||
:size 32
|
||||
:emoji emoji
|
||||
:type :default
|
||||
:name name
|
||||
:address address}
|
||||
:networks []
|
||||
:state :default
|
||||
:action :none}]}]
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
(testing "allows for passing account format options"
|
||||
(swap! rf-db/app-db
|
||||
assoc-in
|
||||
[:wallet :keypairs]
|
||||
[(assoc keypairs-accounts
|
||||
:accounts
|
||||
[wallet-account])])
|
||||
|
||||
(let [{:keys [customization-color
|
||||
name
|
||||
address
|
||||
emoji]} wallet-account
|
||||
network-options [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}
|
||||
{:network-name :arbitrum :short-name "arb1"}]
|
||||
size-option 20]
|
||||
(is
|
||||
(match? [{:name (:name keypairs-accounts)
|
||||
:type (keyword (:type keypairs-accounts))
|
||||
:accounts [{:account-props {:customization-color customization-color
|
||||
:size size-option
|
||||
:emoji emoji
|
||||
:type :default
|
||||
:name name
|
||||
:address address}
|
||||
:networks network-options
|
||||
:state :default
|
||||
:action :none}]}]
|
||||
(rf/sub [sub-name
|
||||
{:networks network-options
|
||||
:size size-option}])))))
|
||||
|
||||
(testing "filters non-wallet accounts"
|
||||
(swap! rf-db/app-db
|
||||
assoc-in
|
||||
[:wallet :keypairs]
|
||||
[(assoc keypairs-accounts
|
||||
:accounts
|
||||
[chat-account])])
|
||||
(is
|
||||
(match? [{:name (:name keypairs-accounts)
|
||||
:type (keyword (:type keypairs-accounts))
|
||||
:accounts []}]
|
||||
(rf/sub [sub-name])))))
|
||||
|
||||
(def local-suggestions ["a" "b"])
|
||||
|
||||
(h/deftest-sub :wallet/local-suggestions
|
||||
|
|
|
@ -2484,6 +2484,7 @@
|
|||
"address-no-activity": "This address has no activity",
|
||||
"scanning": "Scanning for activity...",
|
||||
"keypairs": "Key pairs",
|
||||
"keypairs-and-accounts": "Key pairs and accounts",
|
||||
"keypairs-accounts-and-addresses": "Key pairs, accounts and addresses",
|
||||
"keypairs-description": "Select key pair to derive your new account from",
|
||||
"confirm-account-origin": "Confirm account origin",
|
||||
|
|
Loading…
Reference in New Issue