fix: no routes are found in case of valid amount in fiat is entered (#20000)
Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
parent
3de86b09bd
commit
d4e7e4cd52
|
@ -6,14 +6,16 @@
|
||||||
(h/describe "Wallet: Token Input"
|
(h/describe "Wallet: Token Input"
|
||||||
(h/test "Token label renders"
|
(h/test "Token label renders"
|
||||||
(h/render-with-theme-provider [token-input/view
|
(h/render-with-theme-provider [token-input/view
|
||||||
{:token :snt
|
{:token :snt
|
||||||
:currency :eur
|
:currency :eur
|
||||||
:conversion 1}])
|
:currency-symbol "€"
|
||||||
|
:conversion 1}])
|
||||||
(h/is-truthy (h/get-by-text "SNT")))
|
(h/is-truthy (h/get-by-text "SNT")))
|
||||||
|
|
||||||
(h/test "Amount renders"
|
(h/test "Amount renders"
|
||||||
(h/render-with-theme-provider [token-input/view
|
(h/render-with-theme-provider [token-input/view
|
||||||
{:token :snt
|
{:token :snt
|
||||||
:currency :eur
|
:currency :eur
|
||||||
:conversion 1}])
|
:currency-symbol "€"
|
||||||
|
:conversion 1}])
|
||||||
(h/is-truthy (h/get-by-text "€0.00"))))
|
(h/is-truthy (h/get-by-text "€0.00"))))
|
||||||
|
|
|
@ -12,30 +12,22 @@
|
||||||
{:padding-horizontal 20
|
{:padding-horizontal 20
|
||||||
:padding-bottom 4
|
:padding-bottom 4
|
||||||
:height 36
|
:height 36
|
||||||
:flex-direction :row
|
:flex-direction :row})
|
||||||
:justify-content :space-between})
|
|
||||||
|
|
||||||
(defn token-name
|
(defn token-name
|
||||||
[theme]
|
[theme]
|
||||||
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||||
:margin-right 8
|
:padding-bottom 3})
|
||||||
:padding-bottom 2})
|
|
||||||
|
|
||||||
(def token-label-container
|
|
||||||
{:position :absolute
|
|
||||||
:left 40 ; token image size + margin
|
|
||||||
:right 0
|
|
||||||
:bottom 0
|
|
||||||
:top 0
|
|
||||||
:flex-direction :row
|
|
||||||
:align-items :flex-end})
|
|
||||||
|
|
||||||
(def text-input-container
|
(def text-input-container
|
||||||
{:position :absolute
|
{:flex-direction :row
|
||||||
:top 0
|
:align-items :flex-end})
|
||||||
:bottom 0
|
|
||||||
:left 40 ; token image size + margin
|
(defn input-container
|
||||||
:right 0})
|
[window-width]
|
||||||
|
{:width (- window-width 120)
|
||||||
|
:margin-left 8
|
||||||
|
:margin-right 8})
|
||||||
|
|
||||||
(def text-input-dimensions
|
(def text-input-dimensions
|
||||||
(-> typography/heading-1
|
(-> typography/heading-1
|
||||||
|
@ -54,7 +46,8 @@
|
||||||
:color
|
:color
|
||||||
(if error?
|
(if error?
|
||||||
(colors/resolve-color :danger theme)
|
(colors/resolve-color :danger theme)
|
||||||
(colors/theme-colors colors/neutral-100 colors/white theme))))
|
(colors/theme-colors colors/neutral-100 colors/white theme))
|
||||||
|
:flex-shrink 1))
|
||||||
|
|
||||||
(defn placeholder-text
|
(defn placeholder-text
|
||||||
[theme]
|
[theme]
|
||||||
|
|
|
@ -9,32 +9,34 @@
|
||||||
[quo.components.utilities.token.view :as token]
|
[quo.components.utilities.token.view :as token]
|
||||||
[quo.components.wallet.token-input.schema :as component-schema]
|
[quo.components.wallet.token-input.schema :as component-schema]
|
||||||
[quo.components.wallet.token-input.style :as style]
|
[quo.components.wallet.token-input.style :as style]
|
||||||
[quo.foundations.common :as common]
|
|
||||||
[quo.theme :as quo.theme]
|
[quo.theme :as quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[schema.core :as schema]))
|
[schema.core :as schema]
|
||||||
|
[utils.number :as number]))
|
||||||
|
|
||||||
(defn fiat-format
|
(defn fiat-format
|
||||||
[currency num-value conversion]
|
[currency-symbol num-value conversion]
|
||||||
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2)))
|
(str currency-symbol (.toFixed (* num-value conversion) 2)))
|
||||||
|
|
||||||
(defn crypto-format
|
(defn crypto-format
|
||||||
[num-value conversion crypto-decimals token]
|
[num-value conversion crypto-decimals token]
|
||||||
(str (.toFixed (/ num-value conversion) (or crypto-decimals 2))
|
(str (number/remove-trailing-zeroes
|
||||||
|
(.toFixed (/ num-value conversion) (or crypto-decimals 2)))
|
||||||
" "
|
" "
|
||||||
(string/upper-case (or (clj->js token) ""))))
|
(string/upper-case (or (clj->js token) ""))))
|
||||||
|
|
||||||
(defn calc-value
|
(defn calc-value
|
||||||
[{:keys [crypto? currency token value conversion crypto-decimals]}]
|
[{:keys [crypto? currency-symbol token value conversion crypto-decimals]}]
|
||||||
(let [num-value (if (string? value)
|
(let [num-value (if (string? value)
|
||||||
(or (parse-double value) 0)
|
(or (parse-double value) 0)
|
||||||
value)]
|
value)]
|
||||||
(if crypto?
|
(if crypto?
|
||||||
(fiat-format currency num-value conversion)
|
(fiat-format currency-symbol num-value conversion)
|
||||||
(crypto-format num-value conversion crypto-decimals token))))
|
(crypto-format num-value conversion crypto-decimals token))))
|
||||||
|
|
||||||
(defn- data-info
|
(defn- data-info
|
||||||
[{:keys [theme token crypto-decimals conversion networks title crypto? currency amount error?]}]
|
[{:keys [theme token crypto-decimals conversion networks title crypto? currency-symbol amount
|
||||||
|
error?]}]
|
||||||
[rn/view {:style style/data-container}
|
[rn/view {:style style/data-container}
|
||||||
[network-tag/view
|
[network-tag/view
|
||||||
{:networks networks
|
{:networks networks
|
||||||
|
@ -45,7 +47,7 @@
|
||||||
:weight :medium
|
:weight :medium
|
||||||
:style (style/fiat-amount theme)}
|
:style (style/fiat-amount theme)}
|
||||||
(calc-value {:crypto? crypto?
|
(calc-value {:crypto? crypto?
|
||||||
:currency currency
|
:currency-symbol currency-symbol
|
||||||
:token token
|
:token token
|
||||||
:value amount
|
:value amount
|
||||||
:conversion conversion
|
:conversion conversion
|
||||||
|
@ -59,20 +61,6 @@
|
||||||
:weight :semi-bold}
|
:weight :semi-bold}
|
||||||
(string/upper-case (or (clj->js text) ""))])
|
(string/upper-case (or (clj->js text) ""))])
|
||||||
|
|
||||||
(defn- token-label
|
|
||||||
[{:keys [theme value text]}]
|
|
||||||
[rn/view
|
|
||||||
{:style style/token-label-container
|
|
||||||
:pointer-events :none}
|
|
||||||
[rn/text-input
|
|
||||||
{:max-length 12
|
|
||||||
:style style/text-input-dimensions
|
|
||||||
:editable false
|
|
||||||
:placeholder "0"
|
|
||||||
:opacity 0
|
|
||||||
:value value}]
|
|
||||||
[token-name-text theme text]])
|
|
||||||
|
|
||||||
(defn input-section
|
(defn input-section
|
||||||
[{:keys [on-change-text value value-internal set-value-internal on-selection-change
|
[{:keys [on-change-text value value-internal set-value-internal on-selection-change
|
||||||
on-token-press]}]
|
on-token-press]}]
|
||||||
|
@ -92,36 +80,45 @@
|
||||||
(oops/oget "nativeEvent.selection")
|
(oops/oget "nativeEvent.selection")
|
||||||
(js->clj :keywordize-keys true)
|
(js->clj :keywordize-keys true)
|
||||||
(on-selection-change))))]
|
(on-selection-change))))]
|
||||||
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection]
|
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection
|
||||||
|
handle-on-swap]
|
||||||
:or {show-keyboard? true}}]
|
:or {show-keyboard? true}}]
|
||||||
(let [theme (quo.theme/use-theme)]
|
(let [theme (quo.theme/use-theme)
|
||||||
[rn/view {:style {:flex 1}}
|
window-width (:width (rn/get-window))]
|
||||||
[rn/pressable {:on-press on-token-press}
|
[rn/pressable
|
||||||
[token/view
|
{:style {:width "100%"
|
||||||
{:token token
|
:flex-direction :row}
|
||||||
:size :size-32}]]
|
:on-press on-token-press}
|
||||||
[rn/pressable
|
[token/view
|
||||||
{:style style/text-input-container
|
{:token token
|
||||||
:on-press focus-input}
|
:size :size-32}]
|
||||||
[rn/text-input
|
[rn/view {:style (style/input-container window-width)}
|
||||||
(cond-> {:style (style/text-input theme error?)
|
[rn/pressable
|
||||||
:placeholder-text-color (style/placeholder-text theme)
|
{:style style/text-input-container
|
||||||
:auto-focus true
|
:on-press focus-input}
|
||||||
:ref set-ref
|
[rn/text-input
|
||||||
:placeholder "0"
|
(cond-> {:style (style/text-input theme error?)
|
||||||
:keyboard-type :numeric
|
:placeholder-text-color (style/placeholder-text theme)
|
||||||
:max-length 12
|
:auto-focus true
|
||||||
:on-change-text handle-on-change-text
|
:ref set-ref
|
||||||
:selection-color customization-color
|
:placeholder "0"
|
||||||
:show-soft-input-on-focus show-keyboard?
|
:keyboard-type :numeric
|
||||||
:on-selection-change handle-selection-change
|
:on-change-text handle-on-change-text
|
||||||
:selection (clj->js selection)}
|
:selection-color customization-color
|
||||||
controlled-input? (assoc :value value)
|
:show-soft-input-on-focus show-keyboard?
|
||||||
(not controlled-input?) (assoc :default-value value-internal))]]
|
:on-selection-change handle-selection-change
|
||||||
[token-label
|
:selection (clj->js selection)}
|
||||||
{:theme theme
|
controlled-input? (assoc :value value)
|
||||||
:text (if crypto? token currency)
|
(not controlled-input?) (assoc :default-value value-internal))]
|
||||||
:value (if controlled-input? value value-internal)}]]))))
|
[token-name-text theme (if crypto? token currency)]]]
|
||||||
|
[button/button
|
||||||
|
{:icon true
|
||||||
|
:icon-only? true
|
||||||
|
:size 32
|
||||||
|
:on-press handle-on-swap
|
||||||
|
:type :outline
|
||||||
|
:accessibility-label :reorder}
|
||||||
|
:i/reorder]]))))
|
||||||
|
|
||||||
(defn- view-internal
|
(defn- view-internal
|
||||||
[{:keys [container-style value on-swap] :as props}]
|
[{:keys [container-style value on-swap] :as props}]
|
||||||
|
@ -141,15 +138,8 @@
|
||||||
:value-internal value-internal
|
:value-internal value-internal
|
||||||
:theme theme
|
:theme theme
|
||||||
:set-value-internal set-value-internal
|
:set-value-internal set-value-internal
|
||||||
:crypto? crypto?)]
|
:handle-on-swap handle-on-swap
|
||||||
[button/button
|
:crypto? crypto?)]]
|
||||||
{:icon true
|
|
||||||
:icon-only? true
|
|
||||||
:size 32
|
|
||||||
:on-press handle-on-swap
|
|
||||||
:type :outline
|
|
||||||
:accessibility-label :reorder}
|
|
||||||
:i/reorder]]
|
|
||||||
[divider-line/view {:container-style (style/divider theme)}]
|
[divider-line/view {:container-style (style/divider theme)}]
|
||||||
[data-info
|
[data-info
|
||||||
(assoc props
|
(assoc props
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
(ns quo.foundations.common)
|
|
||||||
|
|
||||||
(def currency-label
|
|
||||||
{:eur "€"
|
|
||||||
:usd "$"})
|
|
|
@ -37,7 +37,7 @@
|
||||||
[state]
|
[state]
|
||||||
(set-input-error state (upper-limit-exceeded? state)))
|
(set-input-error state (upper-limit-exceeded? state)))
|
||||||
|
|
||||||
(defn- set-input-value
|
(defn set-input-value
|
||||||
[state value]
|
[state value]
|
||||||
(-> state
|
(-> state
|
||||||
(assoc :value value)
|
(assoc :value value)
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
[status-im.common.qr-codes.view :as qr-codes]
|
[status-im.common.qr-codes.view :as qr-codes]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[utils.money :as money]
|
[utils.money :as money]
|
||||||
[utils.number]))
|
[utils.number :as number]))
|
||||||
|
|
||||||
(defn get-first-name
|
(defn get-first-name
|
||||||
[full-name]
|
[full-name]
|
||||||
|
@ -56,16 +56,6 @@
|
||||||
(inc max-decimals)
|
(inc max-decimals)
|
||||||
max-decimals)))
|
max-decimals)))
|
||||||
|
|
||||||
(defn remove-trailing-zeroes
|
|
||||||
[num]
|
|
||||||
(let [parts (clojure.string/split (str num) #"\.")]
|
|
||||||
(str (first parts)
|
|
||||||
(if-let [decimals (second parts)]
|
|
||||||
(if (seq (clojure.string/replace decimals #"0+$" ""))
|
|
||||||
(str "." (clojure.string/replace decimals #"0+$" ""))
|
|
||||||
"")
|
|
||||||
""))))
|
|
||||||
|
|
||||||
(defn get-crypto-decimals-count
|
(defn get-crypto-decimals-count
|
||||||
[{:keys [market-values-per-currency]}]
|
[{:keys [market-values-per-currency]}]
|
||||||
(let [price (get-in market-values-per-currency [:usd :price])
|
(let [price (get-in market-values-per-currency [:usd :price])
|
||||||
|
@ -83,8 +73,8 @@
|
||||||
one-cent-value (if (pos? price) (/ 0.01 price) 0)
|
one-cent-value (if (pos? price) (/ 0.01 price) 0)
|
||||||
decimals-count (calc-max-crypto-decimals one-cent-value)]
|
decimals-count (calc-max-crypto-decimals one-cent-value)]
|
||||||
(if (< token-units one-cent-value)
|
(if (< token-units one-cent-value)
|
||||||
(str "<" (remove-trailing-zeroes (.toFixed one-cent-value decimals-count)))
|
(str "<" (number/remove-trailing-zeroes (.toFixed one-cent-value decimals-count)))
|
||||||
(remove-trailing-zeroes (.toFixed token-units decimals-count))))))
|
(number/remove-trailing-zeroes (.toFixed token-units decimals-count))))))
|
||||||
|
|
||||||
(defn get-market-value
|
(defn get-market-value
|
||||||
[currency {:keys [market-values-per-currency]}]
|
[currency {:keys [market-values-per-currency]}]
|
||||||
|
|
|
@ -117,6 +117,7 @@
|
||||||
dissoc
|
dissoc
|
||||||
:suggested-routes
|
:suggested-routes
|
||||||
:route
|
:route
|
||||||
|
:amount
|
||||||
:from-values-by-chain
|
:from-values-by-chain
|
||||||
:to-values-by-chain
|
:to-values-by-chain
|
||||||
:sender-network-values
|
:sender-network-values
|
||||||
|
|
|
@ -69,6 +69,7 @@
|
||||||
:view-id :screen/wallet.send-input-amount
|
:view-id :screen/wallet.send-input-amount
|
||||||
:wallet/wallet-send-to-address "0x04371e2d9d66b82f056bc128064"
|
:wallet/wallet-send-to-address "0x04371e2d9d66b82f056bc128064"
|
||||||
:profile/currency-symbol "$"
|
:profile/currency-symbol "$"
|
||||||
|
:profile/currency :usd
|
||||||
:wallet/token-by-symbol {:symbol :eth
|
:wallet/token-by-symbol {:symbol :eth
|
||||||
:total-balance 100
|
:total-balance 100
|
||||||
:market-values-per-currency {:usd {:price 10}}}
|
:market-values-per-currency {:usd {:price 10}}}
|
||||||
|
@ -86,7 +87,8 @@
|
||||||
:chain-id 1
|
:chain-id 1
|
||||||
:related-chain-id 1
|
:related-chain-id 1
|
||||||
:layer 1}]
|
:layer 1}]
|
||||||
:wallet/wallet-send-enabled-from-chain-ids [1]})
|
:wallet/wallet-send-enabled-from-chain-ids [1]
|
||||||
|
:wallet/wallet-send-amount nil})
|
||||||
|
|
||||||
(h/describe "Send > input amount screen"
|
(h/describe "Send > input amount screen"
|
||||||
(h/setup-restorable-re-frame)
|
(h/setup-restorable-re-frame)
|
||||||
|
@ -173,6 +175,6 @@
|
||||||
(h/is-truthy (h/get-by-label-text :container-error))
|
(h/is-truthy (h/get-by-label-text :container-error))
|
||||||
(h/fire-event :press (h/query-by-label-text :reorder))
|
(h/fire-event :press (h/query-by-label-text :reorder))
|
||||||
|
|
||||||
(-> (h/wait-for #(h/get-by-text "Max: 1000.00 USD"))
|
(-> (h/wait-for #(h/get-by-text "Max: $1000.00"))
|
||||||
(.then (fn []
|
(.then (fn []
|
||||||
(h/wait-for #(h/is-truthy (h/get-by-label-text :container))))))))
|
(h/wait-for #(h/is-truthy (h/get-by-label-text :container))))))))
|
||||||
|
|
|
@ -16,11 +16,13 @@
|
||||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||||
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
|
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
|
||||||
[utils.address :as address]
|
[utils.address :as address]
|
||||||
|
[utils.debounce :as debounce]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.money :as money]
|
[utils.money :as money]
|
||||||
|
[utils.number :as number]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- make-limit-label
|
(defn- make-limit-label-crypto
|
||||||
[amount currency]
|
[amount currency]
|
||||||
(str amount
|
(str amount
|
||||||
" "
|
" "
|
||||||
|
@ -28,6 +30,10 @@
|
||||||
name
|
name
|
||||||
string/upper-case)))
|
string/upper-case)))
|
||||||
|
|
||||||
|
(defn- make-limit-label-fiat
|
||||||
|
[amount currency-symbol]
|
||||||
|
(str currency-symbol amount))
|
||||||
|
|
||||||
(defn- estimated-fees
|
(defn- estimated-fees
|
||||||
[{:keys [loading-routes? fees amount receiver]}]
|
[{:keys [loading-routes? fees amount receiver]}]
|
||||||
[rn/view {:style style/estimated-fees-container}
|
[rn/view {:style style/estimated-fees-container}
|
||||||
|
@ -61,6 +67,7 @@
|
||||||
(every? (fn [{:keys [total-amount]}]
|
(every? (fn [{:keys [total-amount]}]
|
||||||
(and
|
(and
|
||||||
total-amount
|
total-amount
|
||||||
|
(money/bignumber? total-amount)
|
||||||
(money/equal-to total-amount
|
(money/equal-to total-amount
|
||||||
(money/bignumber "0"))))
|
(money/bignumber "0"))))
|
||||||
sender-network-values))
|
sender-network-values))
|
||||||
|
@ -127,129 +134,138 @@
|
||||||
crypto-currency? (reagent/atom initial-crypto-currency?)
|
crypto-currency? (reagent/atom initial-crypto-currency?)
|
||||||
on-navigate-back on-navigate-back]
|
on-navigate-back on-navigate-back]
|
||||||
(fn []
|
(fn []
|
||||||
(let [[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
(let [[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
||||||
clear-input! #(set-input-state controlled-input/delete-all)
|
[just-toggled-mode? set-just-toggled-mode?] (rn/use-state false)
|
||||||
handle-on-confirm (fn []
|
clear-input! #(set-input-state controlled-input/delete-all)
|
||||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
handle-on-confirm (fn []
|
||||||
{:amount
|
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||||
(controlled-input/input-value
|
{:amount
|
||||||
input-state)
|
(controlled-input/input-value
|
||||||
:stack-id current-screen-id}]))
|
input-state)
|
||||||
{fiat-currency :currency} (rf/sub [:profile/profile])
|
:stack-id current-screen-id}]))
|
||||||
|
{fiat-currency :currency} (rf/sub [:profile/profile])
|
||||||
{token-symbol :symbol
|
{token-symbol :symbol
|
||||||
token-networks :networks} (rf/sub [:wallet/wallet-send-token])
|
token-networks :networks
|
||||||
send-enabled-networks (rf/sub [:wallet/wallet-send-enabled-networks])
|
token-decimals :decimals} (rf/sub [:wallet/wallet-send-token])
|
||||||
enabled-from-chain-ids (rf/sub
|
send-enabled-networks (rf/sub [:wallet/wallet-send-enabled-networks])
|
||||||
[:wallet/wallet-send-enabled-from-chain-ids])
|
enabled-from-chain-ids (rf/sub
|
||||||
|
[:wallet/wallet-send-enabled-from-chain-ids])
|
||||||
{token-balance :total-balance
|
{token-balance :total-balance
|
||||||
available-balance :available-balance
|
available-balance :available-balance
|
||||||
:as
|
:as
|
||||||
token} (rf/sub
|
token} (rf/sub
|
||||||
[:wallet/current-viewing-account-tokens-filtered
|
[:wallet/current-viewing-account-tokens-filtered
|
||||||
(str token-symbol) enabled-from-chain-ids])
|
(str token-symbol) enabled-from-chain-ids])
|
||||||
conversion-rate (-> token :market-values-per-currency :usd :price)
|
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||||
loading-routes? (rf/sub
|
currency (rf/sub [:profile/currency])
|
||||||
[:wallet/wallet-send-loading-suggested-routes?])
|
conversion-rate (-> token :market-values-per-currency currency :price)
|
||||||
|
loading-routes? (rf/sub
|
||||||
route (rf/sub [:wallet/wallet-send-route])
|
[:wallet/wallet-send-loading-suggested-routes?])
|
||||||
to-address (rf/sub [:wallet/wallet-send-to-address])
|
route (rf/sub [:wallet/wallet-send-route])
|
||||||
|
to-address (rf/sub [:wallet/wallet-send-to-address])
|
||||||
on-confirm (or default-on-confirm handle-on-confirm)
|
on-confirm (or default-on-confirm handle-on-confirm)
|
||||||
crypto-decimals (or default-crypto-decimals
|
crypto-decimals (or token-decimals default-crypto-decimals)
|
||||||
(utils/get-crypto-decimals-count token))
|
current-crypto-limit (or default-limit-crypto
|
||||||
current-crypto-limit (or default-limit-crypto
|
(utils/get-standard-crypto-format
|
||||||
(utils/get-standard-crypto-format
|
token
|
||||||
token
|
token-balance))
|
||||||
token-balance))
|
available-crypto-limit (or default-limit-crypto
|
||||||
available-crypto-limit (or default-limit-crypto
|
(utils/get-standard-crypto-format
|
||||||
(utils/get-standard-crypto-format
|
token
|
||||||
token
|
available-balance))
|
||||||
available-balance))
|
current-fiat-limit (.toFixed (* token-balance conversion-rate) 2)
|
||||||
current-fiat-limit (.toFixed (* token-balance conversion-rate) 2)
|
available-fiat-limit (.toFixed (* available-balance conversion-rate) 2)
|
||||||
available-fiat-limit (.toFixed (* available-balance conversion-rate) 2)
|
current-limit (if @crypto-currency?
|
||||||
current-limit (if @crypto-currency?
|
current-crypto-limit
|
||||||
current-crypto-limit
|
current-fiat-limit)
|
||||||
current-fiat-limit)
|
available-limit (if @crypto-currency?
|
||||||
available-limit (if @crypto-currency?
|
available-crypto-limit
|
||||||
available-crypto-limit
|
available-fiat-limit)
|
||||||
available-fiat-limit)
|
valid-input? (not (or (string/blank?
|
||||||
valid-input? (not (or (string/blank?
|
(controlled-input/input-value
|
||||||
(controlled-input/input-value
|
input-state))
|
||||||
input-state))
|
(<= (controlled-input/numeric-value
|
||||||
(<= (controlled-input/numeric-value
|
input-state)
|
||||||
input-state)
|
0)
|
||||||
0)
|
(> (controlled-input/numeric-value
|
||||||
(> (controlled-input/numeric-value
|
input-state)
|
||||||
input-state)
|
available-limit)))
|
||||||
available-limit)))
|
input-num-value (controlled-input/numeric-value input-state)
|
||||||
current-currency (if @crypto-currency? token-symbol fiat-currency)
|
input-amount (controlled-input/input-value input-state)
|
||||||
input-num-value (controlled-input/numeric-value input-state)
|
confirm-disabled? (or (nil? route)
|
||||||
confirm-disabled? (or (nil? route)
|
(empty? route)
|
||||||
(empty? route)
|
(string/blank? (controlled-input/input-value
|
||||||
(string/blank? (controlled-input/input-value
|
input-state))
|
||||||
input-state))
|
(<= input-num-value 0)
|
||||||
(<= input-num-value 0)
|
(> input-num-value current-limit))
|
||||||
(> input-num-value current-limit))
|
amount (if @crypto-currency?
|
||||||
amount-text (str (controlled-input/input-value input-state)
|
input-amount
|
||||||
" "
|
(number/remove-trailing-zeroes
|
||||||
token-symbol)
|
(.toFixed (/ input-amount conversion-rate)
|
||||||
first-route (first route)
|
crypto-decimals)))
|
||||||
native-currency-symbol (when-not confirm-disabled?
|
send-amount (rf/sub [:wallet/wallet-send-amount])
|
||||||
(get-in first-route
|
amount-text (str (number/remove-trailing-zeroes
|
||||||
[:from :native-currency-symbol]))
|
(.toFixed (js/parseFloat send-amount)
|
||||||
native-token (when native-currency-symbol
|
(min token-decimals 6)))
|
||||||
(rf/sub [:wallet/token-by-symbol
|
" "
|
||||||
native-currency-symbol]))
|
token-symbol)
|
||||||
fee-in-native-token (when-not confirm-disabled?
|
first-route (first route)
|
||||||
(send-utils/calculate-full-route-gas-fee route))
|
native-currency-symbol (when-not confirm-disabled?
|
||||||
fee-in-crypto-formatted (when fee-in-native-token
|
(get-in first-route
|
||||||
(utils/get-standard-crypto-format
|
[:from :native-currency-symbol]))
|
||||||
native-token
|
native-token (when native-currency-symbol
|
||||||
fee-in-native-token))
|
(rf/sub [:wallet/token-by-symbol
|
||||||
fee-in-fiat (when-not confirm-disabled?
|
native-currency-symbol]))
|
||||||
(utils/calculate-token-fiat-value
|
fee-in-native-token (when-not confirm-disabled?
|
||||||
{:currency fiat-currency
|
(send-utils/calculate-full-route-gas-fee route))
|
||||||
:balance fee-in-native-token
|
fee-in-crypto-formatted (when fee-in-native-token
|
||||||
:token native-token}))
|
(utils/get-standard-crypto-format
|
||||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
native-token
|
||||||
fee-formatted (when fee-in-fiat
|
fee-in-native-token))
|
||||||
(utils/get-standard-fiat-format
|
fee-in-fiat (when-not confirm-disabled?
|
||||||
fee-in-crypto-formatted
|
(utils/calculate-token-fiat-value
|
||||||
currency-symbol
|
{:currency fiat-currency
|
||||||
fee-in-fiat))
|
:balance fee-in-native-token
|
||||||
show-select-asset-sheet #(rf/dispatch
|
:token native-token}))
|
||||||
[:show-bottom-sheet
|
fee-formatted (when fee-in-fiat
|
||||||
{:content (fn []
|
(utils/get-standard-fiat-format
|
||||||
[select-asset-bottom-sheet
|
fee-in-crypto-formatted
|
||||||
clear-input!])}])
|
currency-symbol
|
||||||
sender-network-values (rf/sub
|
fee-in-fiat))
|
||||||
[:wallet/wallet-send-sender-network-values])
|
show-select-asset-sheet #(rf/dispatch
|
||||||
receiver-network-values (rf/sub
|
[:show-bottom-sheet
|
||||||
[:wallet/wallet-send-receiver-network-values])
|
{: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)
|
token-not-supported-in-receiver-networks? (every? #(= (:type %) :not-available)
|
||||||
(filter #(not= (:type %) :add)
|
(filter #(not= (:type %) :add)
|
||||||
receiver-network-values))
|
receiver-network-values))
|
||||||
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
|
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
|
||||||
routes (when suggested-routes
|
routes (when suggested-routes
|
||||||
(or (:best suggested-routes) []))
|
(or (:best suggested-routes) []))
|
||||||
no-routes-found? (and
|
no-routes-found? (and
|
||||||
(every-network-value-is-zero?
|
(every-network-value-is-zero?
|
||||||
sender-network-values)
|
sender-network-values)
|
||||||
(not (nil? routes))
|
(not (nil? routes))
|
||||||
(not loading-routes?)
|
(not loading-routes?)
|
||||||
(not token-not-supported-in-receiver-networks?))
|
(not token-not-supported-in-receiver-networks?))
|
||||||
receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
|
receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
|
||||||
receiver-preferred-networks (rf/sub
|
receiver-preferred-networks (rf/sub
|
||||||
[:wallet/wallet-send-receiver-preferred-networks])
|
[:wallet/wallet-send-receiver-preferred-networks])
|
||||||
receiver-preferred-networks-set (set receiver-preferred-networks)
|
receiver-preferred-networks-set (set receiver-preferred-networks)
|
||||||
sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network]
|
sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network]
|
||||||
(contains?
|
(contains?
|
||||||
receiver-preferred-networks-set
|
receiver-preferred-networks-set
|
||||||
receiver-selected-network))
|
receiver-selected-network))
|
||||||
receiver-networks))
|
receiver-networks))
|
||||||
limit-insufficient? (> (controlled-input/numeric-value input-state)
|
input-error (controlled-input/input-error input-state)
|
||||||
current-limit)
|
limit-insufficient? (> (controlled-input/numeric-value input-state)
|
||||||
should-try-again? (and (not limit-insufficient?) no-routes-found?)]
|
current-limit)
|
||||||
|
should-try-again? (and (not limit-insufficient?) no-routes-found?)]
|
||||||
(rn/use-mount
|
(rn/use-mount
|
||||||
(fn []
|
(fn []
|
||||||
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
||||||
|
@ -259,6 +275,9 @@
|
||||||
(fn []
|
(fn []
|
||||||
(set-input-state #(controlled-input/set-upper-limit % current-limit)))
|
(set-input-state #(controlled-input/set-upper-limit % current-limit)))
|
||||||
[current-limit])
|
[current-limit])
|
||||||
|
(rn/use-effect
|
||||||
|
#(when input-error (debounce/clear-all))
|
||||||
|
[input-error])
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/screen
|
{:style style/screen
|
||||||
:accessibility-label (str "container"
|
:accessibility-label (str "container"
|
||||||
|
@ -270,22 +289,40 @@
|
||||||
[quo/token-input
|
[quo/token-input
|
||||||
{:container-style style/input-container
|
{:container-style style/input-container
|
||||||
:token token-symbol
|
:token token-symbol
|
||||||
:currency current-currency
|
:currency fiat-currency
|
||||||
:crypto-decimals crypto-decimals
|
:currency-symbol currency-symbol
|
||||||
|
:crypto-decimals (min token-decimals 6)
|
||||||
:error? (controlled-input/input-error input-state)
|
:error? (controlled-input/input-error input-state)
|
||||||
:networks (seq send-enabled-networks)
|
:networks (seq send-enabled-networks)
|
||||||
:title (i18n/label :t/send-limit
|
:title (i18n/label
|
||||||
{:limit (make-limit-label current-limit current-currency)})
|
: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
|
:conversion conversion-rate
|
||||||
:show-keyboard? false
|
:show-keyboard? false
|
||||||
:value (controlled-input/input-value input-state)
|
:value input-amount
|
||||||
:on-swap #(reset! crypto-currency? %)
|
:on-swap (fn [swap-to-crypto-currency?]
|
||||||
|
(set-just-toggled-mode? true)
|
||||||
|
(reset! 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}]
|
:on-token-press show-select-asset-sheet}]
|
||||||
[routes/view
|
[routes/view
|
||||||
{:token token
|
{:token token
|
||||||
:input-value (controlled-input/input-value input-state)
|
:input-value input-amount
|
||||||
|
:value amount
|
||||||
:valid-input? valid-input?
|
:valid-input? valid-input?
|
||||||
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
||||||
|
:lock-fetch-routes? just-toggled-mode?
|
||||||
:current-screen-id current-screen-id}]
|
:current-screen-id current-screen-id}]
|
||||||
(when (and (not loading-routes?)
|
(when (and (not loading-routes?)
|
||||||
sender-network-values
|
sender-network-values
|
||||||
|
@ -314,9 +351,15 @@
|
||||||
{:disabled? (and (not should-try-again?) confirm-disabled?)
|
{:disabled? (and (not should-try-again?) confirm-disabled?)
|
||||||
:on-press (cond
|
:on-press (cond
|
||||||
should-try-again?
|
should-try-again?
|
||||||
#(rf/dispatch [:wallet/get-suggested-routes
|
#(let [input-amount (controlled-input/input-value
|
||||||
{:amount (controlled-input/input-value
|
input-state)
|
||||||
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?
|
sending-to-unpreferred-networks?
|
||||||
#(show-unpreferred-networks-alert on-confirm)
|
#(show-unpreferred-networks-alert on-confirm)
|
||||||
:else
|
:else
|
||||||
|
@ -328,11 +371,22 @@
|
||||||
:left-action :dot
|
:left-action :dot
|
||||||
:delete-key? true
|
:delete-key? true
|
||||||
:on-press (fn [c]
|
:on-press (fn [c]
|
||||||
(when-not loading-routes?
|
(let [new-text (str input-amount c)
|
||||||
(set-input-state #(controlled-input/add-character % 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 []
|
:on-delete (fn []
|
||||||
(when-not loading-routes?
|
(when-not loading-routes?
|
||||||
|
(debounce/clear-all)
|
||||||
|
(set-just-toggled-mode? false)
|
||||||
(set-input-state controlled-input/delete-last)))
|
(set-input-state controlled-input/delete-last)))
|
||||||
:on-long-press-delete (fn []
|
:on-long-press-delete (fn []
|
||||||
(when-not loading-routes?
|
(when-not loading-routes?
|
||||||
|
(debounce/clear-all)
|
||||||
|
(set-just-toggled-mode? false)
|
||||||
(set-input-state controlled-input/delete-all)))}]]))))
|
(set-input-state controlled-input/delete-all)))}]]))))
|
||||||
|
|
|
@ -16,8 +16,8 @@
|
||||||
(def network-link-1x-height 56)
|
(def network-link-1x-height 56)
|
||||||
(def network-link-2x-height 111)
|
(def network-link-2x-height 111)
|
||||||
|
|
||||||
(defn fetch-routes
|
(defn- fetch-routes
|
||||||
[amount valid-input? bounce-duration-ms]
|
[{:keys [amount bounce-duration-ms valid-input?]}]
|
||||||
(if valid-input?
|
(if valid-input?
|
||||||
(debounce/debounce-and-dispatch
|
(debounce/debounce-and-dispatch
|
||||||
[:wallet/get-suggested-routes {:amount amount}]
|
[:wallet/get-suggested-routes {:amount amount}]
|
||||||
|
@ -174,8 +174,8 @@
|
||||||
:text (i18n/label :t/at-least-one-network-must-be-activated)}]))))
|
:text (i18n/label :t/at-least-one-network-must-be-activated)}]))))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [token theme input-value valid-input?
|
[{:keys [token theme input-value value valid-input?
|
||||||
on-press-to-network current-screen-id
|
lock-fetch-routes? on-press-to-network current-screen-id
|
||||||
token-not-supported-in-receiver-networks?]}]
|
token-not-supported-in-receiver-networks?]}]
|
||||||
(let [token-symbol (:symbol token)
|
(let [token-symbol (:symbol token)
|
||||||
nav-current-screen-id (rf/sub [:view-id])
|
nav-current-screen-id (rf/sub [:view-id])
|
||||||
|
@ -198,12 +198,21 @@
|
||||||
:disabled-chain-ids disabled-from-chain-ids})
|
:disabled-chain-ids disabled-from-chain-ids})
|
||||||
show-routes? (not-empty sender-network-values)]
|
show-routes? (not-empty sender-network-values)]
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
#(when (and active-screen? (> (count token-available-networks-for-suggested-routes) 0))
|
(fn []
|
||||||
(fetch-routes input-value valid-input? 2000))
|
(when (and active-screen?
|
||||||
|
(> (count token-available-networks-for-suggested-routes) 0)
|
||||||
|
(not lock-fetch-routes?))
|
||||||
|
(fetch-routes
|
||||||
|
{:amount value
|
||||||
|
:valid-input? valid-input?
|
||||||
|
:bounce-duration-ms 2000})))
|
||||||
[input-value valid-input?])
|
[input-value valid-input?])
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
#(when (and active-screen? (> (count token-available-networks-for-suggested-routes) 0))
|
#(when (and active-screen? (> (count token-available-networks-for-suggested-routes) 0))
|
||||||
(fetch-routes input-value valid-input? 0))
|
(fetch-routes
|
||||||
|
{:amount value
|
||||||
|
:valid-input? valid-input?
|
||||||
|
:bounce-duration-ms 0}))
|
||||||
[disabled-from-chain-ids])
|
[disabled-from-chain-ids])
|
||||||
[rn/scroll-view {:content-container-style style/routes-container}
|
[rn/scroll-view {:content-container-style style/routes-container}
|
||||||
(when show-routes?
|
(when show-routes?
|
||||||
|
@ -238,5 +247,8 @@
|
||||||
:loading-routes? loading-routes?
|
:loading-routes? loading-routes?
|
||||||
:theme theme
|
:theme theme
|
||||||
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
||||||
:on-save #(fetch-routes input-value valid-input? 0)}]]]))
|
:on-save #(fetch-routes
|
||||||
|
{:amount input-value
|
||||||
|
:valid-input? valid-input?
|
||||||
|
:bounce-duration-ms 0})}]]]))
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
:<- [:wallet/wallet-send]
|
:<- [:wallet/wallet-send]
|
||||||
:-> :transaction-ids)
|
:-> :transaction-ids)
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/wallet-send-amount
|
||||||
|
:<- [:wallet/wallet-send]
|
||||||
|
:-> :amount)
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/send-transaction-progress
|
:wallet/send-transaction-progress
|
||||||
:<- [:wallet/send-transaction-ids]
|
:<- [:wallet/send-transaction-ids]
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
(ns utils.number)
|
(ns utils.number
|
||||||
|
(:require [clojure.string :as string]))
|
||||||
|
|
||||||
(defn naive-round
|
(defn naive-round
|
||||||
"Quickly and naively round number `n` up to `decimal-places`.
|
"Quickly and naively round number `n` up to `decimal-places`.
|
||||||
|
@ -29,3 +30,13 @@
|
||||||
if `num` exceeds a given bound, then returns the bound exceeded."
|
if `num` exceeds a given bound, then returns the bound exceeded."
|
||||||
[number lower-bound upper-bound]
|
[number lower-bound upper-bound]
|
||||||
(max lower-bound (min number upper-bound)))
|
(max lower-bound (min number upper-bound)))
|
||||||
|
|
||||||
|
(defn remove-trailing-zeroes
|
||||||
|
[num]
|
||||||
|
(let [parts (string/split (str num) #"\.")]
|
||||||
|
(str (first parts)
|
||||||
|
(if-let [decimals (second parts)]
|
||||||
|
(if (seq (string/replace decimals #"0+$" ""))
|
||||||
|
(str "." (string/replace decimals #"0+$" ""))
|
||||||
|
"")
|
||||||
|
""))))
|
||||||
|
|
Loading…
Reference in New Issue