feat(wallet): Add new saved address from wallet settings (#20304)
This commit adds flow for adding new saved addresses from wallet settings Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
This commit is contained in:
parent
00d288fb94
commit
577dc16188
|
@ -44,14 +44,14 @@
|
|||
:monospace? - boolean (default: false) - use monospace font
|
||||
:lowercase? - boolean (default: false) - lowercase text
|
||||
:neutral? - boolean (default: false) - use neutral colors variant"
|
||||
[{:keys [full-name customization-color size monospace? lowercase? neutral?]
|
||||
[{:keys [full-name customization-color size monospace? lowercase? neutral? container-style]
|
||||
:or {size biggest-possible}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
circle-size (:size (size properties))
|
||||
small? (check-if-size-small size)
|
||||
initials (utils.string/get-initials full-name (if small? 1 2))]
|
||||
[rn/view
|
||||
{:style (style/container circle-size customization-color neutral? theme)}
|
||||
{:style (merge (style/container circle-size customization-color neutral? theme) container-style)}
|
||||
[text/text
|
||||
{:accessibility-label :wallet-user-avatar
|
||||
:size (:font-size (size properties))
|
||||
|
|
|
@ -0,0 +1,30 @@
|
|||
(ns status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def header-container
|
||||
{:padding-bottom 8})
|
||||
|
||||
(def input-container
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 20})
|
||||
|
||||
(def input
|
||||
{:flex 1
|
||||
:margin-right 12})
|
||||
|
||||
(def scan-button
|
||||
{:margin-top 26})
|
||||
|
||||
(def info-message
|
||||
{:margin-top 8
|
||||
:margin-left 20})
|
||||
|
||||
(def existing-saved-address-container
|
||||
{:padding-horizontal 20
|
||||
:padding-vertical 12})
|
||||
|
||||
(def existing-saved-address-text
|
||||
{:color colors/white-opa-40})
|
||||
|
||||
(def saved-address-item
|
||||
{:margin-top 4})
|
|
@ -0,0 +1,174 @@
|
|||
(ns status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.clipboard :as clipboard]
|
||||
[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.not-implemented :as not-implemented]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.style :as style]
|
||||
[status-im.contexts.wallet.common.validation :as validation]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- validate-input
|
||||
[account-addresses saved-addresses user-input]
|
||||
(cond
|
||||
(or (nil? user-input) (= user-input ""))
|
||||
nil
|
||||
|
||||
(contains? saved-addresses user-input)
|
||||
:existing-saved-address
|
||||
|
||||
(contains? account-addresses user-input)
|
||||
:own-account
|
||||
|
||||
(not
|
||||
(or (validation/eth-address? user-input)
|
||||
(validation/ens-name? user-input)))
|
||||
:invalid-address-or-ens))
|
||||
|
||||
(defn- address-input
|
||||
[{:keys [input-value on-change-text paste-into-input clear-input]}]
|
||||
(let [empty-input? (string/blank? input-value)]
|
||||
[rn/view {:style style/input-container}
|
||||
[quo/input
|
||||
{:accessibility-label :add-address-to-save
|
||||
:placeholder (i18n/label :t/address-placeholder)
|
||||
:container-style style/input
|
||||
:blur? true
|
||||
:label (i18n/label :t/address-or-ens-name)
|
||||
:auto-capitalize :none
|
||||
:multiline? true
|
||||
:on-clear clear-input
|
||||
:return-key-type :done
|
||||
:clearable? (not empty-input?)
|
||||
:on-change-text on-change-text
|
||||
:button (when empty-input?
|
||||
{:on-press paste-into-input
|
||||
:text (i18n/label :t/paste)})
|
||||
:value input-value}]
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:on-press not-implemented/alert
|
||||
:container-style style/scan-button
|
||||
:background :blur
|
||||
:size 40
|
||||
:icon-only? true}
|
||||
:i/scan]]))
|
||||
|
||||
(defn- error-view
|
||||
[{:keys [error]}]
|
||||
(let [error-msg (condp = error
|
||||
:existing-saved-address
|
||||
(i18n/label :t/this-address-is-already-saved)
|
||||
|
||||
:own-account
|
||||
(i18n/label :t/you-cannot-add-your-own-account-as-a-saved-address)
|
||||
|
||||
:invalid-address-or-ens
|
||||
(i18n/label :t/this-is-not-an-eth-address-or-ens-name)
|
||||
|
||||
:ens-not-registered
|
||||
(i18n/label :t/this-ens-name-is-not-registered-yet)
|
||||
nil)]
|
||||
(when error-msg
|
||||
[quo/info-message
|
||||
{:accessibility-label :error-message
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:type :error
|
||||
:style style/info-message}
|
||||
error-msg])))
|
||||
|
||||
(defn- existing-saved-address
|
||||
[{:keys [address]}]
|
||||
(let [{:keys [name customization-color chain-short-names ens has-ens?]}
|
||||
(rf/sub [:wallet/saved-address-by-address
|
||||
address])]
|
||||
[rn/view {:style style/existing-saved-address-container}
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:weight :medium
|
||||
:style style/existing-saved-address-text}
|
||||
(i18n/label :t/existing-saved-address)]
|
||||
[quo/saved-address
|
||||
{:blur? true
|
||||
:active-state? true
|
||||
:user-props {:name name
|
||||
:address (str chain-short-names address)
|
||||
:ens (when has-ens? ens)
|
||||
:customization-color customization-color
|
||||
:blur? true}
|
||||
:container-style style/saved-address-item}]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-color (rf/sub [:profile/customization-color])
|
||||
accounts-addresses (rf/sub [:wallet/addresses])
|
||||
saved-addresses-addresses (rf/sub [:wallet/saved-addresses-addresses])
|
||||
[input-value set-input-value] (rn/use-state nil)
|
||||
[error set-error] (rn/use-state nil)
|
||||
error? (some? error)
|
||||
validate #(validate-input accounts-addresses
|
||||
saved-addresses-addresses
|
||||
%)
|
||||
clear-input (rn/use-callback
|
||||
(fn []
|
||||
(set-input-value nil)
|
||||
(set-error nil)))
|
||||
on-change-text (rn/use-callback
|
||||
(fn [new-value]
|
||||
(let [lowercase-value (string/lower-case new-value)]
|
||||
(set-error (validate lowercase-value))
|
||||
(set-input-value lowercase-value))))
|
||||
paste-into-input (rn/use-callback #(clipboard/get-string
|
||||
(fn [clipboard-text]
|
||||
(on-change-text clipboard-text))))
|
||||
on-press-continue (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:wallet/set-address-to-save
|
||||
{:address input-value}])
|
||||
(rf/dispatch
|
||||
[:navigate-to-within-stack
|
||||
[:screen/settings.save-address
|
||||
:screen/settings.add-address-to-save]]))
|
||||
[input-value])]
|
||||
(rn/use-unmount #(rf/dispatch [:wallet/clear-address-to-save]))
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:icon-name :i/close
|
||||
:behind-overlay? true
|
||||
:on-press navigate-back
|
||||
:margin-top (safe-area/get-top)
|
||||
:accessibility-label :add-address-to-save-page-nav}]
|
||||
:footer [quo/button
|
||||
{:customization-color profile-color
|
||||
:disabled? (or (string/blank? input-value)
|
||||
error?)
|
||||
:on-press on-press-continue}
|
||||
(i18n/label :t/continue)]}
|
||||
[quo/page-top
|
||||
{:container-style style/header-container
|
||||
:blur? true
|
||||
:title (i18n/label :t/add-address)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/add-address-to-save-description)}]
|
||||
[address-input
|
||||
{:input-value input-value
|
||||
:on-change-text on-change-text
|
||||
:paste-into-input paste-into-input
|
||||
:clear-input clear-input}]
|
||||
(when error?
|
||||
[:<>
|
||||
[error-view {:error error}]
|
||||
(when (= error :existing-saved-address)
|
||||
[existing-saved-address {:address input-value}])])]]))
|
|
@ -1,20 +1,12 @@
|
|||
(ns status-im.contexts.settings.wallet.saved-addresses.events
|
||||
(:require
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.data-store :as data-store]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn save-address
|
||||
[{:keys [db]}
|
||||
[{:keys [address name customization-color on-success on-error chain-short-names ens]
|
||||
:or {on-success (fn [])
|
||||
on-error (fn [])
|
||||
name ""
|
||||
customization-color constants/account-default-customization-color
|
||||
ens ""
|
||||
;; the chain short names should be a string like eth: or eth:arb:oeth:
|
||||
chain-short-names (str constants/mainnet-short-name ":")}}]]
|
||||
[{:keys [address name customization-color on-success on-error chain-short-names ens]}]]
|
||||
(let [test-networks-enabled? (boolean (get-in db [:profile/profile :test-networks-enabled?]))
|
||||
address-to-save {:address address
|
||||
:name name
|
||||
|
@ -93,3 +85,39 @@
|
|||
:on-error [:wallet/delete-saved-address-failed]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address delete-saved-address)
|
||||
|
||||
(defn add-saved-address-success
|
||||
[_ [toast-message]]
|
||||
{:fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:navigate-back-to :screen/settings.saved-addresses]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/add-saved-address-success add-saved-address-success)
|
||||
|
||||
(defn add-saved-address-failed
|
||||
[_ [error]]
|
||||
{:fx [[:dispatch [:wallet/saved-addresses-rpc-error :add-save-address error]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text error}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/add-saved-address-failed add-saved-address-failed)
|
||||
|
||||
(defn set-address-to-save
|
||||
[{:keys [db]} [args]]
|
||||
{:db (assoc-in db [:wallet :ui :saved-address] args)})
|
||||
|
||||
(rf/reg-event-fx :wallet/set-address-to-save set-address-to-save)
|
||||
|
||||
(defn clear-address-to-save
|
||||
[{:keys [db]}]
|
||||
{:db (update-in db [:wallet :ui] dissoc :saved-address)})
|
||||
|
||||
(rf/reg-event-fx :wallet/clear-address-to-save clear-address-to-save)
|
||||
|
|
|
@ -150,3 +150,20 @@
|
|||
:on-success [:wallet/delete-saved-address-success toast-message]
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
(deftest add-saved-address-success-test
|
||||
(testing "add saved address success test - gets saved addresses, dismiss modals and dispatch toast"
|
||||
(let [cofx {:db {}}
|
||||
toast-message "Address saved"
|
||||
effects (events/add-saved-address-success cofx [toast-message])
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:navigate-back-to :screen/settings.saved-addresses]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]]
|
||||
(is (= (count result-fx) 3))
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
(ns status-im.contexts.settings.wallet.saved-addresses.save-address.style)
|
||||
|
||||
(def title-input
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12
|
||||
:padding-bottom 16})
|
||||
|
||||
(def avatar
|
||||
{:margin-horizontal 20
|
||||
:margin-top 12})
|
||||
|
||||
(def color-picker-top-divider
|
||||
{:margin-bottom 12})
|
||||
|
||||
(def section-label
|
||||
{:padding-horizontal 20
|
||||
:padding-bottom 4})
|
||||
|
||||
(def color-picker
|
||||
{:padding-horizontal 20
|
||||
:padding-vertical 12})
|
||||
|
||||
(def color-picker-bottom-divider
|
||||
{:margin-top 8
|
||||
:margin-bottom 12})
|
||||
|
||||
(def data-item
|
||||
{:margin-horizontal 20
|
||||
:padding-vertical 8
|
||||
:margin-top 8
|
||||
:margin-bottom 12})
|
|
@ -0,0 +1,113 @@
|
|||
(ns status-im.contexts.settings.wallet.saved-addresses.save-address.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[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.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.save-address.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- extract-address
|
||||
[address]
|
||||
(re-find constants/regx-address-contains address))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [address]} (rf/sub [:wallet/saved-address])
|
||||
[address-label set-address-label] (rn/use-state "")
|
||||
[address-color set-address-color] (rn/use-state (rand-nth colors/account-colors))
|
||||
placeholder (i18n/label :t/address-name)
|
||||
on-press-save (rn/use-callback
|
||||
(fn []
|
||||
(let [address-without-prefix (extract-address address)]
|
||||
(rf/dispatch [:wallet/save-address
|
||||
{:on-success
|
||||
[:wallet/add-saved-address-success
|
||||
(i18n/label :t/address-saved)]
|
||||
:on-error
|
||||
[:wallet/add-saved-address-failed]
|
||||
:name address-label
|
||||
:address address-without-prefix
|
||||
:customization-color address-color}])))
|
||||
[address address-label address-color])]
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back
|
||||
:margin-top (safe-area/get-top)
|
||||
:accessibility-label :save-address-page-nav}]
|
||||
:footer [quo/button
|
||||
{:accessibility-label :save-address-button
|
||||
:type :primary
|
||||
:customization-color address-color
|
||||
:disabled? (string/blank? address-label)
|
||||
:on-press on-press-save}
|
||||
(i18n/label :t/save-address)]
|
||||
:customization-color address-color
|
||||
:gradient-cover? true}
|
||||
[quo/wallet-user-avatar
|
||||
{:full-name (if (string/blank? address-label)
|
||||
placeholder
|
||||
address-label)
|
||||
:customization-color address-color
|
||||
:blur? true
|
||||
:size :size-80
|
||||
:container-style style/avatar}]
|
||||
[quo/title-input
|
||||
{:blur? true
|
||||
:auto-focus true
|
||||
:max-length 24
|
||||
:size :heading-1
|
||||
:placeholder placeholder
|
||||
:default-value address-label
|
||||
:on-change-text set-address-label
|
||||
:customization-color address-color
|
||||
:container-style style/title-input}]
|
||||
[quo/divider-line
|
||||
{:blur? true
|
||||
:container-style style/color-picker-top-divider}]
|
||||
[quo/section-label
|
||||
{:section (i18n/label :t/colour)
|
||||
:blur? true
|
||||
:container-style style/section-label}]
|
||||
[quo/color-picker
|
||||
{:default-selected address-color
|
||||
:on-change set-address-color
|
||||
:blur? true
|
||||
:container-style style/color-picker}]
|
||||
[quo/divider-line
|
||||
{:blur? true
|
||||
:container-style style/color-picker-bottom-divider}]
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:size :default
|
||||
:subtitle-type :default
|
||||
:label :none
|
||||
:blur? true
|
||||
:icon-right? true
|
||||
:right-icon :i/advanced
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (rn/use-callback
|
||||
(fn []
|
||||
[quo/address-text
|
||||
{:full-address? true
|
||||
:address address
|
||||
:format :long}])
|
||||
[address])
|
||||
:on-press not-implemented/alert
|
||||
:container-style style/data-item}]]]))
|
|
@ -36,7 +36,8 @@
|
|||
:customization-color customization-color}])}])
|
||||
[address chain-short-names full-address name customization-color])]
|
||||
[quo/saved-address
|
||||
{:user-props {:name name
|
||||
{:blur? true
|
||||
:user-props {:name name
|
||||
:address full-address
|
||||
:ens (when has-ens? ens)
|
||||
:customization-color customization-color
|
||||
|
@ -59,6 +60,11 @@
|
|||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- add-address-to-save
|
||||
[]
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/settings.add-address-to-save :screen/settings.saved-addresses]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [inset-top (safe-area/get-top)
|
||||
|
@ -77,6 +83,7 @@
|
|||
{:title (i18n/label :t/saved-addresses)
|
||||
:accessibility-label :saved-addresses-header
|
||||
:right :action
|
||||
:on-press add-address-to-save
|
||||
:customization-color customization-color
|
||||
:icon :i/add}]]
|
||||
[rn/section-list
|
||||
|
|
|
@ -150,7 +150,7 @@
|
|||
(i18n/label :t/continue)]}
|
||||
[quo/page-top
|
||||
{:container-style style/header-container
|
||||
:title (i18n/label :t/add-address)
|
||||
:title (i18n/label :t/add-address-to-watch)
|
||||
:description :text
|
||||
:description-text (i18n/label :t/enter-eth)}]
|
||||
[:f> address-input
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.create-account])}
|
||||
{:icon :i/reveal
|
||||
:accessibility-label :add-a-contact
|
||||
:label (i18n/label :t/add-address)
|
||||
:sub-label (i18n/label :t/add-address-description)
|
||||
:label (i18n/label :t/add-address-to-watch)
|
||||
:sub-label (i18n/label :t/add-address-to-watch-description)
|
||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.add-address-to-watch])
|
||||
:add-divider? true}]]])
|
||||
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
(ns status-im.contexts.wallet.save-address.style)
|
||||
|
||||
(def title-input-container
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12
|
||||
:padding-bottom 16})
|
||||
|
||||
(def account-avatar-container
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12})
|
||||
|
||||
(def color-picker-top-divider
|
||||
{:margin-bottom 12})
|
||||
|
||||
(def color-picker-container
|
||||
{:padding-vertical 12})
|
||||
|
||||
(def section-container
|
||||
{:padding-horizontal 20
|
||||
:padding-bottom 4})
|
||||
|
||||
(def color-picker
|
||||
{:padding-horizontal 20
|
||||
:padding-top 12})
|
||||
|
||||
(def color-picker-bottom-divider
|
||||
{:padding-top 8
|
||||
:padding-bottom 12})
|
||||
|
||||
(def save-address-button
|
||||
{:padding-horizontal 20})
|
||||
|
||||
(def data-item
|
||||
{:margin-horizontal 20
|
||||
:padding-vertical 8})
|
||||
|
||||
(def address-container
|
||||
{:padding-top 8
|
||||
:padding-bottom 12})
|
|
@ -1,90 +0,0 @@
|
|||
(ns status-im.contexts.wallet.save-address.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.contexts.wallet.save-address.style :as style]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view
|
||||
:as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- address-view
|
||||
[]
|
||||
(let [network-details (rf/sub [:wallet/network-preference-details])
|
||||
address (rf/sub [:wallet/wallet-send-to-address])]
|
||||
[rn/view {:style style/address-container}
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:size :default
|
||||
:subtitle-type :default
|
||||
:label :none
|
||||
:blur? false
|
||||
:icon-right? true
|
||||
:right-icon :i/advanced
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (rn/use-callback
|
||||
(fn [] [quo/address-text
|
||||
{:networks network-details
|
||||
:address address
|
||||
:format :long}]))
|
||||
:on-press (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[network-preferences/view
|
||||
{:on-save (fn [])}])}])))
|
||||
:container-style style/data-item}]]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [[address-label set-address-label] (rn/use-state "")
|
||||
[address-color set-address-color] (rn/use-state :blue)
|
||||
placeholder (i18n/label :t/address-name)]
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/close
|
||||
:on-press (rn/use-callback #(rf/dispatch [:navigate-back]))
|
||||
:accessibility-label :save-address-top-bar}]
|
||||
:footer [quo/button
|
||||
{:accessibility-label :save-address-button
|
||||
:type :primary
|
||||
:container-style style/save-address-button}
|
||||
(i18n/label :t/save-address)]
|
||||
:customization-color address-color
|
||||
:gradient-cover? true}
|
||||
[rn/view
|
||||
{:style style/account-avatar-container}
|
||||
[quo/user-avatar
|
||||
{:full-name (if (string/blank? address-label)
|
||||
placeholder
|
||||
address-label)
|
||||
:customization-color address-color
|
||||
:size :big}]]
|
||||
[quo/title-input
|
||||
{:blur? true
|
||||
:auto-focus true
|
||||
:max-length 24
|
||||
:size :heading-1
|
||||
:placeholder placeholder
|
||||
:default-value address-label
|
||||
:on-change-text set-address-label
|
||||
:customization-color address-color
|
||||
:container-style style/title-input-container}]
|
||||
[quo/divider-line {:container-style style/color-picker-top-divider}]
|
||||
[quo/section-label
|
||||
{:section (i18n/label :t/colour)
|
||||
:container-style style/section-container}]
|
||||
[quo/color-picker
|
||||
{:default-selected address-color
|
||||
:on-change set-address-color
|
||||
:container-style style/color-picker}]
|
||||
[quo/divider-line {:container-style style/color-picker-bottom-divider}]
|
||||
[address-view]]))
|
|
@ -36,7 +36,9 @@
|
|||
:icon-left :i/contact-book
|
||||
:accessibility-label :save-address
|
||||
:on-press (rn/use-callback
|
||||
#(rf/dispatch [:open-modal :screen/wallet.save-address]))}
|
||||
#(rf/dispatch [:open-modal
|
||||
:screen/settings.save-address
|
||||
{:address send-to-address}]))}
|
||||
:button-one-label (i18n/label :t/done)
|
||||
:button-one-props {:customization-color color
|
||||
:type :primary
|
||||
|
|
|
@ -63,6 +63,9 @@
|
|||
[status-im.contexts.settings.wallet.keypairs-and-accounts.scan-qr.view :as scan-keypair-qr]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
|
||||
[status-im.contexts.settings.wallet.network-settings.view :as network-settings]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.view :as
|
||||
wallet-add-address-to-save]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.save-address.view :as wallet-save-address]
|
||||
[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]
|
||||
|
@ -98,7 +101,6 @@
|
|||
[status-im.contexts.wallet.collectible.view :as wallet-collectible]
|
||||
[status-im.contexts.wallet.common.scan-account.view :as wallet-scan-address]
|
||||
[status-im.contexts.wallet.connected-dapps.view :as wallet-connected-dapps]
|
||||
[status-im.contexts.wallet.save-address.view :as wallet-save-address]
|
||||
[status-im.contexts.wallet.send.from.view :as wallet-select-from]
|
||||
[status-im.contexts.wallet.send.select-address.view :as wallet-select-address]
|
||||
[status-im.contexts.wallet.send.select-asset.view :as wallet-select-asset]
|
||||
|
@ -450,10 +452,6 @@
|
|||
:options options/transparent-screen-options
|
||||
:component wallet-share-address/view}
|
||||
|
||||
{:name :screen/wallet.save-address
|
||||
:options {:sheet? true}
|
||||
:component wallet-save-address/view}
|
||||
|
||||
{:name :screen/wallet.send-input-amount
|
||||
:options {:modalPresentationStyle :overCurrentContext
|
||||
:insets {:top? true
|
||||
|
@ -540,6 +538,14 @@
|
|||
:options options/transparent-modal-screen-options
|
||||
:component network-settings/view}
|
||||
|
||||
{:name :screen/settings.save-address
|
||||
:options options/transparent-modal-screen-options
|
||||
:component wallet-save-address/view}
|
||||
|
||||
{:name :screen/settings.add-address-to-save
|
||||
:options options/transparent-modal-screen-options
|
||||
:component wallet-add-address-to-save/view}
|
||||
|
||||
{:name :screen/settings-messages
|
||||
:options options/transparent-modal-screen-options
|
||||
:component settings.messages/view}
|
||||
|
|
|
@ -3,32 +3,49 @@
|
|||
[clojure.string :as string]
|
||||
[re-frame.core :as rf]))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/saved-address
|
||||
:<- [:wallet/ui]
|
||||
:-> :saved-address)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/saved-addresses
|
||||
:<- [:wallet]
|
||||
:-> :saved-addresses)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/address-saved?
|
||||
:<- [:wallet]
|
||||
(fn [wallet [address]]
|
||||
(some #(= address (:address %))
|
||||
(:saved-addresses wallet))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/saved-addresses-by-network-mode
|
||||
:<- [:wallet/saved-addresses]
|
||||
:<- [:profile/test-networks-enabled?]
|
||||
(fn [[saved-addresses test-networks-enabled?]]
|
||||
(vals (get saved-addresses (if test-networks-enabled? :test :prod)))))
|
||||
(get saved-addresses (if test-networks-enabled? :test :prod))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/address-saved?
|
||||
:<- [:wallet/saved-addresses-by-network-mode]
|
||||
(fn [saved-addresses [_ address]]
|
||||
(contains? saved-addresses address)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/grouped-saved-addresses
|
||||
:<- [:wallet/saved-addresses-by-network-mode]
|
||||
(fn [saved-addresses]
|
||||
(->> saved-addresses
|
||||
vals
|
||||
(sort-by :name)
|
||||
(group-by #(string/upper-case (first (:name %))))
|
||||
(map (fn [[k v]]
|
||||
{:title k
|
||||
:data v})))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/saved-addresses-addresses
|
||||
:<- [:wallet/saved-addresses-by-network-mode]
|
||||
(fn [saved-addresses]
|
||||
(-> saved-addresses keys set)))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/saved-address-by-address
|
||||
:<- [:wallet/saved-addresses-by-network-mode]
|
||||
(fn [saved-addresses [_ address]]
|
||||
(get saved-addresses address)))
|
||||
|
|
|
@ -91,7 +91,17 @@
|
|||
#(-> %
|
||||
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
|
||||
(assoc-in [:profile/profile :test-networks-enabled?] true)))
|
||||
(is (= (vals (:test saved-addresses-db)) (rf/sub [sub-name])))))
|
||||
(is (= (:test saved-addresses-db) (rf/sub [sub-name])))))
|
||||
|
||||
(h/deftest-sub :wallet/address-saved?
|
||||
[sub-name]
|
||||
(testing "returns boolean if given address is saved"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
|
||||
(assoc-in [:profile/profile :test-networks-enabled?] false)))
|
||||
(is (true? (rf/sub [sub-name "0x1"])))
|
||||
(is (false? (rf/sub [sub-name "0x3"])))))
|
||||
|
||||
(h/deftest-sub :wallet/grouped-saved-addresses
|
||||
[sub-name]
|
||||
|
@ -101,3 +111,22 @@
|
|||
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
|
||||
(assoc-in [:profile/profile :test-networks-enabled?] false)))
|
||||
(is (= grouped-saved-addresses-data (rf/sub [sub-name])))))
|
||||
|
||||
(h/deftest-sub :wallet/saved-addresses-addresses
|
||||
[sub-name]
|
||||
(testing "returns saved addresses addresses set"
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
|
||||
(assoc-in [:profile/profile :test-networks-enabled?] true)))
|
||||
(is (= (-> saved-addresses-db :test keys set) (rf/sub [sub-name])))))
|
||||
|
||||
(h/deftest-sub :wallet/saved-address-by-address
|
||||
[sub-name]
|
||||
(testing "returns a saved address"
|
||||
(let [address "0x1"]
|
||||
(swap! rf-db/app-db
|
||||
#(-> %
|
||||
(assoc-in [:wallet :saved-addresses] saved-addresses-db)
|
||||
(assoc-in [:profile/profile :test-networks-enabled?] false)))
|
||||
(is (= (get-in saved-addresses-db [:prod address]) (rf/sub [sub-name address]))))))
|
||||
|
|
|
@ -2423,8 +2423,8 @@
|
|||
"days": "Days",
|
||||
"add-account": "Add account",
|
||||
"add-account-description": "Create new or import existing account",
|
||||
"add-address": "Add address to watch",
|
||||
"add-address-description": "Watch a public address or ENS name",
|
||||
"add-address-to-watch": "Add address to watch",
|
||||
"add-address-to-watch-description": "Watch a public address or ENS name",
|
||||
"colour": "Colour",
|
||||
"origin": "Origin",
|
||||
"slide-to-sign": "Slide to sign",
|
||||
|
@ -2673,5 +2673,13 @@
|
|||
"saved-address-removed": "Saved address removed",
|
||||
"remove-address": "Remove address",
|
||||
"remove-saved-address": "Remove saved address",
|
||||
"remove-saved-address-description": "Transaction history relating to this address will no longer be labelled ‘{{name}}’."
|
||||
"remove-saved-address-description": "Transaction history relating to this address will no longer be labelled ‘{{name}}’.",
|
||||
"add-address": "Add address",
|
||||
"add-address-to-save-description": "Paste, scan or type ETH address or ENS name",
|
||||
"existing-saved-address": "Existing saved address",
|
||||
"this-is-not-an-eth-address-or-ens-name": "This is not an Ethereum address or ENS name",
|
||||
"you-cannot-add-your-own-account-as-a-saved-address": "You cannot add your own account as a saved address",
|
||||
"this-address-is-already-saved": "This address is already saved",
|
||||
"this-ens-name-is-not-registered-yet": "This ENS name is not registered yet",
|
||||
"address-saved": "Address saved"
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue