From 826ab6625ebd04bed488563a0880a904c1951b84 Mon Sep 17 00:00:00 2001 From: Omar Basem Date: Sat, 20 Jan 2024 10:23:19 +0400 Subject: [PATCH] Wallet: token input conversion (#18539) Wallet: token input conversion --- .../components/wallet/token_input/view.cljs | 26 +++++++++--- .../contexts/wallet/common/utils.cljs | 6 +++ .../contexts/wallet/send/events.cljs | 4 +- .../send/input_amount/component_spec.cljs | 40 ++++++++++--------- .../wallet/send/input_amount/view.cljs | 13 ++++-- 5 files changed, 61 insertions(+), 28 deletions(-) diff --git a/src/quo/components/wallet/token_input/view.cljs b/src/quo/components/wallet/token_input/view.cljs index 82b151e4c4..753de36ccf 100644 --- a/src/quo/components/wallet/token_input/view.cljs +++ b/src/quo/components/wallet/token_input/view.cljs @@ -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)) diff --git a/src/status_im/contexts/wallet/common/utils.cljs b/src/status_im/contexts/wallet/common/utils.cljs index b205f4f95d..f01333a65e 100644 --- a/src/status_im/contexts/wallet/common/utils.cljs +++ b/src/status_im/contexts/wallet/common/utils.cljs @@ -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] diff --git a/src/status_im/contexts/wallet/send/events.cljs b/src/status_im/contexts/wallet/send/events.cljs index 6ba7c9789e..7f99888a54 100644 --- a/src/status_im/contexts/wallet/send/events.cljs +++ b/src/status_im/contexts/wallet/send/events.cljs @@ -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]}]] diff --git a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs index 867cbaa089..54eb8902d3 100644 --- a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs @@ -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"))))))) diff --git a/src/status_im/contexts/wallet/send/input_amount/view.cljs b/src/status_im/contexts/wallet/send/input_amount/view.cljs index 5ee3895f91..3032bcb77c 100644 --- a/src/status_im/contexts/wallet/send/input_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/view.cljs @@ -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