token input refactoring (#21136)
This commit is contained in:
parent
2161c2e433
commit
40f98f8238
|
@ -1485,7 +1485,7 @@ SPEC CHECKSUMS:
|
|||
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
|
||||
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
|
||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||
glog: c5d68082e772fa1c511173d6b30a9de2c05a69a2
|
||||
glog: 36c15c01d70ed395c6e4f3619f98a23ee415b07a
|
||||
hermes-engine: 1d1835b2cc54c381909d94d1b3c8e0a2f1a94a0e
|
||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||
|
|
|
@ -6,16 +6,20 @@
|
|||
(h/describe "Wallet: Token Input"
|
||||
(h/test "Token label renders"
|
||||
(h/render-with-theme-provider [token-input/view
|
||||
{:token :snt
|
||||
:currency :eur
|
||||
:crypto? true
|
||||
:conversion 1}])
|
||||
{:token-symbol :snt
|
||||
:currency-symbol :snt
|
||||
:on-swap nil
|
||||
:error? false
|
||||
:value "1"
|
||||
:converted-value "10"}])
|
||||
(h/is-truthy (h/get-by-text "SNT")))
|
||||
|
||||
(h/test "Amount renders"
|
||||
(h/render-with-theme-provider [token-input/view
|
||||
{:token :snt
|
||||
:currency :eur
|
||||
:converted-value "€0.00"
|
||||
:conversion 1}])
|
||||
{:token-symbol :snt
|
||||
:currency-symbol :snt
|
||||
:on-swap nil
|
||||
:error? false
|
||||
:value "1"
|
||||
:converted-value "€0.00"}])
|
||||
(h/is-truthy (h/get-by-text "€0.00"))))
|
||||
|
|
|
@ -4,15 +4,14 @@
|
|||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map
|
||||
[:token {:optional true} [:maybe [:or :string :keyword]]]
|
||||
[:currency {:optional true} [:maybe [:or :string :keyword]]]
|
||||
[:error? {:optional true} [:maybe :boolean]]
|
||||
[:title {:optional true} [:maybe :string]]
|
||||
[:conversion {:optional true} [:maybe :double]]
|
||||
[:show-keyboard? {:optional true} [:maybe :boolean]]
|
||||
[:networks {:optional true}
|
||||
[:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:value {:optional true} [:maybe :string]]]]]
|
||||
[:map {:closed true}
|
||||
[:token-symbol [:maybe [:or :string :keyword]]]
|
||||
[:currency-symbol [:maybe [:or :string :keyword]]]
|
||||
[:hint-component {:optional true} [:maybe :schema.common/hiccup]]
|
||||
[:on-token-press {:optional true} [:maybe fn?]]
|
||||
[:on-swap [:maybe fn?]]
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
[:error? [:maybe :boolean]]
|
||||
[:value [:maybe :string]]
|
||||
[:converted-value [:maybe :string]]]]]
|
||||
:any])
|
||||
|
|
|
@ -27,7 +27,9 @@
|
|||
[window-width]
|
||||
{:width (- window-width 120)
|
||||
:margin-left 8
|
||||
:margin-right 8})
|
||||
:margin-right 8
|
||||
:flex-direction :row
|
||||
:align-items :flex-end})
|
||||
|
||||
(def text-input-dimensions
|
||||
(-> typography/heading-1
|
||||
|
@ -65,6 +67,6 @@
|
|||
:justify-content :space-between
|
||||
:align-items :center})
|
||||
|
||||
(defn fiat-amount
|
||||
(defn converted-amount
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
(ns quo.components.wallet.token-input.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[oops.core :as oops]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[quo.components.wallet.token-input.schema :as component-schema]
|
||||
[quo.components.wallet.token-input.style :as style]
|
||||
|
@ -13,19 +11,6 @@
|
|||
[react-native.core :as rn]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- data-info
|
||||
[{:keys [theme networks title converted-value error?]}]
|
||||
[rn/view {:style style/data-container}
|
||||
[network-tag/view
|
||||
{:networks networks
|
||||
:title title
|
||||
:status (when error? :error)}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/fiat-amount theme)}
|
||||
converted-value]])
|
||||
|
||||
(defn- token-name-text
|
||||
[theme text]
|
||||
[text/text
|
||||
|
@ -35,28 +20,7 @@
|
|||
(string/upper-case (or (clj->js text) ""))])
|
||||
|
||||
(defn input-section
|
||||
[{:keys [on-change-text value value-internal set-value-internal on-selection-change
|
||||
on-token-press]}]
|
||||
(let [input-ref (atom nil)
|
||||
set-ref #(reset! input-ref %)
|
||||
focus-input #(when-let [ref ^js @input-ref]
|
||||
(.focus ref))
|
||||
controlled-input? (some? value)
|
||||
handle-on-change-text (fn [v]
|
||||
(when-not controlled-input?
|
||||
(set-value-internal v))
|
||||
(when on-change-text
|
||||
(on-change-text v)))
|
||||
handle-selection-change (fn [^js e]
|
||||
(when on-selection-change
|
||||
(-> e
|
||||
(oops/oget "nativeEvent.selection")
|
||||
(js->clj :keywordize-keys true)
|
||||
(on-selection-change))))]
|
||||
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection
|
||||
handle-on-swap allow-selection?]
|
||||
:or {show-keyboard? true
|
||||
allow-selection? true}}]
|
||||
[{:keys [token-symbol on-token-press value error? on-swap currency-symbol]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
window-width (:width (rn/get-window))]
|
||||
[rn/pressable
|
||||
|
@ -64,56 +28,55 @@
|
|||
:flex-direction :row}
|
||||
:on-press on-token-press}
|
||||
[token/view
|
||||
{:token token
|
||||
{:token token-symbol
|
||||
:size :size-32}]
|
||||
[rn/view {:style (style/input-container window-width)}
|
||||
[rn/pressable
|
||||
{:style style/text-input-container
|
||||
:on-press focus-input}
|
||||
[rn/text-input
|
||||
(cond-> {:style (style/text-input theme error?)
|
||||
{:style (style/text-input theme error?)
|
||||
:placeholder-text-color (style/placeholder-text theme)
|
||||
:auto-focus true
|
||||
:ref set-ref
|
||||
:placeholder "0"
|
||||
:keyboard-type :numeric
|
||||
:on-change-text handle-on-change-text
|
||||
:selection-color customization-color
|
||||
:show-soft-input-on-focus show-keyboard?
|
||||
:on-selection-change handle-selection-change
|
||||
:selection (clj->js selection)
|
||||
:editable allow-selection?}
|
||||
controlled-input? (assoc :value value)
|
||||
(not controlled-input?) (assoc :default-value value-internal))]
|
||||
[token-name-text theme (if crypto? token currency)]]]
|
||||
:editable false
|
||||
:value value}]
|
||||
[token-name-text theme currency-symbol]]
|
||||
[button/button
|
||||
{:icon true
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press handle-on-swap
|
||||
:on-press #(when on-swap (on-swap))
|
||||
:type :outline
|
||||
:accessibility-label :reorder}
|
||||
:i/reorder]]))))
|
||||
:i/reorder]]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [container-style on-swap crypto?] :as props}]
|
||||
[{:keys [token-symbol
|
||||
value
|
||||
on-token-press
|
||||
error?
|
||||
container-style
|
||||
on-swap
|
||||
converted-value
|
||||
hint-component
|
||||
currency-symbol]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
width (:width (rn/get-window))
|
||||
[value-internal set-value-internal] (rn/use-state nil)
|
||||
handle-on-swap (rn/use-callback
|
||||
(fn []
|
||||
(when on-swap (on-swap (not crypto?))))
|
||||
[on-swap])]
|
||||
width (:width (rn/get-window))]
|
||||
[rn/view {:style (merge (style/main-container width) container-style)}
|
||||
[rn/view {:style style/amount-container}
|
||||
[input-section
|
||||
(assoc props
|
||||
:value-internal value-internal
|
||||
:theme theme
|
||||
:set-value-internal set-value-internal
|
||||
:handle-on-swap handle-on-swap
|
||||
:crypto? crypto?)]]
|
||||
{:theme theme
|
||||
:token-symbol token-symbol
|
||||
:on-token-press on-token-press
|
||||
:value value
|
||||
:error? error?
|
||||
:on-swap on-swap
|
||||
:currency-symbol currency-symbol}]]
|
||||
[divider-line/view {:container-style (style/divider theme)}]
|
||||
[data-info (assoc props :theme theme)]]))
|
||||
[rn/view {:style style/data-container}
|
||||
hint-component
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/converted-amount theme)}
|
||||
converted-value]]]))
|
||||
|
||||
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
(ns status-im.common.controlled-input.utils
|
||||
(:require
|
||||
[clojure.string :as string]))
|
||||
[clojure.string :as string]
|
||||
[status-im.contexts.wallet.common.utils :as wallet-utils]
|
||||
[utils.money :as money]))
|
||||
|
||||
(def init-state
|
||||
{:value ""
|
||||
|
@ -14,7 +16,7 @@
|
|||
|
||||
(defn numeric-value
|
||||
[state]
|
||||
(or (parse-double (input-value state)) 0))
|
||||
(money/bignumber (input-value state)))
|
||||
|
||||
(defn input-error
|
||||
[state]
|
||||
|
@ -26,23 +28,27 @@
|
|||
|
||||
(defn upper-limit
|
||||
[state]
|
||||
(:upper-limit state))
|
||||
(money/bignumber (:upper-limit state)))
|
||||
|
||||
(defn lower-limit
|
||||
[state]
|
||||
(:lower-limit state))
|
||||
(money/bignumber (:lower-limit state)))
|
||||
|
||||
(defn upper-limit-exceeded?
|
||||
[state]
|
||||
(let [num-value (numeric-value state)]
|
||||
(and
|
||||
(upper-limit state)
|
||||
(> (numeric-value state) (upper-limit state))))
|
||||
(when (money/bignumber? num-value)
|
||||
(money/greater-than (numeric-value state) (upper-limit state))))))
|
||||
|
||||
(defn lower-limit-exceeded?
|
||||
(defn- lower-limit-exceeded?
|
||||
[state]
|
||||
(let [num-value (numeric-value state)]
|
||||
(and
|
||||
(lower-limit state)
|
||||
(< (numeric-value state) (lower-limit state))))
|
||||
(when (money/bignumber? num-value)
|
||||
(money/less-than (numeric-value state) (lower-limit state))))))
|
||||
|
||||
(defn- recheck-errorness
|
||||
[state]
|
||||
|
@ -75,13 +81,11 @@
|
|||
|
||||
(defn increase
|
||||
[state]
|
||||
(let [new-val (inc (numeric-value state))]
|
||||
(set-input-value state (str new-val))))
|
||||
(set-input-value state (str (money/add (numeric-value state) 1))))
|
||||
|
||||
(defn decrease
|
||||
[state]
|
||||
(let [new-val (dec (numeric-value state))]
|
||||
(set-input-value state (str new-val))))
|
||||
(set-input-value state (str (money/add (numeric-value state) -1))))
|
||||
|
||||
(def ^:private not-digits-or-dot-pattern
|
||||
#"[^0-9+\.]")
|
||||
|
@ -130,3 +134,29 @@
|
|||
(defn empty-value?
|
||||
[state]
|
||||
(string/blank? (:value state)))
|
||||
|
||||
(defn- fiat->crypto
|
||||
[value conversion-rate]
|
||||
(-> value
|
||||
(money/fiat->crypto conversion-rate)
|
||||
(wallet-utils/cut-crypto-decimals-to-fit-usd-cents conversion-rate)))
|
||||
|
||||
(defn- crypto->fiat
|
||||
[value conversion-rate]
|
||||
(-> value
|
||||
(money/crypto->fiat conversion-rate)
|
||||
(wallet-utils/cut-fiat-balance-to-two-decimals)))
|
||||
|
||||
(defn ->crypto
|
||||
[state conversion-rate]
|
||||
(-> state
|
||||
(set-input-value (fiat->crypto (input-value state) conversion-rate))
|
||||
(set-upper-limit (fiat->crypto (upper-limit state) conversion-rate))
|
||||
(set-lower-limit (fiat->crypto (lower-limit state) conversion-rate))))
|
||||
|
||||
(defn ->fiat
|
||||
[state conversion-rate]
|
||||
(-> state
|
||||
(set-input-value (crypto->fiat (input-value state) conversion-rate))
|
||||
(set-upper-limit (crypto->fiat (upper-limit state) conversion-rate))
|
||||
(set-lower-limit (crypto->fiat (lower-limit state) conversion-rate))))
|
||||
|
|
|
@ -8,8 +8,7 @@
|
|||
[status-im.common.controlled-input.utils :as controlled-input]
|
||||
[status-im.contexts.preview.quo.preview :as preview]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[utils.money :as money]
|
||||
[utils.number :as number]))
|
||||
[utils.money :as money]))
|
||||
|
||||
(def networks
|
||||
[{:source (resources/get-network :arbitrum)}
|
||||
|
@ -17,9 +16,10 @@
|
|||
{:source (resources/get-network :ethereum)}])
|
||||
|
||||
(def title "Max: 200 SNT")
|
||||
(def conversion-rate 3450.28)
|
||||
|
||||
(def descriptor
|
||||
[{:key :token
|
||||
[{:key :token-symbol
|
||||
:type :select
|
||||
:options [{:key :eth}
|
||||
{:key :snt}]}
|
||||
|
@ -28,49 +28,37 @@
|
|||
:options [{:key "$"}
|
||||
{:key "€"}]}
|
||||
{:key :error?
|
||||
:type :boolean}
|
||||
{:key :allow-selection?
|
||||
:type :boolean}])
|
||||
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:token :eth
|
||||
(let [state (reagent/atom {:token-symbol :eth
|
||||
:currency "$"
|
||||
:conversion-rate 3450.28
|
||||
:networks networks
|
||||
:title title
|
||||
:customization-color :blue
|
||||
:show-keyboard? false
|
||||
:allow-selection? true
|
||||
:crypto? true})]
|
||||
:crypto? true
|
||||
:error? false})]
|
||||
(fn []
|
||||
(let [{:keys [currency token conversion-rate
|
||||
crypto?]} @state
|
||||
(let [{:keys [currency token-symbol crypto? error?]} @state
|
||||
[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
||||
input-amount (controlled-input/input-value input-state)
|
||||
swap-between-fiat-and-crypto (fn []
|
||||
(set-input-state
|
||||
(fn [input-state]
|
||||
(controlled-input/set-input-value
|
||||
input-state
|
||||
(let [new-value
|
||||
(if-not crypto?
|
||||
(utils/cut-crypto-decimals-to-fit-usd-cents
|
||||
conversion-rate
|
||||
(money/fiat->crypto input-amount
|
||||
(if crypto?
|
||||
(set-input-state #(controlled-input/->fiat
|
||||
%
|
||||
conversion-rate))
|
||||
(utils/cut-fiat-balance-to-two-decimals
|
||||
(money/crypto->fiat input-amount
|
||||
conversion-rate)))]
|
||||
(number/remove-trailing-zeroes
|
||||
new-value))))))
|
||||
(set-input-state
|
||||
#(controlled-input/->crypto
|
||||
%
|
||||
conversion-rate))))
|
||||
converted-value (if crypto?
|
||||
(utils/prettify-balance currency
|
||||
(money/crypto->fiat input-amount
|
||||
(money/crypto->fiat
|
||||
input-amount
|
||||
conversion-rate))
|
||||
(utils/prettify-crypto-balance
|
||||
(or (clj->js token) "")
|
||||
(money/fiat->crypto input-amount conversion-rate)
|
||||
(or (clj->js token-symbol) "")
|
||||
(money/fiat->crypto input-amount
|
||||
conversion-rate)
|
||||
conversion-rate))]
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
|
@ -79,12 +67,18 @@
|
|||
:component-container-style {:flex 1
|
||||
:justify-content :space-between}}
|
||||
[quo/token-input
|
||||
(merge @state
|
||||
{:value input-amount
|
||||
{:token-symbol token-symbol
|
||||
:currency-symbol (if crypto? token-symbol currency)
|
||||
:error? error?
|
||||
:value input-amount
|
||||
:converted-value converted-value
|
||||
:on-swap (fn [crypto]
|
||||
(swap! state assoc :crypto? crypto)
|
||||
(swap-between-fiat-and-crypto))})]
|
||||
:on-swap (fn []
|
||||
(swap! state assoc :crypto? (not crypto?))
|
||||
(swap-between-fiat-and-crypto))
|
||||
:hint-component [quo/network-tags
|
||||
{:networks networks
|
||||
:title title
|
||||
:status (when (:error? @state) :error)}]}]
|
||||
[quo/numbered-keyboard
|
||||
{:container-style {:padding-bottom (safe-area/get-top)}
|
||||
:left-action :dot
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
(calc-max-crypto-decimals cent-value))})))
|
||||
|
||||
(defn cut-crypto-decimals-to-fit-usd-cents
|
||||
[token-price-in-usd token-units]
|
||||
[token-units token-price-in-usd]
|
||||
(let [{:keys [zero-value? usd-cent-value standardized-decimals-count]}
|
||||
(analyze-token-amount-for-price token-price-in-usd token-units)]
|
||||
(cond
|
||||
|
@ -99,7 +99,7 @@
|
|||
|
||||
(defn prettify-crypto-balance
|
||||
[token-symbol crypto-balance conversion-rate]
|
||||
(str (cut-crypto-decimals-to-fit-usd-cents conversion-rate crypto-balance)
|
||||
(str (cut-crypto-decimals-to-fit-usd-cents crypto-balance conversion-rate)
|
||||
" "
|
||||
(string/upper-case token-symbol)))
|
||||
|
||||
|
@ -323,18 +323,6 @@
|
|||
(let [counter (count address)]
|
||||
(str (subs address 0 6) "\u2026" (subs address (- counter 3) counter)))))
|
||||
|
||||
(defn make-limit-label-crypto
|
||||
[amount currency]
|
||||
(str amount
|
||||
" "
|
||||
(some-> currency
|
||||
name
|
||||
string/upper-case)))
|
||||
|
||||
(defn make-limit-label-fiat
|
||||
[amount currency-symbol]
|
||||
(str currency-symbol amount))
|
||||
|
||||
(defn get-account-name-error
|
||||
[s existing-account-names]
|
||||
(cond
|
||||
|
|
|
@ -110,7 +110,7 @@
|
|||
(h/setup-subs sub-mocks)
|
||||
(h/render-with-theme-provider [input-amount/view
|
||||
{:crypto-decimals 2
|
||||
:limit-crypto 250
|
||||
:limit-crypto (money/bignumber 250)
|
||||
:initial-crypto-currency? false}])
|
||||
(h/is-truthy (h/get-by-text "0"))
|
||||
(h/is-truthy (h/get-by-text "USD"))
|
||||
|
@ -124,7 +124,7 @@
|
|||
(let [on-confirm (h/mock-fn)]
|
||||
(h/render-with-theme-provider [input-amount/view
|
||||
{:crypto-decimals 10
|
||||
:limit-crypto 1000
|
||||
:limit-crypto (money/bignumber 1000)
|
||||
:on-confirm on-confirm
|
||||
:initial-crypto-currency? true}])
|
||||
|
||||
|
@ -135,18 +135,19 @@
|
|||
(h/fire-event :press (h/query-by-label-text :keyboard-key-4))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||
|
||||
|
||||
(-> (h/wait-for #(h/get-by-text "$1234.50"))
|
||||
(.then (fn []
|
||||
(h/is-truthy (h/get-by-label-text :button-one))
|
||||
(h/is-truthy (h/get-by-label-text :container))
|
||||
(h/fire-event :press (h/get-by-label-text :button-one))
|
||||
(h/was-called on-confirm))))))
|
||||
(let [btn (h/get-by-label-text :button-one)]
|
||||
(h/is-truthy btn)
|
||||
(h/fire-event :press btn)
|
||||
(h/was-called on-confirm)))))))
|
||||
|
||||
(h/test "Try to fill more than limit"
|
||||
(h/setup-subs sub-mocks)
|
||||
(h/render-with-theme-provider [input-amount/view
|
||||
{:crypto-decimals 1
|
||||
:limit-crypto 1}])
|
||||
:limit-crypto (money/bignumber 1)}])
|
||||
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||
|
@ -158,13 +159,12 @@
|
|||
(h/setup-subs sub-mocks)
|
||||
(h/render-with-theme-provider [input-amount/view
|
||||
{:crypto-decimals 1
|
||||
:limit-crypto 1
|
||||
:limit-crypto (money/bignumber 10)
|
||||
:on-confirm #()}])
|
||||
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||
(h/is-truthy (h/get-by-label-text :container-error))
|
||||
(h/fire-event :press (h/query-by-label-text :reorder))
|
||||
(h/is-truthy #(h/get-by-text "Max: $100.00"))))
|
||||
|
||||
(-> (h/wait-for #(h/get-by-text "Max: $1000.00"))
|
||||
(.then (fn []
|
||||
(h/wait-for #(h/is-truthy (h/get-by-label-text :container))))))))
|
||||
|
|
|
@ -153,9 +153,8 @@
|
|||
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 [amount]
|
||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||
{:amount amount
|
||||
|
@ -167,11 +166,9 @@
|
|||
token} (rf/sub [:wallet/wallet-send-token])
|
||||
send-from-locked-amounts (rf/sub [:wallet/wallet-send-from-locked-amounts])
|
||||
{token-balance :total-balance
|
||||
available-balance :available-balance
|
||||
:as token-by-symbol} (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
|
||||
|
@ -181,48 +178,29 @@
|
|||
utils/token-usd-price
|
||||
utils/one-cent-value
|
||||
utils/calc-max-crypto-decimals)
|
||||
[input-state set-input-state] (rn/use-state
|
||||
(-> controlled-input/init-state
|
||||
(controlled-input/set-upper-limit
|
||||
(utils/cut-crypto-decimals-to-fit-usd-cents
|
||||
(or default-limit-crypto token-balance)
|
||||
conversion-rate))))
|
||||
clear-input! #(set-input-state controlled-input/delete-all)
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
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)
|
||||
input-value (controlled-input/input-value input-state)
|
||||
valid-input? (not (or (controlled-input/empty-value? input-state)
|
||||
(controlled-input/input-error 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))
|
||||
(not valid-input?))
|
||||
amount-in-crypto (if crypto-currency?
|
||||
input-amount
|
||||
input-value
|
||||
(number/remove-trailing-zeroes
|
||||
(.toFixed (/ input-amount conversion-rate)
|
||||
(.toFixed (/ input-value conversion-rate)
|
||||
crypto-decimals)))
|
||||
total-amount-receiver (rf/sub [:wallet/total-amount true])
|
||||
amount-text (str (number/remove-trailing-zeroes
|
||||
|
@ -270,8 +248,7 @@
|
|||
receiver-selected-network))
|
||||
receiver-networks))
|
||||
input-error (controlled-input/input-error input-state)
|
||||
limit-insufficient? (> (controlled-input/numeric-value input-state)
|
||||
current-limit)
|
||||
limit-insufficient? (controlled-input/upper-limit-exceeded? input-state)
|
||||
should-try-again? (and (not limit-insufficient?) no-routes-found?)
|
||||
current-address (rf/sub [:wallet/current-viewing-account-address])
|
||||
owned-eth-token (rf/sub [:wallet/token-by-symbol
|
||||
|
@ -284,7 +261,9 @@
|
|||
(if (= token-symbol
|
||||
(string/upper-case
|
||||
constants/mainnet-short-name))
|
||||
(= current-limit input-amount)
|
||||
(money/equal-to
|
||||
(controlled-input/numeric-value input-state)
|
||||
(controlled-input/upper-limit input-state))
|
||||
(money/equal-to (:total-balance
|
||||
owned-eth-token)
|
||||
0)))
|
||||
|
@ -298,38 +277,20 @@
|
|||
:valid-input? valid-input?
|
||||
:bounce-duration-ms bounce-duration-ms
|
||||
:token token}))
|
||||
swap-currency (fn [to-crypto? value]
|
||||
(if to-crypto?
|
||||
(utils/cut-crypto-decimals-to-fit-usd-cents
|
||||
conversion-rate
|
||||
(money/fiat->crypto value conversion-rate))
|
||||
(utils/cut-fiat-balance-to-two-decimals
|
||||
(money/crypto->fiat value
|
||||
conversion-rate))))
|
||||
swap-between-fiat-and-crypto (fn [swap-to-crypto-currency?]
|
||||
swap-between-fiat-and-crypto (fn []
|
||||
(set-just-toggled-mode? true)
|
||||
(set-crypto-currency swap-to-crypto-currency?)
|
||||
(if 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 (swap-currency
|
||||
swap-to-crypto-currency?
|
||||
value)]
|
||||
(number/remove-trailing-zeroes
|
||||
new-value))))))]
|
||||
#(controlled-input/->fiat % conversion-rate))
|
||||
(set-input-state
|
||||
#(controlled-input/->crypto % conversion-rate)))
|
||||
(set-crypto-currency (not crypto-currency?)))]
|
||||
(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))))
|
||||
(hot-reload/use-safe-unmount on-navigate-back)
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(set-input-state #(controlled-input/set-upper-limit % current-limit)))
|
||||
[current-limit])
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when input-error (debounce/clear-all))
|
||||
|
@ -354,34 +315,35 @@
|
|||
: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 from-enabled-networks)
|
||||
:title (i18n/label
|
||||
:t/send-limit
|
||||
{:limit (if crypto-currency?
|
||||
(utils/make-limit-label-crypto current-limit token-symbol)
|
||||
(utils/make-limit-label-fiat current-limit currency-symbol))})
|
||||
:conversion conversion-rate
|
||||
:show-keyboard? false
|
||||
:value input-amount
|
||||
:token-symbol token-symbol
|
||||
:value input-value
|
||||
:on-swap swap-between-fiat-and-crypto
|
||||
:on-token-press show-select-asset-sheet
|
||||
:allow-selection? false
|
||||
:crypto? crypto-currency?
|
||||
:error? (controlled-input/input-error input-state)
|
||||
:currency-symbol (if crypto-currency? token-symbol fiat-currency)
|
||||
:converted-value (if crypto-currency?
|
||||
(utils/prettify-balance
|
||||
currency-symbol
|
||||
(money/crypto->fiat input-amount
|
||||
(money/crypto->fiat input-value
|
||||
conversion-rate))
|
||||
(utils/prettify-crypto-balance
|
||||
(or (clj->js token-symbol) "")
|
||||
(money/fiat->crypto input-amount
|
||||
(money/fiat->crypto input-value
|
||||
conversion-rate)
|
||||
conversion-rate))}]
|
||||
conversion-rate))
|
||||
:hint-component [quo/network-tags
|
||||
{:networks (seq from-enabled-networks)
|
||||
:title (i18n/label
|
||||
:t/send-limit
|
||||
{:limit (if crypto-currency?
|
||||
(utils/prettify-crypto-balance
|
||||
(or (clj->js token-symbol) "")
|
||||
(controlled-input/upper-limit input-state)
|
||||
conversion-rate)
|
||||
(utils/prettify-balance currency-symbol
|
||||
(controlled-input/upper-limit
|
||||
input-state)))})
|
||||
:status (when (controlled-input/input-error input-state) :error)}]}]
|
||||
[routes/view
|
||||
{:token token-by-symbol
|
||||
:send-amount-in-crypto amount-in-crypto
|
||||
|
@ -426,7 +388,7 @@
|
|||
:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press (fn [c]
|
||||
(let [new-text (str input-amount c)
|
||||
(let [new-text (str input-value c)
|
||||
max-decimals (if crypto-currency? crypto-decimals 2)
|
||||
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
|
||||
regex (re-pattern regex-pattern)]
|
||||
|
|
|
@ -1,19 +1,12 @@
|
|||
(ns status-im.contexts.wallet.send.routes.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[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.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.send.routes.style :as style]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.number :as number]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
|
||||
|
@ -87,7 +80,7 @@
|
|||
(rf/dispatch [:wallet/update-receiver-networks
|
||||
chain-ids]))}]))}]))
|
||||
|
||||
(defn- edit-amount
|
||||
#_(defn- edit-amount
|
||||
[{:keys [chain-id token-symbol send-amount-in-crypto init-amount]}]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
|
@ -106,7 +99,8 @@
|
|||
{account-color :color} (rf/sub [:wallet/current-viewing-account])
|
||||
locked-amount (get send-from-locked-amounts chain-id)
|
||||
network-name-str (string/capitalize (name network-name))
|
||||
[input-state set-input-state] (rn/use-state (cond-> controlled-input/init-state
|
||||
[input-state set-input-state] (rn/use-state
|
||||
(cond-> controlled-input/init-state
|
||||
init-amount
|
||||
(controlled-input/set-input-value
|
||||
(money/to-string init-amount))
|
||||
|
@ -144,16 +138,19 @@
|
|||
send-amount-in-crypto)]
|
||||
(and (money/bignumber? amount)
|
||||
(money/bignumber? send-amount)
|
||||
(money/greater-than amount send-amount)))
|
||||
(money/greater-than amount
|
||||
send-amount)))
|
||||
swap-between-fiat-and-crypto (fn [swap-to-crypto-currency?]
|
||||
(set-crypto-currency swap-to-crypto-currency?)
|
||||
(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
|
||||
new-value
|
||||
(if
|
||||
swap-to-crypto-currency?
|
||||
(.toFixed
|
||||
(/ value
|
||||
|
@ -388,13 +385,6 @@
|
|||
chain-id-to-disable
|
||||
disabled-from-chain-ids
|
||||
token-available-networks-for-suggested-routes))
|
||||
(when (ff/enabled? ::ff/wallet.custom-network-amounts)
|
||||
:on-long-press) (fn [chain-id amount-calculated-for-chain]
|
||||
(edit-amount
|
||||
{:chain-id chain-id
|
||||
:token-symbol token-symbol
|
||||
:send-amount-in-crypto send-amount-in-crypto
|
||||
:init-amount amount-calculated-for-chain}))
|
||||
:receiver? false
|
||||
:theme theme
|
||||
:loading-routes? loading-routes?
|
||||
|
|
|
@ -55,8 +55,9 @@
|
|||
(.lessThan ^js bn1 bn2))
|
||||
|
||||
(defn equal-to
|
||||
[bn1 bn2]
|
||||
(.eq ^js bn1 bn2))
|
||||
[n1 n2]
|
||||
(when-let [^js bn1 (bignumber n1)]
|
||||
(.eq ^js bn1 n2)))
|
||||
|
||||
(extend-type BigNumber
|
||||
IEquiv
|
||||
|
|
Loading…
Reference in New Issue