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]
[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
[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)]
(if crypto?
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2))
(str (.toFixed (/ num-value conversion) 2) " " (string/upper-case (or (clj->js token) ""))))))
(fiat-format currency num-value conversion)
(crypto-format num-value conversion crypto-decimals token))))
(defn- view-internal
[{external-value :value}]
@ -27,7 +37,8 @@
crypto? (reagent/atom true)
input-ref (atom nil)
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?]
:or {show-keyboard? true}
external-value :value}]
@ -86,6 +97,11 @@
{:size :paragraph-2
:weight :medium
: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))

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
"For full details: https://github.com/status-im/status-mobile/issues/18225"
[{:keys [market-values-per-currency]} token-units]

View File

@ -67,7 +67,9 @@
(rf/reg-event-fx :wallet/send-select-token
(fn [{:keys [db]} [{:keys [token stack-id]}]]
{: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
(fn [{:keys [db]} [{:keys [token]}]]

View File

@ -39,7 +39,9 @@
:mixedcase-address "0x7bcDfc75c431"
:public-key "0x04371e2d9d66b82f056bc128064"
: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-route {:route []}
:wallet/wallet-send-suggested-routes {:candidates []}})
@ -49,7 +51,9 @@
(h/test "Default render"
(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 "ETH"))
(h/is-truthy (h/get-by-text "$0.00"))
@ -59,9 +63,9 @@
(h/setup-subs sub-mocks)
(let [on-confirm (h/mock-fn)]
(h/render [input-amount/view
{:on-confirm on-confirm
:rate 10
:limit 1000}])
{:on-confirm on-confirm
:crypto-decimals 10
: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-2))
@ -81,9 +85,9 @@
(let [on-confirm (h/mock-fn)]
(h/render [input-amount/view
{:rate 10
:limit 1000
:on-confirm on-confirm}])
{:crypto-decimals 10
:limit-crypto 1000
: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-2))
@ -101,8 +105,8 @@
(h/test "Try to fill more than limit"
(h/setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 286}])
{:crypto-decimals 10
: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-9))
@ -118,9 +122,9 @@
(h/test "Try to fill more than limit"
(h/setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 286
:on-confirm #()}])
{:crypto-decimals 10
:limit-crypto 286
: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-9))
@ -136,9 +140,9 @@
(h/test "Switch from crypto to fiat and check limit"
(h/setup-subs sub-mocks)
(h/render [input-amount/view
{:rate 10
:limit 250
:on-confirm #()}])
{:crypto-decimals 2
:limit-crypto 250
: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-0))
@ -149,7 +153,7 @@
(.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"))))
(.then (fn []
(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]
[reagent.core :as reagent]
[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.routes.view :as routes]
[utils.debounce :as debounce]
@ -61,15 +62,18 @@
(map first)))
(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)
{:keys [currency]} (rf/sub [:profile/profile])
token (rf/sub [:wallet/wallet-send-token])
loading-suggested-routes? (rf/sub [:wallet/wallet-send-loading-suggested-routes?])
token-symbol (:symbol token)
limit-crypto (or (:total-balance token) limit)
conversion-rate (or rate 10)
limit-fiat (* limit-crypto conversion-rate)
limit-crypto (or limit-crypto
(utils/get-standard-crypto-format token (:total-balance token)))
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 "")
current-limit (reagent/atom {:amount limit-crypto
:currency token-symbol})
@ -140,6 +144,7 @@
{:container-style style/input-container
:token token-symbol
:currency currency
:crypto-decimals crypto-decimals
:networks (:networks token)
:title (i18n/label :t/send-limit {:limit limit-label})
:conversion conversion-rate