Wallet: token input conversion (#18539)

Wallet: token input conversion
This commit is contained in:
Omar Basem 2024-01-20 10:23:19 +04:00 committed by GitHub
parent a9ec2ca7ba
commit 826ab6625e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 61 additions and 28 deletions

View File

@ -13,12 +13,22 @@
[react-native.core :as rn] [react-native.core :as rn]
[reagent.core :as reagent])) [reagent.core :as reagent]))
(defn fiat-format
[currency num-value conversion]
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2)))
(defn crypto-format
[num-value conversion crypto-decimals token]
(str (.toFixed (/ num-value conversion) (or crypto-decimals 2))
" "
(string/upper-case (or (clj->js token) ""))))
(defn calc-value (defn calc-value
[crypto? currency token value conversion] [{:keys [crypto? currency token value conversion crypto-decimals]}]
(let [num-value (if (string? value) (parse-double (or value "0")) value)] (let [num-value (if (string? value) (parse-double (or value "0")) value)]
(if crypto? (if crypto?
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2)) (fiat-format currency num-value conversion)
(str (.toFixed (/ num-value conversion) 2) " " (string/upper-case (or (clj->js token) "")))))) (crypto-format num-value conversion crypto-decimals token))))
(defn- view-internal (defn- view-internal
[{external-value :value}] [{external-value :value}]
@ -27,7 +37,8 @@
crypto? (reagent/atom true) crypto? (reagent/atom true)
input-ref (atom nil) input-ref (atom nil)
controlled-input? (some? external-value)] controlled-input? (some? external-value)]
(fn [{:keys [theme token currency conversion networks title customization-color (fn [{:keys [theme token currency crypto-decimals conversion networks title
customization-color
on-change-text on-swap container-style show-keyboard?] on-change-text on-swap container-style show-keyboard?]
:or {show-keyboard? true} :or {show-keyboard? true}
external-value :value}] external-value :value}]
@ -86,6 +97,11 @@
{:size :paragraph-2 {:size :paragraph-2
:weight :medium :weight :medium
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}} :style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
(calc-value @crypto? currency token (or external-value @value) conversion)]]]))) (calc-value {:crypto? @crypto?
:currency currency
:token token
:value (or external-value @value)
:conversion conversion
:crypto-decimals crypto-decimals})]]])))
(def view (quo.theme/with-theme view-internal)) (def view (quo.theme/with-theme view-internal))

View File

@ -65,6 +65,12 @@
"") "")
"")))) ""))))
(defn get-crypto-decimals-count
[{:keys [market-values-per-currency]}]
(let [price (get-in market-values-per-currency [:usd :price])
one-cent-value (if (pos? price) (/ 0.01 price) 0)]
(calc-max-crypto-decimals one-cent-value)))
(defn get-standard-crypto-format (defn get-standard-crypto-format
"For full details: https://github.com/status-im/status-mobile/issues/18225" "For full details: https://github.com/status-im/status-mobile/issues/18225"
[{:keys [market-values-per-currency]} token-units] [{:keys [market-values-per-currency]} token-units]

View File

@ -67,7 +67,9 @@
(rf/reg-event-fx :wallet/send-select-token (rf/reg-event-fx :wallet/send-select-token
(fn [{:keys [db]} [{:keys [token stack-id]}]] (fn [{:keys [db]} [{:keys [token stack-id]}]]
{:db (assoc-in db [:wallet :ui :send :token] token) {:db (assoc-in db [:wallet :ui :send :token] token)
:fx [[:navigate-to-within-stack [:wallet-send-input-amount stack-id]]]})) :fx [[:dispatch-later
{:ms 1
:dispatch [:navigate-to-within-stack [:wallet-send-input-amount stack-id]]}]]}))
(rf/reg-event-fx :wallet/send-select-token-drawer (rf/reg-event-fx :wallet/send-select-token-drawer
(fn [{:keys [db]} [{:keys [token]}]] (fn [{:keys [db]} [{:keys [token]}]]

View File

@ -39,7 +39,9 @@
:mixedcase-address "0x7bcDfc75c431" :mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064" :public-key "0x04371e2d9d66b82f056bc128064"
:removed false} :removed false}
:wallet/wallet-send-token {:symbol :eth} :wallet/wallet-send-token {:symbol :eth
:total-balance 100
:market-values-per-currency {:usd {:price 10}}}
:wallet/wallet-send-loading-suggested-routes? false :wallet/wallet-send-loading-suggested-routes? false
:wallet/wallet-send-route {:route []} :wallet/wallet-send-route {:route []}
:wallet/wallet-send-suggested-routes {:candidates []}}) :wallet/wallet-send-suggested-routes {:candidates []}})
@ -49,7 +51,9 @@
(h/test "Default render" (h/test "Default render"
(h/setup-subs sub-mocks) (h/setup-subs sub-mocks)
(h/render [input-amount/view {}]) (h/render [input-amount/view
{:crypto-decimals 2
:limit-crypto 250}])
(h/is-truthy (h/get-by-text "0")) (h/is-truthy (h/get-by-text "0"))
(h/is-truthy (h/get-by-text "ETH")) (h/is-truthy (h/get-by-text "ETH"))
(h/is-truthy (h/get-by-text "$0.00")) (h/is-truthy (h/get-by-text "$0.00"))
@ -59,9 +63,9 @@
(h/setup-subs sub-mocks) (h/setup-subs sub-mocks)
(let [on-confirm (h/mock-fn)] (let [on-confirm (h/mock-fn)]
(h/render [input-amount/view (h/render [input-amount/view
{:on-confirm on-confirm {:on-confirm on-confirm
:rate 10 :crypto-decimals 10
:limit 1000}]) :limit-crypto 1000}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-1)) (h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2)) (h/fire-event :press (h/query-by-label-text :keyboard-key-2))
@ -81,9 +85,9 @@
(let [on-confirm (h/mock-fn)] (let [on-confirm (h/mock-fn)]
(h/render [input-amount/view (h/render [input-amount/view
{:rate 10 {:crypto-decimals 10
:limit 1000 :limit-crypto 1000
:on-confirm on-confirm}]) :on-confirm on-confirm}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-1)) (h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key-2)) (h/fire-event :press (h/query-by-label-text :keyboard-key-2))
@ -101,8 +105,8 @@
(h/test "Try to fill more than limit" (h/test "Try to fill more than limit"
(h/setup-subs sub-mocks) (h/setup-subs sub-mocks)
(h/render [input-amount/view (h/render [input-amount/view
{:rate 10 {:crypto-decimals 10
:limit 286}]) :limit-crypto 286}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-2)) (h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-9)) (h/fire-event :press (h/query-by-label-text :keyboard-key-9))
@ -118,9 +122,9 @@
(h/test "Try to fill more than limit" (h/test "Try to fill more than limit"
(h/setup-subs sub-mocks) (h/setup-subs sub-mocks)
(h/render [input-amount/view (h/render [input-amount/view
{:rate 10 {:crypto-decimals 10
:limit 286 :limit-crypto 286
:on-confirm #()}]) :on-confirm #()}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-2)) (h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-9)) (h/fire-event :press (h/query-by-label-text :keyboard-key-9))
@ -136,9 +140,9 @@
(h/test "Switch from crypto to fiat and check limit" (h/test "Switch from crypto to fiat and check limit"
(h/setup-subs sub-mocks) (h/setup-subs sub-mocks)
(h/render [input-amount/view (h/render [input-amount/view
{:rate 10 {:crypto-decimals 2
:limit 250 :limit-crypto 250
:on-confirm #()}]) :on-confirm #()}])
(h/fire-event :press (h/query-by-label-text :keyboard-key-2)) (h/fire-event :press (h/query-by-label-text :keyboard-key-2))
(h/fire-event :press (h/query-by-label-text :keyboard-key-0)) (h/fire-event :press (h/query-by-label-text :keyboard-key-0))
@ -149,7 +153,7 @@
(.then (fn [] (.then (fn []
(h/fire-event :press (h/query-by-label-text :keyboard-key-5)) (h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/fire-event :press (h/query-by-label-text :keyboard-key-5)) (h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/get-by-text "205.50 ETH")))) (h/wait-for #(h/get-by-text "20.50 ETH"))))
(.then (fn [] (.then (fn []
(h/fire-event :press (h/query-by-label-text :keyboard-key-5)) (h/fire-event :press (h/query-by-label-text :keyboard-key-5))
(h/wait-for #(h/get-by-text "205.50 ETH"))))))) (h/wait-for #(h/get-by-text "20.50 ETH")))))))

View File

@ -7,6 +7,7 @@
[react-native.safe-area :as safe-area] [react-native.safe-area :as safe-area]
[reagent.core :as reagent] [reagent.core :as reagent]
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher] [status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.send.input-amount.style :as style] [status-im.contexts.wallet.send.input-amount.style :as style]
[status-im.contexts.wallet.send.routes.view :as routes] [status-im.contexts.wallet.send.routes.view :as routes]
[utils.debounce :as debounce] [utils.debounce :as debounce]
@ -61,15 +62,18 @@
(map first))) (map first)))
(defn- f-view-internal (defn- f-view-internal
[{:keys [rate limit]}] ;; crypto-decimals and limit-crypto args are needed for component tests only
[{:keys [crypto-decimals limit-crypto]}]
(let [bottom (safe-area/get-bottom) (let [bottom (safe-area/get-bottom)
{:keys [currency]} (rf/sub [:profile/profile]) {:keys [currency]} (rf/sub [:profile/profile])
token (rf/sub [:wallet/wallet-send-token]) token (rf/sub [:wallet/wallet-send-token])
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?]) loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
token-symbol (:symbol token) token-symbol (:symbol token)
limit-crypto (or (:total-balance token) limit) limit-crypto (or limit-crypto
conversion-rate (or rate 10) (utils/get-standard-crypto-format token (:total-balance token)))
limit-fiat (* limit-crypto conversion-rate) conversion-rate (get-in token [:market-values-per-currency :usd :price])
limit-fiat (.toFixed (* (:total-balance token) conversion-rate) 2)
crypto-decimals (or crypto-decimals (utils/get-crypto-decimals-count token))
input-value (reagent/atom "") input-value (reagent/atom "")
current-limit (reagent/atom {:amount limit-crypto current-limit (reagent/atom {:amount limit-crypto
:currency token-symbol}) :currency token-symbol})
@ -140,6 +144,7 @@
{:container-style style/input-container {:container-style style/input-container
:token token-symbol :token token-symbol
:currency currency :currency currency
:crypto-decimals crypto-decimals
:networks (:networks token) :networks (:networks token)
:title (i18n/label :t/send-limit {:limit limit-label}) :title (i18n/label :t/send-limit {:limit limit-label})
:conversion conversion-rate :conversion conversion-rate