From 01a8258a5f3b99e3948404a58ec3ea0b341d30a5 Mon Sep 17 00:00:00 2001 From: Jamie Caprani Date: Mon, 20 May 2024 22:24:16 +0100 Subject: [PATCH] chore: fix --- .../send/input_amount/component_spec.cljs | 2 +- .../wallet/send/input_amount/view.cljs | 568 +++++++++--------- 2 files changed, 286 insertions(+), 284 deletions(-) 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 a61307390e66..7805277d763a 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 @@ -18,7 +18,7 @@ :network-name :mainnet :chain-id 1 :related-chain-id 5}] - :wallet/current-viewing-account-address "0x1" + :wallet/current-viewing-account-address "0x1" :wallet/current-viewing-account {:path "m/44'/60'/0'/0/1" :emoji "💎" :key-uid "0x2f5ea39" 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 ff4629527b66..79b374ea62c6 100644 --- a/src/status_im/contexts/wallet/send/input_amount/view.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/view.cljs @@ -1,24 +1,24 @@ (ns status-im.contexts.wallet.send.input-amount.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.controlled-input.utils :as controlled-input] - [status-im.contexts.wallet.common.account-switcher.view :as account-switcher] - [status-im.contexts.wallet.common.asset-list.view :as asset-list] - [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] - [status-im.contexts.wallet.send.utils :as send-utils] - [status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert] - [utils.debounce :as debounce] - [utils.i18n :as i18n] - [utils.money :as money] - [utils.number :as number] - [utils.re-frame :as rf])) + [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.controlled-input.utils :as controlled-input] + [status-im.contexts.wallet.common.account-switcher.view :as account-switcher] + [status-im.contexts.wallet.common.asset-list.view :as asset-list] + [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] + [status-im.contexts.wallet.send.utils :as send-utils] + [status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert] + [utils.debounce :as debounce] + [utils.i18n :as i18n] + [utils.money :as money] + [utils.number :as number] + [utils.re-frame :as rf])) (defn- make-limit-label-crypto [amount currency] @@ -128,267 +128,269 @@ initial-crypto-currency? :initial-crypto-currency? :or {initial-crypto-currency? true}}] (let [_ (rn/dismiss-keyboard!) - bottom (safe-area/get-bottom) - [crypto-currency? set-crypto-currency] (rn/use-state initial-crypto-currency?) - on-navigate-back on-navigate-back] - (fn [] - (let [[input-state set-input-state] (rn/use-state controlled-input/init-state) - [just-toggled-mode? set-just-toggled-mode?] (rn/use-state false) - clear-input! #(set-input-state controlled-input/delete-all) - handle-on-confirm (fn [] - (rf/dispatch [:wallet/set-token-amount-to-send - {:amount - (controlled-input/input-value - input-state) - :stack-id current-screen-id}])) - {fiat-currency :currency} (rf/sub [:profile/profile]) - {token-symbol :symbol - token-networks :networks - token-decimals :decimals - :as - token} (rf/sub [:wallet/wallet-send-token]) - send-enabled-networks (rf/sub [:wallet/wallet-send-enabled-networks]) - enabled-from-chain-ids (rf/sub - [:wallet/wallet-send-enabled-from-chain-ids]) - {token-balance :total-balance - available-balance :available-balance} (rf/sub [:wallet/token-by-symbol - (str token-symbol) - enabled-from-chain-ids]) - currency-symbol (rf/sub [:profile/currency-symbol]) - currency (rf/sub [:profile/currency]) - conversion-rate (-> token :market-values-per-currency currency :price) - loading-routes? (rf/sub - [:wallet/wallet-send-loading-suggested-routes?]) - route (rf/sub [:wallet/wallet-send-route]) - on-confirm (or default-on-confirm handle-on-confirm) - crypto-decimals (or token-decimals default-crypto-decimals) - current-crypto-limit (or default-limit-crypto - (utils/get-standard-crypto-format - token - token-balance)) - available-crypto-limit (or default-limit-crypto - (utils/get-standard-crypto-format - token - available-balance)) - current-fiat-limit (.toFixed (* token-balance conversion-rate) 2) - available-fiat-limit (.toFixed (* available-balance conversion-rate) 2) - current-limit (if crypto-currency? - current-crypto-limit - current-fiat-limit) - available-limit (if crypto-currency? - available-crypto-limit - available-fiat-limit) - valid-input? (not (or (string/blank? - (controlled-input/input-value - input-state)) - (<= (controlled-input/numeric-value - input-state) - 0) - (> (controlled-input/numeric-value - input-state) - available-limit))) - input-num-value (controlled-input/numeric-value input-state) - input-amount (controlled-input/input-value input-state) - confirm-disabled? (or (nil? route) - (empty? route) - (string/blank? (controlled-input/input-value - input-state)) - (<= input-num-value 0) - (> input-num-value current-limit)) - amount (if crypto-currency? - input-amount - (number/remove-trailing-zeroes - (.toFixed (/ input-amount conversion-rate) - crypto-decimals))) - send-amount (rf/sub [:wallet/wallet-send-amount]) - amount-text (str (number/remove-trailing-zeroes - (.toFixed (js/parseFloat send-amount) - (min token-decimals 6))) - " " - token-symbol) - first-route (first route) - native-currency-symbol (when-not confirm-disabled? - (get-in first-route - [:from :native-currency-symbol])) - native-token (when native-currency-symbol - (rf/sub [:wallet/token-by-symbol - native-currency-symbol])) - fee-in-native-token (when-not confirm-disabled? - (send-utils/calculate-full-route-gas-fee route)) - fee-in-crypto-formatted (when fee-in-native-token - (utils/get-standard-crypto-format - native-token - fee-in-native-token)) - fee-in-fiat (when-not confirm-disabled? - (utils/calculate-token-fiat-value - {:currency fiat-currency - :balance fee-in-native-token - :token native-token})) - fee-formatted (when fee-in-fiat - (utils/get-standard-fiat-format - fee-in-crypto-formatted - currency-symbol - fee-in-fiat)) - show-select-asset-sheet #(rf/dispatch - [:show-bottom-sheet - {:content (fn [] - [select-asset-bottom-sheet - clear-input!])}]) - sender-network-values (rf/sub - [:wallet/wallet-send-sender-network-values]) - receiver-network-values (rf/sub - [:wallet/wallet-send-receiver-network-values]) - token-not-supported-in-receiver-networks? (every? #(= (:type %) :not-available) - (filter #(not= (:type %) :add) - receiver-network-values)) - suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes]) - routes (when suggested-routes - (or (:best suggested-routes) [])) - no-routes-found? (and - (every-network-value-is-zero? - sender-network-values) - (not (nil? routes)) - (not loading-routes?) - (not token-not-supported-in-receiver-networks?)) - receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks]) - receiver-preferred-networks (rf/sub - [:wallet/wallet-send-receiver-preferred-networks]) - receiver-preferred-networks-set (set receiver-preferred-networks) - sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network] - (contains? - receiver-preferred-networks-set - receiver-selected-network)) - receiver-networks)) - input-error (controlled-input/input-error input-state) - limit-insufficient? (> (controlled-input/numeric-value input-state) - current-limit) - should-try-again? (and (not limit-insufficient?) no-routes-found?) - current-address (rf/sub [:wallet/current-viewing-account-address])] - (rn/use-mount - (fn [] - (let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!)) - app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)] - #(.remove app-keyboard-listener)))) - (rn/use-effect - (fn [] - (set-input-state #(controlled-input/set-upper-limit % current-limit))) - [current-limit]) - (rn/use-effect - #(when input-error (debounce/clear-all)) - [input-error]) - (rn/use-effect - (fn [] - (when (not= input-state controlled-input/init-state) - (set-input-state controlled-input/init-state))) - [current-address]) - [rn/view - {:style style/screen - :accessibility-label (str "container" - (when (controlled-input/input-error input-state) "-error"))} - [account-switcher/view - {:icon-name :i/arrow-left - :on-press on-navigate-back - :switcher-type :select-account}] - [quo/token-input - {:container-style style/input-container - :token token-symbol - :currency fiat-currency - :currency-symbol currency-symbol - :crypto-decimals (min token-decimals 6) - :error? (controlled-input/input-error input-state) - :networks (seq send-enabled-networks) - :title (i18n/label - :t/send-limit - {:limit (if crypto-currency? - (make-limit-label-crypto current-limit token-symbol) - (make-limit-label-fiat current-limit currency-symbol))}) - :conversion conversion-rate - :show-keyboard? false - :value input-amount - :on-swap (fn [swap-to-crypto-currency?] - (set-just-toggled-mode? true) - (set-crypto-currency swap-to-crypto-currency?) - (set-input-state - (fn [input-state] - (controlled-input/set-input-value - input-state - (let [value (controlled-input/input-value input-state) - new-value (if swap-to-crypto-currency? - (.toFixed (/ value conversion-rate) - crypto-decimals) - (.toFixed (* value conversion-rate) 12))] - (number/remove-trailing-zeroes new-value)))))) - :on-token-press show-select-asset-sheet}] - [routes/view - {:token token - :input-value input-amount - :value amount - :valid-input? valid-input? - :token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks? - :lock-fetch-routes? just-toggled-mode? - :current-screen-id current-screen-id}] - (when (and (not loading-routes?) - sender-network-values - token-not-supported-in-receiver-networks?) - [token-not-available token-symbol receiver-networks token-networks]) - (when (or loading-routes? (seq route)) - [estimated-fees - {:loading-routes? loading-routes? - :fees fee-formatted - :amount amount-text}]) - (when (or no-routes-found? limit-insufficient?) - [rn/view {:style style/no-routes-found-container} - [quo/info-message - {:type :error - :icon :i/alert - :size :default - :style {:margin-top 15}} - (i18n/label :t/no-routes-found)]]) - [quo/bottom-actions - {:actions :one-action - :button-one-label (if should-try-again? - (i18n/label :t/try-again) - button-one-label) - :button-one-props (merge (when-not should-try-again? button-one-props) - {:disabled? (and (not should-try-again?) confirm-disabled?) - :on-press (cond - should-try-again? - #(let [input-amount (controlled-input/input-value - input-state) - amount (if crypto-currency? - input-amount - (.toFixed (* token-balance - conversion-rate) - 2))] - (rf/dispatch [:wallet/get-suggested-routes - {:amount amount}])) - sending-to-unpreferred-networks? - #(show-unpreferred-networks-alert on-confirm) - :else - on-confirm)} - (when should-try-again? - {:type :grey}))}] - [quo/numbered-keyboard - {:container-style (style/keyboard-container bottom) - :left-action :dot - :delete-key? true - :on-press (fn [c] - (let [new-text (str input-amount c) - max-decimals (if crypto-currency? crypto-decimals 2) - regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$") - regex (re-pattern regex-pattern)] - (when (and (not loading-routes?) - (re-matches regex new-text)) - (debounce/clear-all) - (set-just-toggled-mode? false) - (set-input-state #(controlled-input/add-character % c))))) - :on-delete (fn [] - (when-not loading-routes? - (debounce/clear-all) - (set-just-toggled-mode? false) - (set-input-state controlled-input/delete-last))) - :on-long-press-delete (fn [] - (when-not loading-routes? - (debounce/clear-all) - (set-just-toggled-mode? false) - (set-input-state controlled-input/delete-all)))}]])))) + bottom (safe-area/get-bottom) + [crypto-currency? set-crypto-currency] (rn/use-state initial-crypto-currency?) + on-navigate-back on-navigate-back + [input-state set-input-state] (rn/use-state controlled-input/init-state) + [just-toggled-mode? set-just-toggled-mode?] (rn/use-state false) + clear-input! #(set-input-state controlled-input/delete-all) + handle-on-confirm (fn [] + (rf/dispatch [:wallet/set-token-amount-to-send + {:amount + (controlled-input/input-value + input-state) + :stack-id current-screen-id}])) + {fiat-currency :currency} (rf/sub [:profile/profile]) + {token-symbol :symbol + token-networks :networks + token-decimals :decimals + :as + token} (rf/sub [:wallet/wallet-send-token]) + send-enabled-networks (rf/sub [:wallet/wallet-send-enabled-networks]) + enabled-from-chain-ids (rf/sub + [:wallet/wallet-send-enabled-from-chain-ids]) + {token-balance :total-balance + available-balance :available-balance} (rf/sub [:wallet/token-by-symbol + (str token-symbol) + enabled-from-chain-ids]) + currency-symbol (rf/sub [:profile/currency-symbol]) + currency (rf/sub [:profile/currency]) + conversion-rate (-> token + :market-values-per-currency + currency + :price) + loading-routes? (rf/sub + [:wallet/wallet-send-loading-suggested-routes?]) + route (rf/sub [:wallet/wallet-send-route]) + on-confirm (or default-on-confirm handle-on-confirm) + crypto-decimals (or token-decimals default-crypto-decimals) + current-crypto-limit (or default-limit-crypto + (utils/get-standard-crypto-format + token + token-balance)) + available-crypto-limit (or default-limit-crypto + (utils/get-standard-crypto-format + token + available-balance)) + current-fiat-limit (.toFixed (* token-balance conversion-rate) 2) + available-fiat-limit (.toFixed (* available-balance conversion-rate) 2) + current-limit (if crypto-currency? + current-crypto-limit + current-fiat-limit) + available-limit (if crypto-currency? + available-crypto-limit + available-fiat-limit) + valid-input? (not (or (string/blank? + (controlled-input/input-value + input-state)) + (<= (controlled-input/numeric-value + input-state) + 0) + (> (controlled-input/numeric-value + input-state) + available-limit))) + input-num-value (controlled-input/numeric-value input-state) + input-amount (controlled-input/input-value input-state) + confirm-disabled? (or (nil? route) + (empty? route) + (string/blank? (controlled-input/input-value + input-state)) + (<= input-num-value 0) + (> input-num-value current-limit)) + amount (if crypto-currency? + input-amount + (number/remove-trailing-zeroes + (.toFixed (/ input-amount conversion-rate) + crypto-decimals))) + send-amount (rf/sub [:wallet/wallet-send-amount]) + amount-text (str (number/remove-trailing-zeroes + (.toFixed (js/parseFloat send-amount) + (min token-decimals 6))) + " " + token-symbol) + first-route (first route) + native-currency-symbol (when-not confirm-disabled? + (get-in first-route + [:from :native-currency-symbol])) + native-token (when native-currency-symbol + (rf/sub [:wallet/token-by-symbol + native-currency-symbol])) + fee-in-native-token (when-not confirm-disabled? + (send-utils/calculate-full-route-gas-fee route)) + fee-in-crypto-formatted (when fee-in-native-token + (utils/get-standard-crypto-format + native-token + fee-in-native-token)) + fee-in-fiat (when-not confirm-disabled? + (utils/calculate-token-fiat-value + {:currency fiat-currency + :balance fee-in-native-token + :token native-token})) + fee-formatted (when fee-in-fiat + (utils/get-standard-fiat-format + fee-in-crypto-formatted + currency-symbol + fee-in-fiat)) + show-select-asset-sheet #(rf/dispatch + [:show-bottom-sheet + {:content (fn [] + [select-asset-bottom-sheet + clear-input!])}]) + sender-network-values (rf/sub + [:wallet/wallet-send-sender-network-values]) + receiver-network-values (rf/sub + [:wallet/wallet-send-receiver-network-values]) + token-not-supported-in-receiver-networks? (every? #(= (:type %) :not-available) + (filter #(not= (:type %) :add) + receiver-network-values)) + suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes]) + routes (when suggested-routes + (or (:best suggested-routes) [])) + no-routes-found? (and + (every-network-value-is-zero? + sender-network-values) + (not (nil? routes)) + (not loading-routes?) + (not token-not-supported-in-receiver-networks?)) + receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks]) + receiver-preferred-networks (rf/sub + [:wallet/wallet-send-receiver-preferred-networks]) + receiver-preferred-networks-set (set receiver-preferred-networks) + sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network] + (contains? + receiver-preferred-networks-set + receiver-selected-network)) + receiver-networks)) + input-error (controlled-input/input-error input-state) + limit-insufficient? (> (controlled-input/numeric-value input-state) + current-limit) + should-try-again? (and (not limit-insufficient?) no-routes-found?) + current-address (rf/sub [:wallet/current-viewing-account-address])] + (rn/use-mount + (fn [] + (let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!)) + app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)] + #(.remove app-keyboard-listener)))) + (rn/use-effect + (fn [] + (set-input-state #(controlled-input/set-upper-limit % current-limit))) + [current-limit]) + (rn/use-effect + #(when input-error (debounce/clear-all)) + [input-error]) + (rn/use-effect + (fn [] + (when (not= input-state controlled-input/init-state) + (set-input-state controlled-input/init-state))) + [current-address]) + [rn/view + {:style style/screen + :accessibility-label (str "container" + (when (controlled-input/input-error input-state) "-error"))} + [account-switcher/view + {:icon-name :i/arrow-left + :on-press on-navigate-back + :switcher-type :select-account}] + [quo/token-input + {:container-style style/input-container + :token token-symbol + :currency fiat-currency + :currency-symbol currency-symbol + :crypto-decimals (min token-decimals 6) + :error? (controlled-input/input-error input-state) + :networks (seq send-enabled-networks) + :title (i18n/label + :t/send-limit + {:limit (if crypto-currency? + (make-limit-label-crypto current-limit token-symbol) + (make-limit-label-fiat current-limit currency-symbol))}) + :conversion conversion-rate + :show-keyboard? false + :value input-amount + :on-swap (fn [swap-to-crypto-currency?] + (set-just-toggled-mode? true) + (set-crypto-currency swap-to-crypto-currency?) + (set-input-state + (fn [input-state] + (controlled-input/set-input-value + input-state + (let [value (controlled-input/input-value input-state) + new-value (if swap-to-crypto-currency? + (.toFixed (/ value conversion-rate) + crypto-decimals) + (.toFixed (* value conversion-rate) 12))] + (number/remove-trailing-zeroes new-value)))))) + :on-token-press show-select-asset-sheet}] + [routes/view + {:token token + :input-value input-amount + :value amount + :valid-input? valid-input? + :token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks? + :lock-fetch-routes? just-toggled-mode? + :current-screen-id current-screen-id}] + (when (and (not loading-routes?) + sender-network-values + token-not-supported-in-receiver-networks?) + [token-not-available token-symbol receiver-networks token-networks]) + (when (or loading-routes? (seq route)) + [estimated-fees + {:loading-routes? loading-routes? + :fees fee-formatted + :amount amount-text}]) + (when (or no-routes-found? limit-insufficient?) + [rn/view {:style style/no-routes-found-container} + [quo/info-message + {:type :error + :icon :i/alert + :size :default + :style {:margin-top 15}} + (i18n/label :t/no-routes-found)]]) + [quo/bottom-actions + {:actions :one-action + :button-one-label (if should-try-again? + (i18n/label :t/try-again) + button-one-label) + :button-one-props (merge (when-not should-try-again? button-one-props) + {:disabled? (and (not should-try-again?) confirm-disabled?) + :on-press (cond + should-try-again? + #(let [input-amount (controlled-input/input-value + input-state) + amount (if crypto-currency? + input-amount + (.toFixed (* token-balance + conversion-rate) + 2))] + (rf/dispatch [:wallet/get-suggested-routes + {:amount amount}])) + sending-to-unpreferred-networks? + #(show-unpreferred-networks-alert on-confirm) + :else + on-confirm)} + (when should-try-again? + {:type :grey}))}] + [quo/numbered-keyboard + {:container-style (style/keyboard-container bottom) + :left-action :dot + :delete-key? true + :on-press (fn [c] + (let [new-text (str input-amount c) + max-decimals (if crypto-currency? crypto-decimals 2) + regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$") + regex (re-pattern regex-pattern)] + (when (and (not loading-routes?) + (re-matches regex new-text)) + (debounce/clear-all) + (set-just-toggled-mode? false) + (set-input-state #(controlled-input/add-character % c))))) + :on-delete (fn [] + (when-not loading-routes? + (debounce/clear-all) + (set-just-toggled-mode? false) + (set-input-state controlled-input/delete-last))) + :on-long-press-delete (fn [] + (when-not loading-routes? + (debounce/clear-all) + (set-just-toggled-mode? false) + (set-input-state controlled-input/delete-all)))}]]))