Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6ac5f77678 | ||
|
|
895a8b9588 | ||
|
|
7076f365ee | ||
|
|
94ab92d931 | ||
|
|
91cb714ea9 | ||
|
|
c7bd607c5a | ||
|
|
f62afdac16 | ||
|
|
41997d9851 | ||
|
|
2ced6095b9 | ||
|
|
ea1b01a352 | ||
|
|
b7d89aa185 | ||
|
|
fb25ccfc6a |
+3
-3
@@ -1115,7 +1115,7 @@ PODS:
|
|||||||
- React-perflogger (= 0.73.5)
|
- React-perflogger (= 0.73.5)
|
||||||
- ReactNativeAudioToolkit (2.0.3):
|
- ReactNativeAudioToolkit (2.0.3):
|
||||||
- React
|
- React
|
||||||
- ReactNativeCameraKit (14.0.0-beta13):
|
- ReactNativeCameraKit (14.0.0-beta15):
|
||||||
- React-Core
|
- React-Core
|
||||||
- ReactNativeNavigation (7.39.0):
|
- ReactNativeNavigation (7.39.0):
|
||||||
- HMSegmentedControl
|
- HMSegmentedControl
|
||||||
@@ -1485,7 +1485,7 @@ SPEC CHECKSUMS:
|
|||||||
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
|
FBLazyVector: 56e0e498dbb513b96c40bac6284729ba4e62672d
|
||||||
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
|
FBReactNativeSpec: 146c741a3f40361f6bc13a4ba284678cbedb5881
|
||||||
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
|
||||||
glog: 530710e7949eb12c82670bd09e946becf50a3c2a
|
glog: 36c15c01d70ed395c6e4f3619f98a23ee415b07a
|
||||||
hermes-engine: 1d1835b2cc54c381909d94d1b3c8e0a2f1a94a0e
|
hermes-engine: 1d1835b2cc54c381909d94d1b3c8e0a2f1a94a0e
|
||||||
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
|
||||||
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
Keycard: ac6df4d91525c3c82635ac24d4ddd9a80aca5fc8
|
||||||
@@ -1551,7 +1551,7 @@ SPEC CHECKSUMS:
|
|||||||
React-utils: 987a4526a2fc0acdfaf87888adfe0bf9d0452066
|
React-utils: 987a4526a2fc0acdfaf87888adfe0bf9d0452066
|
||||||
ReactCommon: 2947b0bffd82ea0e58ca7928881152d4c6dae9af
|
ReactCommon: 2947b0bffd82ea0e58ca7928881152d4c6dae9af
|
||||||
ReactNativeAudioToolkit: de9610f323e855ac6574be8c99621f3d57c5df06
|
ReactNativeAudioToolkit: de9610f323e855ac6574be8c99621f3d57c5df06
|
||||||
ReactNativeCameraKit: d95d3e19c514526a234d9f93c6db7e7f10eef9ea
|
ReactNativeCameraKit: 71343efc1256720184ce980f164c7eedb78d5c16
|
||||||
ReactNativeNavigation: 679d8c8bf3b8ae98d285bce810964d10da85dbdb
|
ReactNativeNavigation: 679d8c8bf3b8ae98d285bce810964d10da85dbdb
|
||||||
RNCAsyncStorage: c913ede1fa163a71cea118ed4670bbaaa4b511bb
|
RNCAsyncStorage: c913ede1fa163a71cea118ed4670bbaaa4b511bb
|
||||||
RNCClipboard: 60fed4b71560d7bfe40e9d35dea9762b024da86d
|
RNCClipboard: 60fed4b71560d7bfe40e9d35dea9762b024da86d
|
||||||
|
|||||||
@@ -6,16 +6,20 @@
|
|||||||
(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-symbol :snt
|
||||||
:currency :eur
|
:currency-symbol :snt
|
||||||
:currency-symbol "€"
|
:on-swap nil
|
||||||
:conversion 1}])
|
:error? false
|
||||||
|
:value "1"
|
||||||
|
:converted-value "10"}])
|
||||||
(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-symbol :snt
|
||||||
:currency :eur
|
:currency-symbol :snt
|
||||||
:currency-symbol "€"
|
:on-swap nil
|
||||||
:conversion 1}])
|
:error? false
|
||||||
|
:value "1"
|
||||||
|
:converted-value "€0.00"}])
|
||||||
(h/is-truthy (h/get-by-text "€0.00"))))
|
(h/is-truthy (h/get-by-text "€0.00"))))
|
||||||
|
|||||||
@@ -4,15 +4,14 @@
|
|||||||
[:=>
|
[:=>
|
||||||
[:catn
|
[:catn
|
||||||
[:props
|
[:props
|
||||||
[:map
|
[:map {:closed true}
|
||||||
[:token {:optional true} [:maybe [:or :string :keyword]]]
|
[:token-symbol [:maybe [:or :string :keyword]]]
|
||||||
[:currency {:optional true} [:maybe [:or :string :keyword]]]
|
[:currency-symbol [:maybe [:or :string :keyword]]]
|
||||||
[:error? {:optional true} [:maybe :boolean]]
|
[:hint-component {:optional true} [:maybe :schema.common/hiccup]]
|
||||||
[:title {:optional true} [:maybe :string]]
|
[:on-token-press {:optional true} [:maybe fn?]]
|
||||||
[:conversion {:optional true} [:maybe :double]]
|
[:on-swap [:maybe fn?]]
|
||||||
[:show-keyboard? {:optional true} [:maybe :boolean]]
|
[:container-style {:optional true} [:maybe :map]]
|
||||||
[:networks {:optional true}
|
[:error? [:maybe :boolean]]
|
||||||
[:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]]
|
[:value [:maybe :string]]
|
||||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
[:converted-value [:maybe :string]]]]]
|
||||||
[:value {:optional true} [:maybe :string]]]]]
|
|
||||||
:any])
|
:any])
|
||||||
|
|||||||
@@ -25,9 +25,11 @@
|
|||||||
|
|
||||||
(defn input-container
|
(defn input-container
|
||||||
[window-width]
|
[window-width]
|
||||||
{:width (- window-width 120)
|
{:width (- window-width 120)
|
||||||
:margin-left 8
|
:margin-left 8
|
||||||
:margin-right 8})
|
:margin-right 8
|
||||||
|
:flex-direction :row
|
||||||
|
:align-items :flex-end})
|
||||||
|
|
||||||
(def text-input-dimensions
|
(def text-input-dimensions
|
||||||
(-> typography/heading-1
|
(-> typography/heading-1
|
||||||
@@ -65,6 +67,6 @@
|
|||||||
:justify-content :space-between
|
:justify-content :space-between
|
||||||
:align-items :center})
|
:align-items :center})
|
||||||
|
|
||||||
(defn fiat-amount
|
(defn converted-amount
|
||||||
[theme]
|
[theme]
|
||||||
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
||||||
|
|||||||
@@ -1,57 +1,15 @@
|
|||||||
(ns quo.components.wallet.token-input.view
|
(ns quo.components.wallet.token-input.view
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[oops.core :as oops]
|
|
||||||
[quo.components.buttons.button.view :as button]
|
[quo.components.buttons.button.view :as button]
|
||||||
[quo.components.dividers.divider-line.view :as divider-line]
|
[quo.components.dividers.divider-line.view :as divider-line]
|
||||||
[quo.components.markdown.text :as text]
|
[quo.components.markdown.text :as text]
|
||||||
[quo.components.tags.network-tags.view :as network-tag]
|
|
||||||
[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.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
|
|
||||||
[currency-symbol num-value conversion]
|
|
||||||
(str currency-symbol (.toFixed (* num-value conversion) 2)))
|
|
||||||
|
|
||||||
(defn crypto-format
|
|
||||||
[num-value conversion crypto-decimals token]
|
|
||||||
(str (number/remove-trailing-zeroes
|
|
||||||
(.toFixed (/ num-value conversion) (or crypto-decimals 2)))
|
|
||||||
" "
|
|
||||||
(string/upper-case (or (clj->js token) ""))))
|
|
||||||
|
|
||||||
(defn calc-value
|
|
||||||
[{:keys [crypto? currency-symbol token value conversion crypto-decimals]}]
|
|
||||||
(let [num-value (if (string? value)
|
|
||||||
(or (parse-double value) 0)
|
|
||||||
value)]
|
|
||||||
(if crypto?
|
|
||||||
(fiat-format currency-symbol num-value conversion)
|
|
||||||
(crypto-format num-value conversion crypto-decimals token))))
|
|
||||||
|
|
||||||
(defn- data-info
|
|
||||||
[{:keys [theme token crypto-decimals conversion networks title crypto? currency-symbol amount
|
|
||||||
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)}
|
|
||||||
(calc-value {:crypto? crypto?
|
|
||||||
:currency-symbol currency-symbol
|
|
||||||
:token token
|
|
||||||
:value amount
|
|
||||||
:conversion conversion
|
|
||||||
:crypto-decimals crypto-decimals})]])
|
|
||||||
|
|
||||||
(defn- token-name-text
|
(defn- token-name-text
|
||||||
[theme text]
|
[theme text]
|
||||||
@@ -62,91 +20,63 @@
|
|||||||
(string/upper-case (or (clj->js text) ""))])
|
(string/upper-case (or (clj->js text) ""))])
|
||||||
|
|
||||||
(defn input-section
|
(defn input-section
|
||||||
[{:keys [on-change-text value value-internal set-value-internal on-selection-change
|
[{:keys [token-symbol on-token-press value error? on-swap currency-symbol]}]
|
||||||
on-token-press]}]
|
(let [theme (quo.theme/use-theme)
|
||||||
(let [input-ref (atom nil)
|
window-width (:width (rn/get-window))]
|
||||||
set-ref #(reset! input-ref %)
|
[rn/pressable
|
||||||
focus-input #(when-let [ref ^js @input-ref]
|
{:style {:width "100%"
|
||||||
(.focus ref))
|
:flex-direction :row}
|
||||||
controlled-input? (some? value)
|
:on-press on-token-press}
|
||||||
handle-on-change-text (fn [v]
|
[token/view
|
||||||
(when-not controlled-input?
|
{:token token-symbol
|
||||||
(set-value-internal v))
|
:size :size-32}]
|
||||||
(when on-change-text
|
[rn/view {:style (style/input-container window-width)}
|
||||||
(on-change-text v)))
|
[rn/text-input
|
||||||
handle-selection-change (fn [^js e]
|
{:style (style/text-input theme error?)
|
||||||
(when on-selection-change
|
:placeholder-text-color (style/placeholder-text theme)
|
||||||
(-> e
|
:placeholder "0"
|
||||||
(oops/oget "nativeEvent.selection")
|
:keyboard-type :numeric
|
||||||
(js->clj :keywordize-keys true)
|
:editable false
|
||||||
(on-selection-change))))]
|
:value value}]
|
||||||
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection
|
[token-name-text theme currency-symbol]]
|
||||||
handle-on-swap allow-selection?]
|
[button/button
|
||||||
:or {show-keyboard? true
|
{:icon true
|
||||||
allow-selection? true}}]
|
:icon-only? true
|
||||||
(let [theme (quo.theme/use-theme)
|
:size 32
|
||||||
window-width (:width (rn/get-window))]
|
:on-press #(when on-swap (on-swap))
|
||||||
[rn/pressable
|
:type :outline
|
||||||
{:style {:width "100%"
|
:accessibility-label :reorder}
|
||||||
:flex-direction :row}
|
:i/reorder]]))
|
||||||
:on-press on-token-press}
|
|
||||||
[token/view
|
|
||||||
{:token token
|
|
||||||
: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?)
|
|
||||||
: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)]]]
|
|
||||||
[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 [token-symbol
|
||||||
(let [theme (quo.theme/use-theme)
|
value
|
||||||
width (:width (rn/get-window))
|
on-token-press
|
||||||
[value-internal set-value-internal] (rn/use-state nil)
|
error?
|
||||||
[crypto? set-crypto] (rn/use-state true)
|
container-style
|
||||||
handle-on-swap (rn/use-callback
|
on-swap
|
||||||
(fn []
|
converted-value
|
||||||
(set-crypto (not crypto?))
|
hint-component
|
||||||
(when on-swap (on-swap (not crypto?))))
|
currency-symbol]}]
|
||||||
[crypto? on-swap])]
|
(let [theme (quo.theme/use-theme)
|
||||||
|
width (:width (rn/get-window))]
|
||||||
[rn/view {:style (merge (style/main-container width) container-style)}
|
[rn/view {:style (merge (style/main-container width) container-style)}
|
||||||
[rn/view {:style style/amount-container}
|
[rn/view {:style style/amount-container}
|
||||||
[input-section
|
[input-section
|
||||||
(assoc props
|
{:theme theme
|
||||||
:value-internal value-internal
|
:token-symbol token-symbol
|
||||||
:theme theme
|
:on-token-press on-token-press
|
||||||
:set-value-internal set-value-internal
|
:value value
|
||||||
:handle-on-swap handle-on-swap
|
:error? error?
|
||||||
:crypto? crypto?)]]
|
:on-swap on-swap
|
||||||
|
:currency-symbol currency-symbol}]]
|
||||||
[divider-line/view {:container-style (style/divider theme)}]
|
[divider-line/view {:container-style (style/divider theme)}]
|
||||||
[data-info
|
[rn/view {:style style/data-container}
|
||||||
(assoc props
|
hint-component
|
||||||
:theme theme
|
[text/text
|
||||||
:crypto? crypto?
|
{:size :paragraph-2
|
||||||
:amount (or value value-internal))]]))
|
:weight :medium
|
||||||
|
:style (style/converted-amount theme)}
|
||||||
|
converted-value]]]))
|
||||||
|
|
||||||
(def view (schema/instrument #'view-internal component-schema/?schema))
|
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
(ns status-im.common.controlled-input.utils
|
(ns status-im.common.controlled-input.utils
|
||||||
(:require
|
(: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
|
(def init-state
|
||||||
{:value ""
|
{:value ""
|
||||||
@@ -14,7 +16,7 @@
|
|||||||
|
|
||||||
(defn numeric-value
|
(defn numeric-value
|
||||||
[state]
|
[state]
|
||||||
(or (parse-double (input-value state)) 0))
|
(money/bignumber (input-value state)))
|
||||||
|
|
||||||
(defn input-error
|
(defn input-error
|
||||||
[state]
|
[state]
|
||||||
@@ -26,23 +28,29 @@
|
|||||||
|
|
||||||
(defn upper-limit
|
(defn upper-limit
|
||||||
[state]
|
[state]
|
||||||
(:upper-limit state))
|
(money/bignumber (:upper-limit state)))
|
||||||
|
|
||||||
(defn lower-limit
|
(defn lower-limit
|
||||||
[state]
|
[state]
|
||||||
(:lower-limit state))
|
(money/bignumber (:lower-limit state)))
|
||||||
|
|
||||||
(defn upper-limit-exceeded?
|
(defn upper-limit-exceeded?
|
||||||
[state]
|
[state]
|
||||||
(and
|
(let [num-value (numeric-value state)]
|
||||||
(upper-limit state)
|
(and
|
||||||
(> (numeric-value state) (upper-limit state))))
|
(upper-limit state)
|
||||||
|
(if (money/bignumber? num-value)
|
||||||
|
(money/greater-than (numeric-value state) (upper-limit state))
|
||||||
|
false))))
|
||||||
|
|
||||||
(defn lower-limit-exceeded?
|
(defn- lower-limit-exceeded?
|
||||||
[state]
|
[state]
|
||||||
(and
|
(let [num-value (numeric-value state)]
|
||||||
(lower-limit state)
|
(and
|
||||||
(< (numeric-value state) (lower-limit state))))
|
(lower-limit state)
|
||||||
|
(if (money/bignumber? num-value)
|
||||||
|
(money/less-than (numeric-value state) (lower-limit state))
|
||||||
|
false))))
|
||||||
|
|
||||||
(defn- recheck-errorness
|
(defn- recheck-errorness
|
||||||
[state]
|
[state]
|
||||||
@@ -75,13 +83,11 @@
|
|||||||
|
|
||||||
(defn increase
|
(defn increase
|
||||||
[state]
|
[state]
|
||||||
(let [new-val (inc (numeric-value state))]
|
(set-input-value state (str (money/add (numeric-value state) 1))))
|
||||||
(set-input-value state (str new-val))))
|
|
||||||
|
|
||||||
(defn decrease
|
(defn decrease
|
||||||
[state]
|
[state]
|
||||||
(let [new-val (dec (numeric-value state))]
|
(set-input-value state (str (money/add (numeric-value state) -1))))
|
||||||
(set-input-value state (str new-val))))
|
|
||||||
|
|
||||||
(def ^:private not-digits-or-dot-pattern
|
(def ^:private not-digits-or-dot-pattern
|
||||||
#"[^0-9+\.]")
|
#"[^0-9+\.]")
|
||||||
@@ -130,3 +136,29 @@
|
|||||||
(defn empty-value?
|
(defn empty-value?
|
||||||
[state]
|
[state]
|
||||||
(string/blank? (: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))))
|
||||||
|
|||||||
@@ -2,9 +2,13 @@
|
|||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.resources :as resources]
|
[quo.foundations.resources :as resources]
|
||||||
|
[react-native.core :as rn]
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
[status-im.contexts.preview.quo.preview :as preview]))
|
[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]))
|
||||||
|
|
||||||
(def networks
|
(def networks
|
||||||
[{:source (resources/get-network :arbitrum)}
|
[{:source (resources/get-network :arbitrum)}
|
||||||
@@ -12,47 +16,75 @@
|
|||||||
{:source (resources/get-network :ethereum)}])
|
{:source (resources/get-network :ethereum)}])
|
||||||
|
|
||||||
(def title "Max: 200 SNT")
|
(def title "Max: 200 SNT")
|
||||||
|
(def conversion-rate 3450.28)
|
||||||
|
|
||||||
(def descriptor
|
(def descriptor
|
||||||
[{:key :token
|
[{:key :token-symbol
|
||||||
:type :select
|
:type :select
|
||||||
:options [{:key :eth}
|
:options [{:key :eth}
|
||||||
{:key :snt}]}
|
{:key :snt}]}
|
||||||
{:key :currency
|
{:key :currency
|
||||||
:type :select
|
:type :select
|
||||||
:options [{:key :usd}
|
:options [{:key "$"}
|
||||||
{:key :eur}]}
|
{:key "€"}]}
|
||||||
{:key :error?
|
{:key :error?
|
||||||
:type :boolean}
|
|
||||||
{:key :allow-selection?
|
|
||||||
:type :boolean}])
|
:type :boolean}])
|
||||||
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [state (reagent/atom {:token :eth
|
(let [state (reagent/atom {:token-symbol :eth
|
||||||
:currency :usd
|
:currency "$"
|
||||||
:conversion 0.02
|
:crypto? true
|
||||||
:networks networks
|
:error? false})]
|
||||||
:title title
|
|
||||||
:customization-color :blue
|
|
||||||
:show-keyboard? false
|
|
||||||
:allow-selection? true})
|
|
||||||
value (reagent/atom "")
|
|
||||||
set-value (fn [v]
|
|
||||||
(swap! value str v))
|
|
||||||
delete (fn [_]
|
|
||||||
(swap! value #(subs % 0 (dec (count %)))))]
|
|
||||||
(fn []
|
(fn []
|
||||||
[preview/preview-container
|
(let [{:keys [currency token-symbol crypto? error?]} @state
|
||||||
{:state state
|
[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
||||||
:descriptor descriptor
|
input-amount (controlled-input/input-value input-state)
|
||||||
:full-screen? true
|
swap-between-fiat-and-crypto (fn []
|
||||||
:component-container-style {:flex 1
|
(if crypto?
|
||||||
:justify-content :space-between}}
|
(set-input-state #(controlled-input/->fiat
|
||||||
[quo/token-input (assoc @state :value @value)]
|
%
|
||||||
[quo/numbered-keyboard
|
conversion-rate))
|
||||||
{:container-style {:padding-bottom (safe-area/get-top)}
|
(set-input-state
|
||||||
:left-action :dot
|
#(controlled-input/->crypto
|
||||||
:delete-key? true
|
%
|
||||||
:on-press set-value
|
conversion-rate))))
|
||||||
:on-delete delete}]])))
|
converted-value (if crypto?
|
||||||
|
(utils/prettify-balance currency
|
||||||
|
(money/crypto->fiat
|
||||||
|
input-amount
|
||||||
|
conversion-rate))
|
||||||
|
(utils/prettify-crypto-balance
|
||||||
|
(or (clj->js token-symbol) "")
|
||||||
|
(money/fiat->crypto input-amount
|
||||||
|
conversion-rate)
|
||||||
|
conversion-rate))]
|
||||||
|
[preview/preview-container
|
||||||
|
{:state state
|
||||||
|
:descriptor descriptor
|
||||||
|
:full-screen? true
|
||||||
|
:component-container-style {:flex 1
|
||||||
|
:justify-content :space-between}}
|
||||||
|
[quo/token-input
|
||||||
|
{:token-symbol token-symbol
|
||||||
|
:currency-symbol (if crypto? token-symbol currency)
|
||||||
|
:error? error?
|
||||||
|
:value input-amount
|
||||||
|
:converted-value converted-value
|
||||||
|
: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
|
||||||
|
:delete-key? true
|
||||||
|
:on-press (fn [c]
|
||||||
|
(set-input-state #(controlled-input/add-character % c)))
|
||||||
|
|
||||||
|
:on-delete (fn []
|
||||||
|
(set-input-state controlled-input/delete-last))}]]))))
|
||||||
|
|||||||
@@ -12,14 +12,17 @@
|
|||||||
[full-name]
|
[full-name]
|
||||||
(first (string/split full-name #" ")))
|
(first (string/split full-name #" ")))
|
||||||
|
|
||||||
(defn prettify-balance
|
(defn cut-fiat-balance-to-two-decimals
|
||||||
[currency-symbol balance]
|
[balance]
|
||||||
(let [valid-balance? (and balance
|
(let [valid-balance? (and balance
|
||||||
(or (number? balance) (.-toFixed balance)))]
|
(or (number? balance) (.-toFixed balance)))]
|
||||||
(as-> balance $
|
(as-> balance $
|
||||||
(if valid-balance? $ 0)
|
(if valid-balance? $ 0)
|
||||||
(.toFixed $ 2)
|
(.toFixed $ 2))))
|
||||||
(str currency-symbol $))))
|
|
||||||
|
(defn prettify-balance
|
||||||
|
[currency-symbol balance]
|
||||||
|
(str currency-symbol (cut-fiat-balance-to-two-decimals balance)))
|
||||||
|
|
||||||
(defn get-derivation-path
|
(defn get-derivation-path
|
||||||
[number-of-accounts]
|
[number-of-accounts]
|
||||||
@@ -47,8 +50,8 @@
|
|||||||
nil))
|
nil))
|
||||||
|
|
||||||
(defn calc-max-crypto-decimals
|
(defn calc-max-crypto-decimals
|
||||||
[value]
|
[one-cent-value]
|
||||||
(let [str-representation (str value)
|
(let [str-representation (str one-cent-value)
|
||||||
decimal-part (second (clojure.string/split str-representation #"\."))
|
decimal-part (second (clojure.string/split str-representation #"\."))
|
||||||
exponent (extract-exponent str-representation)
|
exponent (extract-exponent str-representation)
|
||||||
zeroes-count (count (take-while #(= \0 %) decimal-part))
|
zeroes-count (count (take-while #(= \0 %) decimal-part))
|
||||||
@@ -58,29 +61,60 @@
|
|||||||
(inc max-decimals)
|
(inc max-decimals)
|
||||||
max-decimals)))
|
max-decimals)))
|
||||||
|
|
||||||
(defn get-crypto-decimals-count
|
(defn token-usd-price
|
||||||
[{:keys [market-values-per-currency]}]
|
[token]
|
||||||
(let [price (get-in market-values-per-currency [:usd :price])
|
(get-in token [:market-values-per-currency :usd :price]))
|
||||||
one-cent-value (if (pos? price) (/ 0.01 price) 0)]
|
|
||||||
(calc-max-crypto-decimals one-cent-value)))
|
(defn one-cent-value
|
||||||
|
[token-price-in-usd]
|
||||||
|
(if (pos? token-price-in-usd)
|
||||||
|
(/ 0.01 token-price-in-usd)
|
||||||
|
0))
|
||||||
|
|
||||||
|
(defn analyze-token-amount-for-price
|
||||||
|
"For full details: https://github.com/status-im/status-mobile/issues/18225"
|
||||||
|
[token-price-in-usd token-units]
|
||||||
|
(if (or (nil? token-units)
|
||||||
|
(not (money/bignumber? token-units))
|
||||||
|
(money/equal-to token-units 0))
|
||||||
|
{:zero-value? true}
|
||||||
|
(let [cent-value (one-cent-value token-price-in-usd)]
|
||||||
|
{:usd-cent-value cent-value
|
||||||
|
:standardized-decimals-count (if (nil? token-price-in-usd)
|
||||||
|
missing-price-decimals
|
||||||
|
(calc-max-crypto-decimals cent-value))})))
|
||||||
|
|
||||||
|
(defn cut-crypto-decimals-to-fit-usd-cents
|
||||||
|
[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
|
||||||
|
zero-value? "0"
|
||||||
|
(< token-units usd-cent-value) "0"
|
||||||
|
:else (number/remove-trailing-zeroes
|
||||||
|
(.toFixed token-units standardized-decimals-count)))))
|
||||||
|
|
||||||
|
(defn prettify-crypto-balance
|
||||||
|
[token-symbol crypto-balance conversion-rate]
|
||||||
|
(str (cut-crypto-decimals-to-fit-usd-cents crypto-balance conversion-rate)
|
||||||
|
" "
|
||||||
|
(string/upper-case token-symbol)))
|
||||||
|
|
||||||
(defn get-standard-crypto-format
|
(defn get-standard-crypto-format
|
||||||
"For full details: https://github.com/status-im/status-mobile/issues/18225"
|
"For full details: https://github.com/status-im/status-mobile/issues/18225"
|
||||||
[{:keys [market-values-per-currency]} token-units]
|
[token token-units]
|
||||||
(cond (or (nil? token-units)
|
(let [token-price-in-usd (token-usd-price token)
|
||||||
(money/equal-to token-units 0))
|
{:keys [zero-value? usd-cent-value standardized-decimals-count]}
|
||||||
"0"
|
(analyze-token-amount-for-price token-price-in-usd token-units)]
|
||||||
|
(cond
|
||||||
|
zero-value?
|
||||||
|
"0"
|
||||||
|
|
||||||
(nil? (-> market-values-per-currency :usd :price))
|
(< token-units usd-cent-value)
|
||||||
(number/remove-trailing-zeroes (.toFixed token-units missing-price-decimals))
|
(str "<" (number/remove-trailing-zeroes (.toFixed usd-cent-value standardized-decimals-count)))
|
||||||
|
|
||||||
:else
|
:else
|
||||||
(let [price (-> market-values-per-currency :usd :price)
|
(number/remove-trailing-zeroes (.toFixed token-units standardized-decimals-count)))))
|
||||||
one-cent-value (if (pos? price) (/ 0.01 price) 0)
|
|
||||||
decimals-count (calc-max-crypto-decimals one-cent-value)]
|
|
||||||
(if (< token-units one-cent-value)
|
|
||||||
(str "<" (number/remove-trailing-zeroes (.toFixed one-cent-value 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]}]
|
||||||
@@ -286,18 +320,6 @@
|
|||||||
(let [counter (count address)]
|
(let [counter (count address)]
|
||||||
(str (subs address 0 6) "\u2026" (subs address (- counter 3) counter)))))
|
(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
|
(defn get-account-name-error
|
||||||
[s existing-account-names]
|
[s existing-account-names]
|
||||||
(cond
|
(cond
|
||||||
|
|||||||
@@ -73,7 +73,12 @@
|
|||||||
token-units (money/bignumber 0.01)]
|
token-units (money/bignumber 0.01)]
|
||||||
(is (= (utils/get-standard-crypto-format {:market-values-per-currency market-values-per-currency}
|
(is (= (utils/get-standard-crypto-format {:market-values-per-currency market-values-per-currency}
|
||||||
token-units)
|
token-units)
|
||||||
"<2")))))
|
"<2")))
|
||||||
|
(let [market-values-per-currency {:usd {:price 0.005}}
|
||||||
|
token-units "0.01"]
|
||||||
|
(is (= (utils/get-standard-crypto-format {:market-values-per-currency market-values-per-currency}
|
||||||
|
token-units)
|
||||||
|
"0")))))
|
||||||
|
|
||||||
(deftest calculate-total-token-balance-test
|
(deftest calculate-total-token-balance-test
|
||||||
(testing "calculate-total-token-balance function"
|
(testing "calculate-total-token-balance function"
|
||||||
@@ -163,5 +168,3 @@
|
|||||||
expected-order ["DAI" "ETH" "SNT"]]
|
expected-order ["DAI" "ETH" "SNT"]]
|
||||||
(is (= expected-order sorted-tokens)))))
|
(is (= expected-order sorted-tokens)))))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -110,46 +110,23 @@
|
|||||||
(h/setup-subs sub-mocks)
|
(h/setup-subs sub-mocks)
|
||||||
(h/render-with-theme-provider [input-amount/view
|
(h/render-with-theme-provider [input-amount/view
|
||||||
{:crypto-decimals 2
|
{:crypto-decimals 2
|
||||||
:limit-crypto 250
|
:limit-crypto (money/bignumber 250)
|
||||||
:initial-crypto-currency? false}])
|
:initial-crypto-currency? false}])
|
||||||
(h/is-truthy (h/get-by-text "0"))
|
(h/is-truthy (h/get-by-text "0"))
|
||||||
(h/is-truthy (h/get-by-text "ETH"))
|
(h/is-truthy (h/get-by-text "USD"))
|
||||||
(h/is-truthy (h/get-by-text "$0.00"))
|
(h/is-truthy (h/get-by-text "0 ETH"))
|
||||||
(h/is-truthy (h/get-by-label-text :container))
|
(h/is-truthy (h/get-by-label-text :container))
|
||||||
(h/is-disabled (h/get-by-label-text :button-one)))
|
(h/is-disabled (h/get-by-label-text :button-one)))
|
||||||
|
|
||||||
(h/test "Fill token input and confirm"
|
|
||||||
(h/setup-subs sub-mocks)
|
|
||||||
(let [on-confirm (h/mock-fn)]
|
|
||||||
(h/render-with-theme-provider [input-amount/view
|
|
||||||
{:on-confirm on-confirm
|
|
||||||
:crypto-decimals 10
|
|
||||||
:limit-crypto 1000
|
|
||||||
:initial-crypto-currency? false}])
|
|
||||||
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-3))
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-.))
|
|
||||||
(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))))))
|
|
||||||
|
|
||||||
(h/test "Fill token input and confirm"
|
(h/test "Fill token input and confirm"
|
||||||
(h/setup-subs sub-mocks)
|
(h/setup-subs sub-mocks)
|
||||||
|
|
||||||
(let [on-confirm (h/mock-fn)]
|
(let [on-confirm (h/mock-fn)]
|
||||||
(h/render-with-theme-provider [input-amount/view
|
(h/render-with-theme-provider [input-amount/view
|
||||||
{:crypto-decimals 10
|
{:crypto-decimals 10
|
||||||
:limit-crypto 1000
|
:limit-crypto (money/bignumber 1000)
|
||||||
:on-confirm on-confirm
|
:on-confirm on-confirm
|
||||||
:initial-crypto-currency? false}])
|
:initial-crypto-currency? true}])
|
||||||
|
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||||
@@ -158,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-4))
|
||||||
(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 "$1234.50"))
|
(-> (h/wait-for #(h/get-by-text "$1234.50"))
|
||||||
(.then (fn []
|
(.then (fn []
|
||||||
(h/is-truthy (h/get-by-label-text :button-one))
|
(let [btn (h/get-by-label-text :button-one)]
|
||||||
(h/is-truthy (h/get-by-label-text :container))
|
(h/is-truthy btn)
|
||||||
(h/fire-event :press (h/get-by-label-text :button-one))
|
(h/fire-event :press btn)
|
||||||
(h/was-called on-confirm))))))
|
(h/was-called on-confirm)))))))
|
||||||
|
|
||||||
(h/test "Try to fill more than limit"
|
(h/test "Try to fill more than limit"
|
||||||
(h/setup-subs sub-mocks)
|
(h/setup-subs sub-mocks)
|
||||||
(h/render-with-theme-provider [input-amount/view
|
(h/render-with-theme-provider [input-amount/view
|
||||||
{:crypto-decimals 1
|
{: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-2))
|
||||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||||
@@ -181,13 +159,12 @@
|
|||||||
(h/setup-subs sub-mocks)
|
(h/setup-subs sub-mocks)
|
||||||
(h/render-with-theme-provider [input-amount/view
|
(h/render-with-theme-provider [input-amount/view
|
||||||
{:crypto-decimals 1
|
{:crypto-decimals 1
|
||||||
:limit-crypto 1
|
:limit-crypto (money/bignumber 10)
|
||||||
:on-confirm #()}])
|
: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/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||||
(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/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)
|
bottom (safe-area/get-bottom)
|
||||||
[crypto-currency? set-crypto-currency] (rn/use-state initial-crypto-currency?)
|
[crypto-currency? set-crypto-currency] (rn/use-state initial-crypto-currency?)
|
||||||
on-navigate-back on-navigate-back
|
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)
|
[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]
|
handle-on-confirm (fn [amount]
|
||||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||||
{:amount amount
|
{:amount amount
|
||||||
@@ -167,59 +166,39 @@
|
|||||||
:as
|
:as
|
||||||
token} (rf/sub [:wallet/wallet-send-token])
|
token} (rf/sub [:wallet/wallet-send-token])
|
||||||
send-from-locked-amounts (rf/sub [:wallet/wallet-send-from-locked-amounts])
|
send-from-locked-amounts (rf/sub [:wallet/wallet-send-from-locked-amounts])
|
||||||
{token-balance :total-balance
|
{token-balance :total-balance
|
||||||
available-balance :available-balance
|
:as token-by-symbol} (rf/sub [:wallet/token-by-symbol
|
||||||
:as token-by-symbol} (rf/sub [:wallet/token-by-symbol
|
|
||||||
(str token-symbol)
|
(str token-symbol)
|
||||||
enabled-from-chain-ids])
|
enabled-from-chain-ids])
|
||||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
|
||||||
currency (rf/sub [:profile/currency])
|
currency (rf/sub [:profile/currency])
|
||||||
conversion-rate (-> token
|
conversion-rate (-> token
|
||||||
:market-values-per-currency
|
:market-values-per-currency
|
||||||
currency
|
currency
|
||||||
:price)
|
:price)
|
||||||
|
[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
|
loading-routes? (rf/sub
|
||||||
[:wallet/wallet-send-loading-suggested-routes?])
|
[:wallet/wallet-send-loading-suggested-routes?])
|
||||||
route (rf/sub [:wallet/wallet-send-route])
|
route (rf/sub [:wallet/wallet-send-route])
|
||||||
on-confirm (or default-on-confirm handle-on-confirm)
|
on-confirm (or default-on-confirm handle-on-confirm)
|
||||||
crypto-decimals (or token-decimals default-crypto-decimals)
|
crypto-decimals (or token-decimals default-crypto-decimals)
|
||||||
current-crypto-limit (or default-limit-crypto
|
input-value (controlled-input/input-value input-state)
|
||||||
(utils/get-standard-crypto-format
|
valid-input? (not (or (controlled-input/empty-value? input-state)
|
||||||
token
|
(controlled-input/input-error input-state)))
|
||||||
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)
|
confirm-disabled? (or (nil? route)
|
||||||
(empty? route)
|
(empty? route)
|
||||||
(string/blank? (controlled-input/input-value
|
(not valid-input?))
|
||||||
input-state))
|
|
||||||
(<= input-num-value 0)
|
|
||||||
(> input-num-value current-limit))
|
|
||||||
amount-in-crypto (if crypto-currency?
|
amount-in-crypto (if crypto-currency?
|
||||||
input-amount
|
input-value
|
||||||
(number/remove-trailing-zeroes
|
(number/remove-trailing-zeroes
|
||||||
(.toFixed (/ input-amount conversion-rate)
|
(.toFixed (/ input-value conversion-rate)
|
||||||
crypto-decimals)))
|
crypto-decimals)))
|
||||||
total-amount-receiver (rf/sub [:wallet/total-amount true])
|
total-amount-receiver (rf/sub [:wallet/total-amount true])
|
||||||
amount-text (str (number/remove-trailing-zeroes
|
amount-text (str (number/remove-trailing-zeroes
|
||||||
@@ -267,8 +246,7 @@
|
|||||||
receiver-selected-network))
|
receiver-selected-network))
|
||||||
receiver-networks))
|
receiver-networks))
|
||||||
input-error (controlled-input/input-error input-state)
|
input-error (controlled-input/input-error input-state)
|
||||||
limit-insufficient? (> (controlled-input/numeric-value input-state)
|
limit-insufficient? (controlled-input/upper-limit-exceeded? input-state)
|
||||||
current-limit)
|
|
||||||
should-try-again? (and (not limit-insufficient?) no-routes-found?)
|
should-try-again? (and (not limit-insufficient?) no-routes-found?)
|
||||||
current-address (rf/sub [:wallet/current-viewing-account-address])
|
current-address (rf/sub [:wallet/current-viewing-account-address])
|
||||||
owned-eth-token (rf/sub [:wallet/token-by-symbol
|
owned-eth-token (rf/sub [:wallet/token-by-symbol
|
||||||
@@ -281,7 +259,9 @@
|
|||||||
(if (= token-symbol
|
(if (= token-symbol
|
||||||
(string/upper-case
|
(string/upper-case
|
||||||
constants/mainnet-short-name))
|
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
|
(money/equal-to (:total-balance
|
||||||
owned-eth-token)
|
owned-eth-token)
|
||||||
0)))
|
0)))
|
||||||
@@ -295,34 +275,20 @@
|
|||||||
:valid-input? valid-input?
|
:valid-input? valid-input?
|
||||||
:bounce-duration-ms bounce-duration-ms
|
:bounce-duration-ms bounce-duration-ms
|
||||||
:token token}))
|
:token token}))
|
||||||
swap-between-fiat-and-crypto (fn [swap-to-crypto-currency?]
|
swap-between-fiat-and-crypto (fn []
|
||||||
(set-just-toggled-mode? true)
|
(set-just-toggled-mode? true)
|
||||||
(set-crypto-currency swap-to-crypto-currency?)
|
(if crypto-currency?
|
||||||
(set-input-state
|
(set-input-state
|
||||||
(fn [input-state]
|
#(controlled-input/->fiat % conversion-rate))
|
||||||
(controlled-input/set-input-value
|
(set-input-state
|
||||||
input-state
|
#(controlled-input/->crypto % conversion-rate)))
|
||||||
(let [value (controlled-input/input-value
|
(set-crypto-currency (not crypto-currency?)))]
|
||||||
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))))))]
|
|
||||||
(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!))
|
||||||
app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)]
|
app-keyboard-listener (.addEventListener rn/app-state "change" dismiss-keyboard-fn)]
|
||||||
#(.remove app-keyboard-listener))))
|
#(.remove app-keyboard-listener))))
|
||||||
(hot-reload/use-safe-unmount on-navigate-back)
|
(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
|
(rn/use-effect
|
||||||
(fn []
|
(fn []
|
||||||
(when input-error (debounce/clear-all))
|
(when input-error (debounce/clear-all))
|
||||||
@@ -346,24 +312,36 @@
|
|||||||
:on-press #(rf/dispatch [:navigate-back])
|
:on-press #(rf/dispatch [:navigate-back])
|
||||||
:switcher-type :select-account}]
|
:switcher-type :select-account}]
|
||||||
[quo/token-input
|
[quo/token-input
|
||||||
{:container-style style/input-container
|
{:container-style style/input-container
|
||||||
:token token-symbol
|
:token-symbol token-symbol
|
||||||
:currency fiat-currency
|
:value input-value
|
||||||
:currency-symbol currency-symbol
|
:on-swap swap-between-fiat-and-crypto
|
||||||
:crypto-decimals (min token-decimals 6)
|
:on-token-press show-select-asset-sheet
|
||||||
:error? (controlled-input/input-error input-state)
|
:error? (controlled-input/input-error input-state)
|
||||||
:networks (seq from-enabled-networks)
|
:currency-symbol (if crypto-currency? token-symbol fiat-currency)
|
||||||
:title (i18n/label
|
:converted-value (if crypto-currency?
|
||||||
:t/send-limit
|
(utils/prettify-balance
|
||||||
{:limit (if crypto-currency?
|
currency-symbol
|
||||||
(utils/make-limit-label-crypto current-limit token-symbol)
|
(money/crypto->fiat input-value
|
||||||
(utils/make-limit-label-fiat current-limit currency-symbol))})
|
conversion-rate))
|
||||||
:conversion conversion-rate
|
(utils/prettify-crypto-balance
|
||||||
:show-keyboard? false
|
(or (clj->js token-symbol) "")
|
||||||
:value input-amount
|
(money/fiat->crypto input-value
|
||||||
:on-swap swap-between-fiat-and-crypto
|
conversion-rate)
|
||||||
:on-token-press show-select-asset-sheet
|
conversion-rate))
|
||||||
:allow-selection? false}]
|
: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
|
[routes/view
|
||||||
{:token token-by-symbol
|
{:token token-by-symbol
|
||||||
:send-amount-in-crypto amount-in-crypto
|
:send-amount-in-crypto amount-in-crypto
|
||||||
@@ -408,7 +386,7 @@
|
|||||||
:left-action :dot
|
:left-action :dot
|
||||||
:delete-key? true
|
:delete-key? true
|
||||||
:on-press (fn [c]
|
: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)
|
max-decimals (if crypto-currency? crypto-decimals 2)
|
||||||
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
|
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
|
||||||
regex (re-pattern regex-pattern)]
|
regex (re-pattern regex-pattern)]
|
||||||
|
|||||||
@@ -1,19 +1,12 @@
|
|||||||
(ns status-im.contexts.wallet.send.routes.view
|
(ns status-im.contexts.wallet.send.routes.view
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[react-native.core :as rn]
|
[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.common.utils.networks :as network-utils]
|
||||||
[status-im.contexts.wallet.send.routes.style :as style]
|
[status-im.contexts.wallet.send.routes.style :as style]
|
||||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||||
[status-im.feature-flags :as ff]
|
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.money :as money]
|
|
||||||
[utils.number :as number]
|
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
|
||||||
@@ -87,160 +80,164 @@
|
|||||||
(rf/dispatch [:wallet/update-receiver-networks
|
(rf/dispatch [:wallet/update-receiver-networks
|
||||||
chain-ids]))}]))}]))
|
chain-ids]))}]))}]))
|
||||||
|
|
||||||
(defn- edit-amount
|
#_(defn- edit-amount
|
||||||
[{:keys [chain-id token-symbol send-amount-in-crypto init-amount]}]
|
[{:keys [chain-id token-symbol send-amount-in-crypto init-amount]}]
|
||||||
(rf/dispatch
|
(rf/dispatch
|
||||||
[:show-bottom-sheet
|
[:show-bottom-sheet
|
||||||
{:content
|
{:content
|
||||||
(fn []
|
(fn []
|
||||||
(let [{:keys [network-name] :as network-details} (rf/sub [:wallet/network-details-by-chain-id
|
(let [{:keys [network-name] :as network-details} (rf/sub [:wallet/network-details-by-chain-id
|
||||||
chain-id])
|
chain-id])
|
||||||
{fiat-currency :currency} (rf/sub [:profile/profile])
|
{fiat-currency :currency} (rf/sub [:profile/profile])
|
||||||
{token-decimals :decimals
|
{token-decimals :decimals
|
||||||
:as
|
:as
|
||||||
token} (rf/sub [:wallet/wallet-send-token])
|
token} (rf/sub [:wallet/wallet-send-token])
|
||||||
currency (rf/sub [:profile/currency])
|
currency (rf/sub [:profile/currency])
|
||||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||||
send-from-locked-amounts (rf/sub
|
send-from-locked-amounts (rf/sub
|
||||||
[:wallet/wallet-send-from-locked-amounts])
|
[:wallet/wallet-send-from-locked-amounts])
|
||||||
{account-color :color} (rf/sub [:wallet/current-viewing-account])
|
{account-color :color} (rf/sub [:wallet/current-viewing-account])
|
||||||
locked-amount (get send-from-locked-amounts chain-id)
|
locked-amount (get send-from-locked-amounts chain-id)
|
||||||
network-name-str (string/capitalize (name network-name))
|
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
|
||||||
init-amount
|
(cond-> controlled-input/init-state
|
||||||
(controlled-input/set-input-value
|
init-amount
|
||||||
(money/to-string init-amount))
|
|
||||||
locked-amount
|
|
||||||
(controlled-input/set-input-value
|
|
||||||
locked-amount)))
|
|
||||||
[crypto-currency? set-crypto-currency] (rn/use-state true)
|
|
||||||
conversion-rate (-> token
|
|
||||||
:market-values-per-currency
|
|
||||||
currency
|
|
||||||
:price)
|
|
||||||
{token-balance :total-balance} (rf/sub [:wallet/token-by-symbol
|
|
||||||
(str token-symbol)
|
|
||||||
[chain-id]])
|
|
||||||
current-crypto-limit (utils/get-standard-crypto-format
|
|
||||||
token
|
|
||||||
token-balance)
|
|
||||||
current-fiat-limit (.toFixed (* token-balance conversion-rate) 2)
|
|
||||||
current-limit (if crypto-currency?
|
|
||||||
current-crypto-limit
|
|
||||||
current-fiat-limit)
|
|
||||||
crypto-decimals token-decimals
|
|
||||||
input-amount (controlled-input/input-value input-state)
|
|
||||||
[is-amount-locked? set-is-amount-locked] (rn/use-state (some? locked-amount))
|
|
||||||
bottom (safe-area/get-bottom)
|
|
||||||
amount-in-crypto (if crypto-currency?
|
|
||||||
input-amount
|
|
||||||
(number/remove-trailing-zeroes
|
|
||||||
(.toFixed (/ input-amount
|
|
||||||
conversion-rate)
|
|
||||||
crypto-decimals)))
|
|
||||||
locked-greater-then-send-amount? (let [amount (money/bignumber
|
|
||||||
amount-in-crypto)
|
|
||||||
send-amount (money/bignumber
|
|
||||||
send-amount-in-crypto)]
|
|
||||||
(and (money/bignumber? amount)
|
|
||||||
(money/bignumber? 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-input-state
|
|
||||||
(fn [input-state]
|
|
||||||
(controlled-input/set-input-value
|
(controlled-input/set-input-value
|
||||||
input-state
|
(money/to-string init-amount))
|
||||||
(let [value (controlled-input/input-value
|
locked-amount
|
||||||
input-state)
|
(controlled-input/set-input-value
|
||||||
new-value (if
|
locked-amount)))
|
||||||
swap-to-crypto-currency?
|
[crypto-currency? set-crypto-currency] (rn/use-state true)
|
||||||
(.toFixed
|
conversion-rate (-> token
|
||||||
(/ value
|
:market-values-per-currency
|
||||||
conversion-rate)
|
currency
|
||||||
crypto-decimals)
|
:price)
|
||||||
(.toFixed
|
{token-balance :total-balance} (rf/sub [:wallet/token-by-symbol
|
||||||
(* value
|
(str token-symbol)
|
||||||
conversion-rate)
|
[chain-id]])
|
||||||
12))]
|
current-crypto-limit (utils/get-standard-crypto-format
|
||||||
(number/remove-trailing-zeroes
|
token
|
||||||
new-value))))))
|
token-balance)
|
||||||
lock-or-unlock-amount (fn []
|
current-fiat-limit (.toFixed (* token-balance conversion-rate) 2)
|
||||||
(if is-amount-locked?
|
current-limit (if crypto-currency?
|
||||||
(rf/dispatch [:wallet/lock-from-amount
|
current-crypto-limit
|
||||||
chain-id
|
current-fiat-limit)
|
||||||
amount-in-crypto])
|
crypto-decimals token-decimals
|
||||||
(rf/dispatch [:wallet/unlock-from-amount
|
input-amount (controlled-input/input-value input-state)
|
||||||
chain-id]))
|
[is-amount-locked? set-is-amount-locked] (rn/use-state (some? locked-amount))
|
||||||
(rf/dispatch [:hide-bottom-sheet]))]
|
bottom (safe-area/get-bottom)
|
||||||
(rn/use-effect
|
amount-in-crypto (if crypto-currency?
|
||||||
(fn []
|
input-amount
|
||||||
(set-input-state #(controlled-input/set-upper-limit % current-limit)))
|
(number/remove-trailing-zeroes
|
||||||
[current-limit])
|
(.toFixed (/ input-amount
|
||||||
[:<>
|
conversion-rate)
|
||||||
[quo/drawer-top
|
crypto-decimals)))
|
||||||
{:title (i18n/label :t/send-from-network {:network network-name-str})
|
locked-greater-then-send-amount? (let [amount (money/bignumber
|
||||||
:description (i18n/label :t/define-amount-sent-from-network {:network network-name-str})}]
|
amount-in-crypto)
|
||||||
[quo/token-input
|
send-amount (money/bignumber
|
||||||
{:container-style style/input-container
|
send-amount-in-crypto)]
|
||||||
:token token-symbol
|
(and (money/bignumber? amount)
|
||||||
:currency fiat-currency
|
(money/bignumber? send-amount)
|
||||||
:currency-symbol currency-symbol
|
(money/greater-than amount
|
||||||
:crypto-decimals (min token-decimals 6)
|
send-amount)))
|
||||||
:error? (controlled-input/input-error input-state)
|
swap-between-fiat-and-crypto (fn [swap-to-crypto-currency?]
|
||||||
:networks [network-details]
|
(set-crypto-currency
|
||||||
:title (i18n/label
|
swap-to-crypto-currency?)
|
||||||
:t/send-limit
|
(set-input-state
|
||||||
{:limit (if crypto-currency?
|
(fn [input-state]
|
||||||
(utils/make-limit-label-crypto current-limit token-symbol)
|
(controlled-input/set-input-value
|
||||||
(utils/make-limit-label-fiat current-limit currency-symbol))})
|
input-state
|
||||||
:conversion conversion-rate
|
(let [value (controlled-input/input-value
|
||||||
:show-keyboard? false
|
input-state)
|
||||||
:value (controlled-input/input-value input-state)
|
new-value
|
||||||
:on-swap swap-between-fiat-and-crypto
|
(if
|
||||||
:allow-selection? false}]
|
swap-to-crypto-currency?
|
||||||
(when locked-greater-then-send-amount?
|
(.toFixed
|
||||||
[quo/information-box
|
(/ value
|
||||||
{:type :error
|
conversion-rate)
|
||||||
:icon :i/info
|
crypto-decimals)
|
||||||
:style style/error-box}
|
(.toFixed
|
||||||
(i18n/label :t/value-higher-than-send-amount)])
|
(* value
|
||||||
[quo/disclaimer
|
conversion-rate)
|
||||||
{:on-change (fn [checked?]
|
12))]
|
||||||
(set-is-amount-locked checked?))
|
(number/remove-trailing-zeroes
|
||||||
:checked? is-amount-locked?
|
new-value))))))
|
||||||
:container-style style/disclaimer
|
lock-or-unlock-amount (fn []
|
||||||
:icon (if is-amount-locked?
|
(if is-amount-locked?
|
||||||
:i/locked
|
(rf/dispatch [:wallet/lock-from-amount
|
||||||
:i/unlocked)
|
chain-id
|
||||||
:customization-color account-color}
|
amount-in-crypto])
|
||||||
(i18n/label :t/dont-auto-recalculate-network {:network network-name-str})]
|
(rf/dispatch [:wallet/unlock-from-amount
|
||||||
[quo/bottom-actions
|
chain-id]))
|
||||||
{:actions :one-action
|
(rf/dispatch [:hide-bottom-sheet]))]
|
||||||
:button-one-label (i18n/label :t/update)
|
(rn/use-effect
|
||||||
:button-one-props {:on-press lock-or-unlock-amount
|
(fn []
|
||||||
:customization-color account-color
|
(set-input-state #(controlled-input/set-upper-limit % current-limit)))
|
||||||
:disabled? (or (controlled-input/empty-value? input-state)
|
[current-limit])
|
||||||
(controlled-input/input-error input-state)
|
[:<>
|
||||||
locked-greater-then-send-amount?)}}]
|
[quo/drawer-top
|
||||||
[quo/numbered-keyboard
|
{:title (i18n/label :t/send-from-network {:network network-name-str})
|
||||||
{:container-style (style/keyboard-container bottom)
|
:description (i18n/label :t/define-amount-sent-from-network {:network network-name-str})}]
|
||||||
:left-action :dot
|
[quo/token-input
|
||||||
:delete-key? true
|
{:container-style style/input-container
|
||||||
:on-press (fn [c]
|
:token token-symbol
|
||||||
(let [new-text (str input-amount c)
|
:currency fiat-currency
|
||||||
max-decimals (if crypto-currency? crypto-decimals 2)
|
:currency-symbol currency-symbol
|
||||||
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
|
:crypto-decimals (min token-decimals 6)
|
||||||
regex (re-pattern regex-pattern)]
|
:error? (controlled-input/input-error input-state)
|
||||||
(when (re-matches regex new-text)
|
:networks [network-details]
|
||||||
(set-is-amount-locked true)
|
:title (i18n/label
|
||||||
(set-input-state #(controlled-input/add-character % c)))))
|
:t/send-limit
|
||||||
:on-delete (fn []
|
{:limit (if crypto-currency?
|
||||||
(set-is-amount-locked true)
|
(utils/make-limit-label-crypto current-limit token-symbol)
|
||||||
(set-input-state controlled-input/delete-last))
|
(utils/make-limit-label-fiat current-limit currency-symbol))})
|
||||||
:on-long-press-delete (fn []
|
:conversion conversion-rate
|
||||||
(set-is-amount-locked true)
|
:show-keyboard? false
|
||||||
(set-input-state controlled-input/delete-all))}]]))}]))
|
:value (controlled-input/input-value input-state)
|
||||||
|
:on-swap swap-between-fiat-and-crypto
|
||||||
|
:allow-selection? false}]
|
||||||
|
(when locked-greater-then-send-amount?
|
||||||
|
[quo/information-box
|
||||||
|
{:type :error
|
||||||
|
:icon :i/info
|
||||||
|
:style style/error-box}
|
||||||
|
(i18n/label :t/value-higher-than-send-amount)])
|
||||||
|
[quo/disclaimer
|
||||||
|
{:on-change (fn [checked?]
|
||||||
|
(set-is-amount-locked checked?))
|
||||||
|
:checked? is-amount-locked?
|
||||||
|
:container-style style/disclaimer
|
||||||
|
:icon (if is-amount-locked?
|
||||||
|
:i/locked
|
||||||
|
:i/unlocked)
|
||||||
|
:customization-color account-color}
|
||||||
|
(i18n/label :t/dont-auto-recalculate-network {:network network-name-str})]
|
||||||
|
[quo/bottom-actions
|
||||||
|
{:actions :one-action
|
||||||
|
:button-one-label (i18n/label :t/update)
|
||||||
|
:button-one-props {:on-press lock-or-unlock-amount
|
||||||
|
:customization-color account-color
|
||||||
|
:disabled? (or (controlled-input/empty-value? input-state)
|
||||||
|
(controlled-input/input-error input-state)
|
||||||
|
locked-greater-then-send-amount?)}}]
|
||||||
|
[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 (re-matches regex new-text)
|
||||||
|
(set-is-amount-locked true)
|
||||||
|
(set-input-state #(controlled-input/add-character % c)))))
|
||||||
|
:on-delete (fn []
|
||||||
|
(set-is-amount-locked true)
|
||||||
|
(set-input-state controlled-input/delete-last))
|
||||||
|
:on-long-press-delete (fn []
|
||||||
|
(set-is-amount-locked true)
|
||||||
|
(set-input-state controlled-input/delete-all))}]]))}]))
|
||||||
|
|
||||||
(defn render-network-values
|
(defn render-network-values
|
||||||
[{:keys [network-values token-symbol on-press on-long-press receiver? loading-routes?
|
[{:keys [network-values token-symbol on-press on-long-press receiver? loading-routes?
|
||||||
@@ -388,13 +385,6 @@
|
|||||||
chain-id-to-disable
|
chain-id-to-disable
|
||||||
disabled-from-chain-ids
|
disabled-from-chain-ids
|
||||||
token-available-networks-for-suggested-routes))
|
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
|
:receiver? false
|
||||||
:theme theme
|
:theme theme
|
||||||
:loading-routes? loading-routes?
|
:loading-routes? loading-routes?
|
||||||
|
|||||||
@@ -6,6 +6,8 @@
|
|||||||
prefer to use it for more general purpose concepts, such as the re-frame event
|
prefer to use it for more general purpose concepts, such as the re-frame event
|
||||||
layer."
|
layer."
|
||||||
(:require-macros test-helpers.unit)
|
(:require-macros test-helpers.unit)
|
||||||
|
;; We must require test-helpers.matchers namespace to register the custom cljs.test directive
|
||||||
|
;; `match-strict?`
|
||||||
(:require
|
(:require
|
||||||
[re-frame.core :as rf]
|
[re-frame.core :as rf]
|
||||||
[re-frame.db :as rf-db]
|
[re-frame.db :as rf-db]
|
||||||
|
|||||||
@@ -55,8 +55,9 @@
|
|||||||
(.lessThan ^js bn1 bn2))
|
(.lessThan ^js bn1 bn2))
|
||||||
|
|
||||||
(defn equal-to
|
(defn equal-to
|
||||||
[bn1 bn2]
|
[n1 n2]
|
||||||
(.eq ^js bn1 bn2))
|
(when-let [^js bn1 (bignumber n1)]
|
||||||
|
(.eq ^js bn1 n2)))
|
||||||
|
|
||||||
(extend-type BigNumber
|
(extend-type BigNumber
|
||||||
IEquiv
|
IEquiv
|
||||||
@@ -262,6 +263,12 @@
|
|||||||
[bn1 bn2]
|
[bn1 bn2]
|
||||||
(.round (.dividedBy ^js bn1 bn2) 0))
|
(.round (.dividedBy ^js bn1 bn2) 0))
|
||||||
|
|
||||||
|
(defn fiat->crypto
|
||||||
|
[crypto fiat-price]
|
||||||
|
(when-let [crypto-bn (bignumber crypto)]
|
||||||
|
(div crypto-bn
|
||||||
|
(bignumber fiat-price))))
|
||||||
|
|
||||||
(defn absolute-value
|
(defn absolute-value
|
||||||
[bn]
|
[bn]
|
||||||
(when bn
|
(when bn
|
||||||
|
|||||||
Reference in New Issue
Block a user