chore: add ability to create watch address & some related ui changes on account page (#17868)

This commit is contained in:
Jamie Caprani 2023-12-01 12:29:01 +00:00 committed by GitHub
parent 04dee8be45
commit f9f328107d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 137 additions and 107 deletions

View File

@ -30,6 +30,6 @@
{:accessibility-label :account-emoji {:accessibility-label :account-emoji
:adjusts-font-size-to-fit true :adjusts-font-size-to-fit true
:style {:font-size emoji-size}} :style {:font-size emoji-size}}
(string/trim emoji)]])) (when emoji (string/trim emoji))]]))
(def view (quo.theme/with-theme view-internal)) (def view (quo.theme/with-theme view-internal))

View File

@ -67,7 +67,7 @@
[rn/text [rn/text
{:style (style/emoji-size size) {:style (style/emoji-size size)
:accessibility-label :emoji} :accessibility-label :emoji}
(string/trim emoji)]) (when emoji (string/trim emoji))])
[lock locked? size theme]]) [lock locked? size theme]])
(def view (quo.theme/with-theme view-internal)) (def view (quo.theme/with-theme view-internal))

View File

@ -56,6 +56,6 @@
:size (:font-size (size properties)) :size (:font-size (size properties))
:weight (if monospace? :monospace (:font-weight (size properties))) :weight (if monospace? :monospace (:font-weight (size properties)))
:style (style/text customization-color neutral? theme)} :style (style/text customization-color neutral? theme)}
(if lowercase? (string/lower-case initials) initials)]])) (if (and initials lowercase?) (string/lower-case initials) initials)]]))
(def wallet-user-avatar (quo.theme/with-theme view-internal)) (def wallet-user-avatar (quo.theme/with-theme view-internal))

View File

@ -133,7 +133,7 @@
| key | description | | key | description |
| -------------|-------------| | -------------|-------------|
| `:account-name` | A value representing the account name (default `nil`) | `:account-name` | A value representing the account name (default `nil`)
| `:account` | A value that represents if the account is a `:watched-account` or a `:default` account. (default `nil`) | `:account` | A value that represents if the account is a `:watched-address` or a `:default` account. (default `nil`)
| `:time-frame` | A value that represents the type of the timeframe, Can be from a preset of time frames. `[:1-week :1-month :3-months :1-year :custom]` (default `nil`) if custom is set, We expect a start time and if there's a space between two times that are in `time-frame-string` we'll split them with an arrow to the right icon | `:time-frame` | A value that represents the type of the timeframe, Can be from a preset of time frames. `[:1-week :1-month :3-months :1-year :custom]` (default `nil`) if custom is set, We expect a start time and if there's a space between two times that are in `time-frame-string` we'll split them with an arrow to the right icon
| `:loading?` | A value that indicates that component is loading data. (default `nil`) | `:loading?` | A value that indicates that component is loading data. (default `nil`)
| `:metrics` | A value that indicates if the account value have increased can be `:positive` or `:negative` (default `nil`) | `:metrics` | A value that indicates if the account value have increased can be `:positive` or `:negative` (default `nil`)

View File

@ -117,7 +117,7 @@
[rn/view [rn/view
{:style (style/sheet-content theme padding-bottom-override insets shell? bottom-margin) {:style (style/sheet-content theme padding-bottom-override insets shell? bottom-margin)
:on-layout #(reset! sheet-height (.-nativeEvent.layout.height ^js %))} :on-layout #(reset! sheet-height (.-nativeEvent.layout.height ^js %))}
(when gradient-cover? (when (and gradient-cover? customization-color)
[rn/view {:style style/gradient-bg} [rn/view {:style style/gradient-bg}
[quo/gradient-cover [quo/gradient-cover
{:customization-color customization-color {:customization-color customization-color

View File

@ -1,31 +1,12 @@
(ns status-im2.contexts.wallet.account.tabs.about.view (ns status-im2.contexts.wallet.account.tabs.about.view
(:require (:require
[quo.core :as quo] [quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.core :as rn] [react-native.core :as rn]
[status-im2.contexts.wallet.account.tabs.about.style :as style] [status-im2.contexts.wallet.account.tabs.about.style :as style]
[status-im2.contexts.wallet.common.temp :as temp] [status-im2.contexts.wallet.common.temp :as temp]
[utils.i18n :as i18n] [utils.i18n :as i18n]
[utils.re-frame :as rf])) [utils.re-frame :as rf]))
(defn description
[{:keys [address theme]}]
(let [networks-list (rf/sub [:wallet/network-details])]
[quo/text {:size :paragraph-2}
(map (fn [{:keys [chain-id short-name network-name]}]
^{:key (str chain-id short-name)}
[quo/text
{:size :paragraph-2
:weight :medium
:style {:color (colors/resolve-color network-name theme)}}
(str short-name ":")])
networks-list)
[quo/text
{:size :paragraph-2
:weight :monospace}
address]]))
(defn about-options (defn about-options
[] []
[quo/action-drawer [quo/action-drawer
@ -51,19 +32,25 @@
:accessibility-label :share-address :accessibility-label :share-address
:label (i18n/label :t/share-address)}]]]) :label (i18n/label :t/share-address)}]]])
(defn- view-internal (defn view
[] []
[rn/view {:style style/about-tab} (let [{:keys [type address]} (rf/sub [:wallet/current-viewing-account])
[quo/data-item networks (rf/sub [:wallet/network-details])
(merge temp/data-item-state watch-only? (= type :watch)]
{:custom-subtitle (fn [] [quo/address-text [rn/view {:style style/about-tab}
{:networks [{:network-name :ethereum :short-name "eth"} [quo/data-item
{:network-name :optimism :short-name "opt"} {:description :default
{:network-name :arbitrum :short-name "arb1"}] :icon-right? true
:address temp/address :right-icon :i/options
:format :long}]) :card? true
:container-style {:margin-bottom 12} :label :none
:on-press #(rf/dispatch [:show-bottom-sheet {:content about-options}])})] :status :default
[quo/account-origin temp/account-origin-state]]) :size :default
:title (if watch-only? (i18n/label :t/watched-address) (i18n/label :t/address))
(def view (quo.theme/with-theme view-internal)) :custom-subtitle (fn [] [quo/address-text
{:networks networks
:address address
:format :long}])
:container-style {:margin-bottom 12}
:on-press #(rf/dispatch [:show-bottom-sheet {:content about-options}])}]
(when (not watch-only?) [quo/account-origin temp/account-origin-state])]))

View File

@ -21,37 +21,41 @@
:padding-bottom 8} :padding-bottom 8}
:render-fn quo/settings-item}]]) :render-fn quo/settings-item}]])
(def tabs-data (def first-tab-id :assets)
[{:id :assets :label (i18n/label :t/assets) :accessibility-label :assets-tab}
{:id :collectibles :label (i18n/label :t/collectibles) :accessibility-label :collectibles-tab} (defn tabs-data
{:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab} [watch-only?]
{:id :dapps :label (i18n/label :t/dapps) :accessibility-label :dapps} (cond-> [{:id :assets :label (i18n/label :t/assets) :accessibility-label :assets-tab}
{:id :about :label (i18n/label :t/about) :accessibility-label :about}]) {:id :collectibles :label (i18n/label :t/collectibles) :accessibility-label :collectibles-tab}
{:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab}]
(not watch-only?) (conj {:id :dapps :label (i18n/label :t/dapps) :accessibility-label :dapps})
true (conj {:id :about :label (i18n/label :t/about) :accessibility-label :about})))
(defn view (defn view
[] []
(let [selected-tab (reagent/atom (:id (first tabs-data)))] (let [selected-tab (reagent/atom first-tab-id)]
(fn [] (fn []
(let [{:keys [name color balance]} (rf/sub [:wallet/current-viewing-account]) (let [{:keys [name color balance type]} (rf/sub [:wallet/current-viewing-account])
] watch-only? (= type :watch)]
[rn/view {:style {:flex 1}} [rn/view {:style {:flex 1}}
[account-switcher/view {:on-press #(rf/dispatch [:wallet/close-account-page])}] [account-switcher/view {:on-press #(rf/dispatch [:wallet/close-account-page])}]
[quo/account-overview [quo/account-overview
{:current-value (utils/prettify-balance balance) {:current-value (utils/prettify-balance balance)
:account-name name :account-name name
:account :default :account (if watch-only? :watched-address :default)
:customization-color color}] :customization-color color}]
[quo/wallet-graph {:time-frame :empty}] [quo/wallet-graph {:time-frame :empty}]
[quo/wallet-ctas (when (not watch-only?)
{:send-action #(rf/dispatch [:open-modal :wallet-select-address]) [quo/wallet-ctas
:buy-action #(rf/dispatch [:show-bottom-sheet {:send-action #(rf/dispatch [:open-modal :wallet-select-address])
{:content buy-drawer}]) :buy-action #(rf/dispatch [:show-bottom-sheet
:bridge-action #(rf/dispatch [:open-modal :wallet-bridge])}] {:content buy-drawer}])
:bridge-action #(rf/dispatch [:open-modal :wallet-bridge])}])
[quo/tabs [quo/tabs
{:style style/tabs {:style style/tabs
:size 32 :size 32
:default-active @selected-tab :default-active @selected-tab
:data tabs-data :data (tabs-data watch-only?)
:on-change #(reset! selected-tab %) :on-change #(reset! selected-tab %)
:scrollable? true :scrollable? true
:scroll-on-press? true}] :scroll-on-press? true}]

View File

@ -0,0 +1,26 @@
(ns status-im2.contexts.wallet.add-address-to-watch.confirm-address.component-spec
(:require
[re-frame.core :as re-frame]
[status-im2.contexts.wallet.add-address-to-watch.confirm-address.view :as confirm-address]
[test-helpers.component :as h]
[utils.re-frame :as rf]))
(defn setup-subs
[subscriptions]
(doseq [keyval subscriptions]
(re-frame/reg-sub
(key keyval)
(fn [_] (val keyval)))))
(h/describe "Add Watch Only Account Page"
(h/test "Create Account button is disabled while no account name exists"
(let [callback (h/mock-fn)]
(with-redefs [rf/dispatch #(callback)]
(setup-subs {:profile/wallet-accounts []
:get-screen-params {:address "0xmock-address"}})
(h/render [confirm-address/view {}])
(h/is-truthy (h/get-by-text "0xmock-address"))
(h/was-not-called callback)
(h/fire-event :change-text (h/get-by-label-text :profile-title-input) "NAME")
(h/fire-event :press (h/get-by-translation-text :t/add-watched-address))
(h/was-called callback)))))

View File

@ -3,7 +3,6 @@
[clojure.string :as string] [clojure.string :as string]
[quo.core :as quo] [quo.core :as quo]
[quo.foundations.colors :as colors] [quo.foundations.colors :as colors]
[re-frame.core :as re-frame]
[react-native.core :as rn] [react-native.core :as rn]
[reagent.core :as reagent] [reagent.core :as reagent]
[status-im2.contexts.emoji-picker.utils :as emoji-picker.utils] [status-im2.contexts.emoji-picker.utils :as emoji-picker.utils]
@ -43,8 +42,14 @@
:bottom-action-label :t/add-watched-address :bottom-action-label :t/add-watched-address
:bottom-action-props {:customization-color @account-color :bottom-action-props {:customization-color @account-color
:disabled? (string/blank? @account-name) :disabled? (string/blank? @account-name)
:on-press #(re-frame/dispatch [:navigate-to :on-press #(rf/dispatch [:wallet/add-account
:wallet-account])}} nil
{:type :watch
:account-name @account-name
:emoji @account-emoji
:color @account-color}
{:address address
:public-key ""}])}}
[quo/data-item [quo/data-item
{:card? true {:card? true
:right-icon :i/advanced :right-icon :i/advanced

View File

@ -6,8 +6,7 @@
:margin-bottom 20}) :margin-bottom 20})
(def scan (def scan
{:align-self {:margin-top 26})
:flex-end})
(def input (def input
{:flex 1 {:flex 1

View File

@ -18,23 +18,32 @@
(rf/reg-event-fx :wallet/show-account-created-toast (rf/reg-event-fx :wallet/show-account-created-toast
(fn [{:keys [db]} [address]] (fn [{:keys [db]} [address]]
(let [{:keys [name]} (get-in db [:wallet :accounts address])] (let [account (get-in db [:wallet :accounts address])]
{:db (update db :wallet dissoc :navigate-to-account :new-account?) {:db (update db :wallet dissoc :navigate-to-account :new-account?)
:fx [[:dispatch :fx [[:dispatch
[:toasts/upsert [:toasts/upsert
{:id :new-wallet-account-created {:id :new-wallet-account-created
:icon :i/correct :icon :i/correct
:icon-color colors/success-50 :icon-color colors/success-50
:text (i18n/label :t/account-created {:name name})}]]]}))) :text (i18n/label :t/account-created {:name (:name account)})}]]]})))
(rf/reg-event-fx :wallet/navigate-to-account (rf/reg-event-fx :wallet/navigate-to-account
(fn [{:keys [db]} [address]] (fn [{:keys [db]} [address]]
(let [new-account? (get-in db [:wallet :new-account?])] {:db (assoc-in db [:wallet :current-viewing-account-address] address)
(cond-> {:db (assoc-in db [:wallet :current-viewing-account-address] address) :fx [[:dispatch [:navigate-to :wallet-accounts address]]]}))
:fx [[:dispatch [:navigate-to :wallet-accounts address]]]}
new-account? (rf/reg-event-fx :wallet/navigate-to-new-account
(update :fx conj [:dispatch [:wallet/show-account-created-toast address]]))))) (fn [{:keys [db]} [address]]
{:db (assoc-in db [:wallet :current-viewing-account-address] address)
:fx [[:dispatch [:hide-bottom-sheet]]
[:dispatch-later
[{:dispatch [:navigate-back]
:ms 100}
{:dispatch [:navigate-back]
:ms 100}
{:dispatch [:navigate-to :wallet-accounts address]
:ms 300}]]
[:dispatch [:wallet/show-account-created-toast address]]]}))
(rf/reg-event-fx :wallet/close-account-page (rf/reg-event-fx :wallet/close-account-page
(fn [{:keys [db]}] (fn [{:keys [db]}]
@ -44,24 +53,17 @@
(rf/reg-event-fx (rf/reg-event-fx
:wallet/get-accounts-success :wallet/get-accounts-success
(fn [{:keys [db]} [accounts]] (fn [{:keys [db]} [accounts]]
(let [wallet-db (get db :wallet) (let [wallet-accounts (filter #(not (:chat %)) accounts)
wallet-db (get db :wallet)
new-account? (:new-account? wallet-db) new-account? (:new-account? wallet-db)
navigate-to-account (:navigate-to-account wallet-db)] navigate-to-account (:navigate-to-account wallet-db)]
(cond-> {:db (reduce (fn [db {:keys [address] :as account}] {:db (reduce (fn [db {:keys [address] :as account}]
(assoc-in db [:wallet :accounts address] account)) (assoc-in db [:wallet :accounts address] account))
db db
(data-store/rpc->accounts accounts)) (data-store/rpc->accounts wallet-accounts))
:fx [[:dispatch [:wallet/get-wallet-token]]]} :fx [[:dispatch [:wallet/get-wallet-token]]
(when new-account?
new-account? [:dispatch [:wallet/navigate-to-new-account navigate-to-account]])]})))
(update :fx
conj
[:dispatch [:hide-bottom-sheet]]
[:dispatch-later
[{:dispatch [:navigate-back]
:ms 100}
{:dispatch [:wallet/navigate-to-account navigate-to-account]
:ms 300}]])))))
(rf/reg-event-fx (rf/reg-event-fx
:wallet/get-accounts :wallet/get-accounts
@ -144,29 +146,35 @@
:on-success on-success :on-success on-success
:on-error #(log/info "failed to derive address " %)}]]]}))) :on-error #(log/info "failed to derive address " %)}]]]})))
(rf/reg-event-fx (rf/reg-event-fx :wallet/add-account-success
:wallet/add-account (fn [{:keys [db]} [address]]
(fn [{:keys [db]} [password {:keys [emoji account-name color]} {:keys [public-key address path]}]] {:db (update db
(let [key-uid (get-in db [:profile/profile :key-uid]) :wallet assoc
sha3-pwd (native-module/sha3 (security/safe-unmask-data password)) :navigate-to-account address
account-config {:key-uid key-uid :new-account? true)
:wallet false :fx [[:dispatch [:wallet/get-accounts]]]}))
:chat false
:type :generated (rf/reg-event-fx :wallet/add-account
:name account-name (fn [{:keys [db]}
:emoji emoji [password {:keys [emoji account-name color type] :or {type :generated}}
:path path {:keys [public-key address path]}]]
:address address (let [lowercase-address (if address (string/lower-case address) address)
:public-key public-key key-uid (get-in db [:profile/profile :key-uid])
:colorID color}] sha3-pwd (native-module/sha3 (security/safe-unmask-data password))
{:db (update db account-config {:key-uid (when (= type :generated) key-uid)
:wallet assoc :wallet false
:navigate-to-account address :chat false
:new-account? true) :type type
:fx [[:json-rpc/call :name account-name
:emoji emoji
:path path
:address lowercase-address
:public-key public-key
:colorID color}]
{:fx [[:json-rpc/call
[{:method "accounts_addAccount" [{:method "accounts_addAccount"
:params [sha3-pwd account-config] :params [(when (= type :generated) sha3-pwd) account-config]
:on-success [:wallet/get-accounts] :on-success [:wallet/add-account-success lowercase-address]
:on-error #(log/info "failed to create account " %)}]]]}))) :on-error #(log/info "failed to create account " %)}]]]})))
(rf/reg-event-fx (rf/reg-event-fx

View File

@ -4,5 +4,6 @@
[status-im2.contexts.chat.messages.content.audio.component-spec] [status-im2.contexts.chat.messages.content.audio.component-spec]
[status-im2.contexts.communities.actions.community-options.component-spec] [status-im2.contexts.communities.actions.community-options.component-spec]
[status-im2.contexts.wallet.add-address-to-watch.component-spec] [status-im2.contexts.wallet.add-address-to-watch.component-spec]
[status-im2.contexts.wallet.add-address-to-watch.confirm-address.component-spec]
[status-im2.contexts.wallet.create-account.edit-derivation-path.component-spec] [status-im2.contexts.wallet.create-account.edit-derivation-path.component-spec]
[status-im2.contexts.wallet.send.input-amount.component-spec])) [status-im2.contexts.wallet.send.input-amount.component-spec]))

View File

@ -48,10 +48,10 @@
:<- [:wallet/balances] :<- [:wallet/balances]
:<- [:wallet/tokens-loading?] :<- [:wallet/tokens-loading?]
(fn [[accounts balances tokens-loading?]] (fn [[accounts balances tokens-loading?]]
(mapv (fn [{:keys [color address] :as account}] (mapv (fn [{:keys [color address type] :as account}]
(assoc account (assoc account
:customization-color color :customization-color color
:type :empty :type (if (= type :watch) :watch-only :empty)
:on-press #(rf/dispatch [:wallet/navigate-to-account address]) :on-press #(rf/dispatch [:wallet/navigate-to-account address])
:loading? tokens-loading? :loading? tokens-loading?
:balance (utils/prettify-balance (get balances address)))) :balance (utils/prettify-balance (get balances address))))