mirror of
https://github.com/status-im/status-mobile.git
synced 2025-01-27 08:55:39 +00:00
feat: support edge case flow in the wallet send flow when token is not available on receiver preferred networks (#19674)
feat: implement wallet send flow edge case when selected token is not supported on receiver's preferred networks Signed-off-by: Brian Sztamfater <brian@status.im>
This commit is contained in:
parent
8f0840e913
commit
0145429852
@ -229,15 +229,16 @@
|
||||
|
||||
(defn make-network-item
|
||||
"This function generates props for quo/category component item"
|
||||
[{:keys [network-name color on-change networks state label-props]}]
|
||||
[{:keys [network-name color on-change networks state label-props type]}]
|
||||
(cond-> {:title (string/capitalize (name network-name))
|
||||
:image :icon-avatar
|
||||
:image-props {:icon (resources/get-network network-name)
|
||||
:size :size-20}
|
||||
:action :selector
|
||||
:action-props {:type (if (= :default state)
|
||||
:filled-checkbox
|
||||
:checkbox)
|
||||
:action-props {:type (or type
|
||||
(if (= :default state)
|
||||
:filled-checkbox
|
||||
:checkbox))
|
||||
:customization-color color
|
||||
:checked? (contains? networks network-name)
|
||||
:on-change on-change}}
|
||||
|
@ -3,6 +3,8 @@
|
||||
[status-im.constants :as constants]
|
||||
[utils.number]))
|
||||
|
||||
(def ^:private last-comma-followed-by-text-to-end-regex #",\s(?=[^,]+$)")
|
||||
|
||||
(def id->network
|
||||
{constants/ethereum-mainnet-chain-id constants/mainnet-network-name
|
||||
constants/ethereum-goerli-chain-id constants/mainnet-network-name
|
||||
@ -113,3 +115,13 @@
|
||||
(as-> prefix $
|
||||
(string/split $ ":")
|
||||
(map short-name->network $)))
|
||||
|
||||
(defn network-ids->formatted-text
|
||||
[network-ids]
|
||||
(let [network-names (->> network-ids
|
||||
(map id->network)
|
||||
(map name)
|
||||
(map string/capitalize)
|
||||
(string/join ", "))
|
||||
formatted-text (string/replace network-names last-comma-followed-by-text-to-end-regex " and ")]
|
||||
formatted-text))
|
||||
|
@ -43,3 +43,21 @@
|
||||
(seq [:mainnet]) "eth"
|
||||
(seq [:mainnet :optimism]) "eth:opt"
|
||||
(seq [:mainnet :optimism :arbitrum]) "eth:opt:arb1"))
|
||||
|
||||
(deftest test-network-ids->formatted-text
|
||||
(testing "Empty network-ids should return an empty string"
|
||||
(is (= "" (utils/network-ids->formatted-text []))))
|
||||
|
||||
(testing "Single network-id should return the capitalized name of that network"
|
||||
(is (= "Mainnet" (utils/network-ids->formatted-text [constants/ethereum-mainnet-chain-id]))))
|
||||
|
||||
(testing "Two network-ids should return a comma-separated string with 'and' for the last item"
|
||||
(is (= "Mainnet and Optimism"
|
||||
(utils/network-ids->formatted-text [constants/ethereum-mainnet-chain-id
|
||||
constants/optimism-mainnet-chain-id]))))
|
||||
|
||||
(testing "Multiple network-ids should return a comma-separated string with 'and' for the last item"
|
||||
(is (= "Mainnet, Optimism and Arbitrum"
|
||||
(utils/network-ids->formatted-text [constants/ethereum-mainnet-chain-id
|
||||
constants/optimism-mainnet-chain-id
|
||||
constants/arbitrum-mainnet-chain-id])))))
|
||||
|
@ -39,32 +39,38 @@
|
||||
token-decimals (if collectible 0 (:decimals token))
|
||||
native-token? (and token (= token-display-name "ETH"))
|
||||
routes-available? (pos? (count chosen-route))
|
||||
token-networks (:networks token)
|
||||
token-networks-ids (when token-networks (mapv #(:chain-id %) token-networks))
|
||||
from-network-amounts-by-chain (send-utils/network-amounts-by-chain {:route chosen-route
|
||||
:token-decimals
|
||||
token-decimals
|
||||
:native-token?
|
||||
native-token?
|
||||
:to? false})
|
||||
:receiver? false})
|
||||
from-network-values-for-ui (send-utils/network-values-for-ui from-network-amounts-by-chain)
|
||||
to-network-amounts-by-chain (send-utils/network-amounts-by-chain {:route chosen-route
|
||||
:token-decimals
|
||||
token-decimals
|
||||
:native-token?
|
||||
native-token?
|
||||
:to? true})
|
||||
:receiver? true})
|
||||
to-network-values-for-ui (send-utils/network-values-for-ui to-network-amounts-by-chain)
|
||||
sender-network-values (if routes-available?
|
||||
(send-utils/network-amounts from-network-values-for-ui
|
||||
disabled-from-chain-ids
|
||||
receiver-networks
|
||||
false)
|
||||
(send-utils/network-amounts
|
||||
{:network-values from-network-values-for-ui
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? false})
|
||||
(send-utils/reset-network-amounts-to-zero
|
||||
sender-network-values))
|
||||
receiver-network-values (if routes-available?
|
||||
(send-utils/network-amounts to-network-values-for-ui
|
||||
disabled-from-chain-ids
|
||||
receiver-networks
|
||||
true)
|
||||
(send-utils/network-amounts
|
||||
{:network-values to-network-values-for-ui
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? true})
|
||||
(send-utils/reset-network-amounts-to-zero
|
||||
receiver-network-values))
|
||||
network-links (when routes-available?
|
||||
@ -147,6 +153,7 @@
|
||||
(assoc-in [:wallet :ui :send :recipient] (or recipient address))
|
||||
(assoc-in [:wallet :ui :send :to-address] to-address)
|
||||
(assoc-in [:wallet :ui :send :address-prefix] prefix)
|
||||
(assoc-in [:wallet :ui :send :receiver-preferred-networks] receiver-networks)
|
||||
(assoc-in [:wallet :ui :send :receiver-networks] receiver-networks))
|
||||
:fx [(when (and collectible-tx? one-collectible?)
|
||||
[:dispatch [:wallet/get-suggested-routes {:amount 1}]])
|
||||
@ -176,26 +183,44 @@
|
||||
;; `token` is a map extracted from the sender, but in the wallet home page we don't know the
|
||||
;; sender yet, so we only provide the `token-symbol`, later in
|
||||
;; `:wallet/select-from-account` the `token` key will be set.
|
||||
{:db (cond-> db
|
||||
:always (update-in [:wallet :ui :send] dissoc :collectible)
|
||||
:always (assoc-in [:wallet :ui :send :token-display-name] (:symbol token))
|
||||
token (assoc-in [:wallet :ui :send :token] token)
|
||||
token-symbol (assoc-in [:wallet :ui :send :token-symbol] token-symbol))
|
||||
:fx [[:dispatch [:wallet/clean-suggested-routes]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-send-flow}]]]}))
|
||||
(let [{token-networks :networks} token
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
token-networks-ids (mapv #(:chain-id %) token-networks)
|
||||
token-not-supported-in-receiver-networks? (not (some (set receiver-networks)
|
||||
token-networks-ids))]
|
||||
{:db (cond-> db
|
||||
:always (update-in [:wallet :ui :send] dissoc :collectible)
|
||||
:always (assoc-in [:wallet :ui :send :token-display-name]
|
||||
(:symbol token))
|
||||
:always (assoc-in
|
||||
[:wallet :ui :send
|
||||
:token-not-supported-in-receiver-networks?]
|
||||
token-not-supported-in-receiver-networks?)
|
||||
token (assoc-in [:wallet :ui :send :token] token)
|
||||
token-symbol (assoc-in [:wallet :ui :send :token-symbol]
|
||||
token-symbol))
|
||||
:fx [[:dispatch [:wallet/clean-suggested-routes]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-send-flow}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/edit-token-to-send
|
||||
(fn [{:keys [db]} [token]]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :token] token)
|
||||
(assoc-in [:wallet :ui :send :token-display-name] token))
|
||||
:fx [[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch [:wallet/clean-suggested-routes]]]}))
|
||||
(let [{token-networks :networks} token
|
||||
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
|
||||
token-networks-ids (mapv #(:chain-id %) token-networks)
|
||||
token-not-supported-in-receiver-networks? (not (some (set receiver-networks)
|
||||
token-networks-ids))]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :token] token)
|
||||
(assoc-in [:wallet :ui :send :token-display-name] token)
|
||||
(assoc-in [:wallet :ui :send :token-not-supported-in-receiver-networks?]
|
||||
token-not-supported-in-receiver-networks?))
|
||||
:fx [[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch [:wallet/clean-suggested-routes]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-selected-token
|
||||
(fn [{:keys [db]}]
|
||||
@ -307,18 +332,21 @@
|
||||
balances-per-chain
|
||||
:disabled-chain-ids
|
||||
disabled-from-chain-ids}))
|
||||
token-networks-ids (when token (mapv #(:chain-id %) (:networks token)))
|
||||
sender-network-values (when token-available-networks-for-suggested-routes
|
||||
(send-utils/loading-network-amounts
|
||||
token-available-networks-for-suggested-routes
|
||||
disabled-from-chain-ids
|
||||
receiver-networks
|
||||
false))
|
||||
{:valid-networks token-available-networks-for-suggested-routes
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? false}))
|
||||
receiver-network-values (when token-available-networks-for-suggested-routes
|
||||
(send-utils/loading-network-amounts
|
||||
token-available-networks-for-suggested-routes
|
||||
disabled-from-chain-ids
|
||||
receiver-networks
|
||||
true))
|
||||
{:valid-networks token-available-networks-for-suggested-routes
|
||||
:disabled-chain-ids disabled-from-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? true}))
|
||||
request-params [transaction-type-param
|
||||
from-address
|
||||
to-address
|
||||
|
@ -76,7 +76,8 @@
|
||||
:wallet/wallet-send-to-values-by-chain {1 (money/bignumber "250")}
|
||||
:wallet/wallet-send-sender-network-values nil
|
||||
:wallet/wallet-send-receiver-network-values nil
|
||||
:wallet/wallet-send-network-links nil})
|
||||
:wallet/wallet-send-network-links nil
|
||||
:wallet/wallet-send-receiver-preferred-networks [1]})
|
||||
|
||||
(h/describe "Send > input amount screen"
|
||||
(h/setup-restorable-re-frame)
|
||||
|
@ -1,4 +1,5 @@
|
||||
(ns status-im.contexts.wallet.send.input-amount.style)
|
||||
(ns status-im.contexts.wallet.send.input-amount.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def screen
|
||||
{:flex 1})
|
||||
@ -38,3 +39,24 @@
|
||||
{:height 40
|
||||
:width "100%"
|
||||
:align-items :center})
|
||||
|
||||
(defn token-not-available-container
|
||||
[theme]
|
||||
{:height 90
|
||||
:flex-direction :row
|
||||
:background-color (colors/resolve-color :danger theme 5)
|
||||
:border-color (colors/resolve-color :danger theme 10)
|
||||
:border-width 1
|
||||
:border-radius 12
|
||||
:margin-horizontal 20
|
||||
:padding 12})
|
||||
|
||||
(def token-not-available-content-container
|
||||
{:margin-left 8
|
||||
:align-items :flex-start})
|
||||
|
||||
(defn token-not-available-text
|
||||
[theme]
|
||||
{:height 36
|
||||
:flex 1
|
||||
:color (colors/resolve-color :danger theme)})
|
||||
|
@ -2,6 +2,8 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
@ -12,6 +14,7 @@
|
||||
[status-im.contexts.wallet.send.input-amount.style :as style]
|
||||
[status-im.contexts.wallet.send.routes.view :as routes]
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
|
||||
[utils.address :as address]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
@ -26,7 +29,7 @@
|
||||
string/upper-case)))
|
||||
|
||||
(defn- estimated-fees
|
||||
[{:keys [loading-suggested-routes? fees amount receiver]}]
|
||||
[{:keys [loading-routes? fees amount receiver]}]
|
||||
[rn/view {:style style/estimated-fees-container}
|
||||
[rn/view {:style style/estimated-fees-content-container}
|
||||
[quo/button
|
||||
@ -35,20 +38,20 @@
|
||||
:size 32
|
||||
:inner-style {:opacity 1}
|
||||
:accessibility-label :advanced-button
|
||||
:disabled? loading-suggested-routes?
|
||||
:disabled? loading-routes?
|
||||
:on-press #(js/alert "Not implemented yet")}
|
||||
:i/advanced]]
|
||||
[quo/data-item
|
||||
{:container-style style/fees-data-item
|
||||
:label :none
|
||||
:status (if loading-suggested-routes? :loading :default)
|
||||
:status (if loading-routes? :loading :default)
|
||||
:size :small
|
||||
:title (i18n/label :t/fees)
|
||||
:subtitle fees}]
|
||||
[quo/data-item
|
||||
{:container-style style/amount-data-item
|
||||
:label :none
|
||||
:status (if loading-suggested-routes? :loading :default)
|
||||
:status (if loading-routes? :loading :default)
|
||||
:size :small
|
||||
:title (i18n/label :t/user-gets {:name receiver})
|
||||
:subtitle amount}]])
|
||||
@ -77,6 +80,36 @@
|
||||
(rf/dispatch [:wallet/edit-token-to-send token])
|
||||
(clear-input!))}]]))
|
||||
|
||||
(defn- token-not-available
|
||||
[token-symbol receiver-networks token-networks]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
add-token-networks (fn []
|
||||
(let [chain-ids (concat receiver-networks
|
||||
(mapv #(:chain-id %) token-networks))]
|
||||
(rf/dispatch [:wallet/update-receiver-networks chain-ids])))]
|
||||
[rn/view {:style (style/token-not-available-container theme)}
|
||||
[rn/view
|
||||
[quo/icon :i/alert
|
||||
{:size 16
|
||||
:color colors/danger-50}]]
|
||||
[rn/view {:style style/token-not-available-content-container}
|
||||
[quo/text
|
||||
{:style (style/token-not-available-text theme)
|
||||
:size :paragraph-2}
|
||||
(i18n/label :t/token-not-available-on-receiver-networks {:token-symbol token-symbol})]
|
||||
[quo/button
|
||||
{:size 24
|
||||
:customization-color colors/danger-50
|
||||
:on-press add-token-networks}
|
||||
(i18n/label :t/add-networks-token-can-be-sent-to {:token-symbol token-symbol})]]]))
|
||||
|
||||
(defn- show-unpreferred-networks-alert
|
||||
[on-confirm]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[unpreferred-networks-alert/view
|
||||
{:on-confirm on-confirm}])}]))
|
||||
(defn view
|
||||
;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed
|
||||
;; for component tests only
|
||||
@ -94,91 +127,112 @@
|
||||
crypto-currency? (reagent/atom initial-crypto-currency?)
|
||||
on-navigate-back on-navigate-back]
|
||||
(fn []
|
||||
(let [[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
||||
clear-input! #(set-input-state controlled-input/delete-all)
|
||||
handle-on-confirm (fn []
|
||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||
{:amount (controlled-input/input-value
|
||||
input-state)
|
||||
:stack-id current-screen-id}]))
|
||||
{fiat-currency :currency} (rf/sub [:profile/profile])
|
||||
(let [[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
||||
clear-input! #(set-input-state controlled-input/delete-all)
|
||||
handle-on-confirm (fn []
|
||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||
{:amount
|
||||
(controlled-input/input-value
|
||||
input-state)
|
||||
:stack-id current-screen-id}]))
|
||||
{fiat-currency :currency} (rf/sub [:profile/profile])
|
||||
{token-symbol :symbol
|
||||
token-networks :networks} (rf/sub [:wallet/wallet-send-token])
|
||||
token-networks :networks} (rf/sub [:wallet/wallet-send-token])
|
||||
{token-balance :total-balance
|
||||
:as
|
||||
token} (rf/sub
|
||||
[:wallet/current-viewing-account-tokens-filtered
|
||||
(str token-symbol)])
|
||||
conversion-rate (-> token :market-values-per-currency :usd :price)
|
||||
loading-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
token} (rf/sub
|
||||
[:wallet/current-viewing-account-tokens-filtered
|
||||
(str token-symbol)])
|
||||
conversion-rate (-> token :market-values-per-currency :usd :price)
|
||||
loading-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
|
||||
route (rf/sub [:wallet/wallet-send-route])
|
||||
to-address (rf/sub [:wallet/wallet-send-to-address])
|
||||
route (rf/sub [:wallet/wallet-send-route])
|
||||
to-address (rf/sub [:wallet/wallet-send-to-address])
|
||||
|
||||
on-confirm (or default-on-confirm handle-on-confirm)
|
||||
crypto-decimals (or default-crypto-decimals
|
||||
(utils/get-crypto-decimals-count token))
|
||||
crypto-limit (or default-limit-crypto
|
||||
(utils/get-standard-crypto-format
|
||||
token
|
||||
token-balance))
|
||||
fiat-limit (.toFixed (* token-balance conversion-rate) 2)
|
||||
current-limit (if @crypto-currency? crypto-limit 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)
|
||||
current-limit)))
|
||||
current-currency (if @crypto-currency? token-symbol fiat-currency)
|
||||
input-num-value (controlled-input/numeric-value input-state)
|
||||
confirm-disabled? (or (nil? route)
|
||||
(empty? route)
|
||||
(string/blank? (controlled-input/input-value input-state))
|
||||
(<= input-num-value 0)
|
||||
(> input-num-value current-limit))
|
||||
amount-text (str (controlled-input/input-value input-state)
|
||||
" "
|
||||
token-symbol)
|
||||
first-route (first route)
|
||||
native-currency-symbol (when-not confirm-disabled?
|
||||
(get-in first-route [:from :native-currency-symbol]))
|
||||
native-token (when native-currency-symbol
|
||||
(rf/sub [:wallet/token-by-symbol
|
||||
native-currency-symbol]))
|
||||
fee-in-native-token (when-not confirm-disabled?
|
||||
(send-utils/calculate-full-route-gas-fee route))
|
||||
fee-in-crypto-formatted (when fee-in-native-token
|
||||
(utils/get-standard-crypto-format
|
||||
native-token
|
||||
fee-in-native-token))
|
||||
fee-in-fiat (when-not confirm-disabled?
|
||||
(utils/calculate-token-fiat-value
|
||||
{:currency fiat-currency
|
||||
:balance fee-in-native-token
|
||||
:token native-token}))
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
fee-formatted (when fee-in-fiat
|
||||
(utils/get-standard-fiat-format
|
||||
fee-in-crypto-formatted
|
||||
currency-symbol
|
||||
fee-in-fiat))
|
||||
show-select-asset-sheet #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[select-asset-bottom-sheet
|
||||
clear-input!])}])
|
||||
loading-suggested-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
sender-network-values (rf/sub
|
||||
[:wallet/wallet-send-sender-network-values])
|
||||
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
|
||||
routes (when suggested-routes
|
||||
(or (:best suggested-routes) []))
|
||||
no-routes-found? (and
|
||||
(every-network-value-is-zero? sender-network-values)
|
||||
(not (nil? routes))
|
||||
(not loading-suggested-routes?))]
|
||||
on-confirm (or default-on-confirm handle-on-confirm)
|
||||
crypto-decimals (or default-crypto-decimals
|
||||
(utils/get-crypto-decimals-count token))
|
||||
crypto-limit (or default-limit-crypto
|
||||
(utils/get-standard-crypto-format
|
||||
token
|
||||
token-balance))
|
||||
fiat-limit (.toFixed (* token-balance conversion-rate) 2)
|
||||
current-limit (if @crypto-currency? crypto-limit 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)
|
||||
current-limit)))
|
||||
current-currency (if @crypto-currency? token-symbol fiat-currency)
|
||||
input-num-value (controlled-input/numeric-value input-state)
|
||||
confirm-disabled? (or (nil? route)
|
||||
(empty? route)
|
||||
(string/blank? (controlled-input/input-value
|
||||
input-state))
|
||||
(<= input-num-value 0)
|
||||
(> input-num-value current-limit))
|
||||
amount-text (str (controlled-input/input-value input-state)
|
||||
" "
|
||||
token-symbol)
|
||||
first-route (first route)
|
||||
native-currency-symbol (when-not confirm-disabled?
|
||||
(get-in first-route
|
||||
[:from :native-currency-symbol]))
|
||||
native-token (when native-currency-symbol
|
||||
(rf/sub [:wallet/token-by-symbol
|
||||
native-currency-symbol]))
|
||||
fee-in-native-token (when-not confirm-disabled?
|
||||
(send-utils/calculate-full-route-gas-fee route))
|
||||
fee-in-crypto-formatted (when fee-in-native-token
|
||||
(utils/get-standard-crypto-format
|
||||
native-token
|
||||
fee-in-native-token))
|
||||
fee-in-fiat (when-not confirm-disabled?
|
||||
(utils/calculate-token-fiat-value
|
||||
{:currency fiat-currency
|
||||
:balance fee-in-native-token
|
||||
:token native-token}))
|
||||
currency-symbol (rf/sub [:profile/currency-symbol])
|
||||
fee-formatted (when fee-in-fiat
|
||||
(utils/get-standard-fiat-format
|
||||
fee-in-crypto-formatted
|
||||
currency-symbol
|
||||
fee-in-fiat))
|
||||
show-select-asset-sheet #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[select-asset-bottom-sheet
|
||||
clear-input!])}])
|
||||
sender-network-values (rf/sub
|
||||
[:wallet/wallet-send-sender-network-values])
|
||||
receiver-network-values (rf/sub
|
||||
[:wallet/wallet-send-receiver-network-values])
|
||||
token-not-supported-in-receiver-networks? (every? #(= (:type %) :not-available)
|
||||
(filter #(not= (:type %) :add)
|
||||
receiver-network-values))
|
||||
suggested-routes (rf/sub [:wallet/wallet-send-suggested-routes])
|
||||
routes (when suggested-routes
|
||||
(or (:best suggested-routes) []))
|
||||
no-routes-found? (and
|
||||
(every-network-value-is-zero?
|
||||
sender-network-values)
|
||||
(not (nil? routes))
|
||||
(not loading-routes?)
|
||||
(not token-not-supported-in-receiver-networks?))
|
||||
receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
|
||||
receiver-preferred-networks (rf/sub
|
||||
[:wallet/wallet-send-receiver-preferred-networks])
|
||||
receiver-preferred-networks-set (set receiver-preferred-networks)
|
||||
sending-to-unpreferred-networks? (not (every? (fn [receiver-selected-network]
|
||||
(contains?
|
||||
receiver-preferred-networks-set
|
||||
receiver-selected-network))
|
||||
receiver-networks))]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
||||
@ -211,16 +265,21 @@
|
||||
:on-swap #(reset! crypto-currency? %)
|
||||
:on-token-press show-select-asset-sheet}]
|
||||
[routes/view
|
||||
{:token token
|
||||
:input-value (controlled-input/input-value input-state)
|
||||
:valid-input? valid-input?
|
||||
:current-screen-id current-screen-id}]
|
||||
{:token token
|
||||
:input-value (controlled-input/input-value input-state)
|
||||
:valid-input? valid-input?
|
||||
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
||||
:current-screen-id current-screen-id}]
|
||||
(when (and (not loading-routes?)
|
||||
sender-network-values
|
||||
token-not-supported-in-receiver-networks?)
|
||||
[token-not-available token-symbol receiver-networks token-networks])
|
||||
(when (or loading-routes? (seq route))
|
||||
[estimated-fees
|
||||
{:loading-suggested-routes? loading-routes?
|
||||
:fees fee-formatted
|
||||
:amount amount-text
|
||||
:receiver (address/get-shortened-key to-address)}])
|
||||
{:loading-routes? loading-routes?
|
||||
:fees fee-formatted
|
||||
:amount amount-text
|
||||
:receiver (address/get-shortened-key to-address)}])
|
||||
(when no-routes-found?
|
||||
[rn/view {:style style/no-routes-found-container}
|
||||
[quo/info-message
|
||||
@ -236,10 +295,14 @@
|
||||
button-one-label)
|
||||
:button-one-props (merge button-one-props
|
||||
{:disabled? (and (not no-routes-found?) confirm-disabled?)
|
||||
:on-press (if no-routes-found?
|
||||
:on-press (cond
|
||||
no-routes-found?
|
||||
#(rf/dispatch [:wallet/get-suggested-routes
|
||||
{:amount (controlled-input/input-value
|
||||
input-state)}])
|
||||
sending-to-unpreferred-networks?
|
||||
#(show-unpreferred-networks-alert on-confirm)
|
||||
:else
|
||||
on-confirm)}
|
||||
(when no-routes-found?
|
||||
{:type :grey}))}]
|
||||
|
@ -1,14 +1,11 @@
|
||||
(ns status-im.contexts.wallet.send.routes.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.resources :as resources]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[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]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@ -19,19 +16,6 @@
|
||||
(def network-link-1x-height 56)
|
||||
(def network-link-2x-height 111)
|
||||
|
||||
(defn- make-network-item
|
||||
[{:keys [network-name chain-id] :as _network}
|
||||
{:keys [title color on-change network-preferences] :as _options}]
|
||||
{:title (or title (string/capitalize (name network-name)))
|
||||
:image :icon-avatar
|
||||
:image-props {:icon (resources/get-network network-name)
|
||||
:size :size-20}
|
||||
:action :selector
|
||||
:action-props {:type :checkbox
|
||||
:customization-color color
|
||||
:checked? (some #(= % chain-id) @network-preferences)
|
||||
:on-change on-change}})
|
||||
|
||||
(defn fetch-routes
|
||||
[amount valid-input? bounce-duration-ms]
|
||||
(if valid-input?
|
||||
@ -40,82 +24,93 @@
|
||||
bounce-duration-ms)
|
||||
(rf/dispatch [:wallet/clean-suggested-routes])))
|
||||
|
||||
(defn networks-drawer
|
||||
[{:keys [on-save theme]}]
|
||||
(let [network-details (rf/sub [:wallet/network-details])
|
||||
{:keys [color]} (rf/sub [:wallet/current-viewing-account])
|
||||
selected-networks (rf/sub [:wallet/wallet-send-receiver-networks])
|
||||
prefix (rf/sub [:wallet/wallet-send-address-prefix])
|
||||
prefix-seq (string/split prefix #":")
|
||||
grouped-details (group-by #(contains? (set prefix-seq) (:short-name %)) network-details)
|
||||
preferred (get grouped-details true [])
|
||||
not-preferred (get grouped-details false [])
|
||||
network-preferences (reagent/atom selected-networks)
|
||||
toggle-network (fn [{:keys [chain-id]}]
|
||||
(swap! network-preferences
|
||||
(fn [preferences]
|
||||
(if (some #(= % chain-id) preferences)
|
||||
(vec (remove #(= % chain-id) preferences))
|
||||
(conj preferences chain-id)))))]
|
||||
(fn []
|
||||
[rn/view
|
||||
[quo/drawer-top {:title (i18n/label :t/edit-receiver-networks)}]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:label (i18n/label :t/preferred-by-receiver)
|
||||
:data (mapv (fn [network]
|
||||
(make-network-item network
|
||||
{:color color
|
||||
:network-preferences network-preferences
|
||||
:on-change #(toggle-network network)}))
|
||||
preferred)}]
|
||||
(when (pos? (count not-preferred))
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:label (i18n/label :t/not-preferred-by-receiver)
|
||||
:data (mapv (fn [network]
|
||||
(make-network-item network
|
||||
{:color color
|
||||
:network-preferences network-preferences
|
||||
:on-change #(toggle-network network)}))
|
||||
not-preferred)}])
|
||||
(when (not= selected-networks @network-preferences)
|
||||
[rn/view {:style (style/warning-container color theme)}
|
||||
[quo/icon :i/info {:color (colors/resolve-color color theme)}]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/warning-text} (i18n/label :t/receiver-networks-warning)]])
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/apply-changes)
|
||||
:button-one-props {:disabled? (or (= selected-networks @network-preferences)
|
||||
(empty? @network-preferences))
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:wallet/update-receiver-networks
|
||||
@network-preferences])
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(on-save))
|
||||
:customization-color color}}]])))
|
||||
(defn- open-preferences
|
||||
[]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
(let [receiver-networks (rf/sub [:wallet/wallet-send-receiver-networks])
|
||||
receiver-preferred-networks (rf/sub
|
||||
[:wallet/wallet-send-receiver-preferred-networks])
|
||||
{token-symbol :symbol
|
||||
token-networks :networks} (rf/sub [:wallet/wallet-send-token])
|
||||
token-chain-ids-set (set (mapv #(:chain-id %) token-networks))
|
||||
[selected-receiver-networks
|
||||
set-selected-receiver-networks] (rn/use-state receiver-networks)
|
||||
receiver-preferred-networks-set (set receiver-preferred-networks)
|
||||
receiver-selected-preferred-networks (filter #(contains?
|
||||
receiver-preferred-networks-set
|
||||
%)
|
||||
selected-receiver-networks)
|
||||
receiver-selected-non-preferred-networks (filter #(not (contains?
|
||||
receiver-preferred-networks-set
|
||||
%))
|
||||
selected-receiver-networks)
|
||||
not-available-preferred-networks (filter (fn [preferred-chain-id]
|
||||
(not (contains? token-chain-ids-set
|
||||
preferred-chain-id)))
|
||||
receiver-selected-preferred-networks)
|
||||
not-available-non-preferred-networks (filter (fn [preferred-chain-id]
|
||||
(not (contains?
|
||||
token-chain-ids-set
|
||||
preferred-chain-id)))
|
||||
receiver-selected-non-preferred-networks)
|
||||
first-section-warning-label (when (not-empty not-available-preferred-networks)
|
||||
(i18n/label
|
||||
:t/token-not-available-on-networks
|
||||
{:token-symbol token-symbol
|
||||
:networks
|
||||
(network-utils/network-ids->formatted-text
|
||||
not-available-preferred-networks)}))
|
||||
second-section-warning-label (when (not-empty
|
||||
not-available-non-preferred-networks)
|
||||
(i18n/label
|
||||
:t/token-not-available-on-networks
|
||||
{:token-symbol token-symbol
|
||||
:networks
|
||||
(network-utils/network-ids->formatted-text
|
||||
not-available-non-preferred-networks)}))]
|
||||
[network-preferences/view
|
||||
{:title (i18n/label :t/edit-receiver-networks)
|
||||
:first-section-label (i18n/label :t/preferred-by-receiver)
|
||||
:second-section-label (i18n/label :t/not-preferred-by-receiver)
|
||||
:selected-networks (set (map network-utils/id->network
|
||||
receiver-networks))
|
||||
:receiver-preferred-networks receiver-preferred-networks
|
||||
:button-label (i18n/label :t/apply-changes)
|
||||
:first-section-warning-label first-section-warning-label
|
||||
:second-section-warning-label second-section-warning-label
|
||||
:on-change #(set-selected-receiver-networks %)
|
||||
:on-save (fn [chain-ids]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:wallet/update-receiver-networks
|
||||
chain-ids]))}]))}]))
|
||||
|
||||
(defn render-network-values
|
||||
[{:keys [network-values token-symbol on-press theme on-save to? loading-suggested-routes?]}]
|
||||
[{:keys [network-values token-symbol on-press receiver? loading-routes?
|
||||
token-not-supported-in-receiver-networks?]}]
|
||||
[rn/view
|
||||
(map-indexed (fn [index {:keys [chain-id total-amount type]}]
|
||||
[rn/view
|
||||
{:key (str (if to? "to" "from") "-" chain-id)
|
||||
{:key (str (if receiver? "to" "from") "-" chain-id)
|
||||
:style {:margin-top (if (pos? index) 11 7.5)}}
|
||||
[quo/network-bridge
|
||||
{:amount (str total-amount " " token-symbol)
|
||||
{:amount (if (= type :not-available)
|
||||
(i18n/label :t/not-available)
|
||||
(str total-amount " " token-symbol))
|
||||
:network (network-utils/id->network chain-id)
|
||||
:status type
|
||||
:on-press #(when (not loading-suggested-routes?)
|
||||
:status (cond (and (= type :not-available)
|
||||
loading-routes?
|
||||
token-not-supported-in-receiver-networks?)
|
||||
:loading
|
||||
(= type :not-available)
|
||||
:disabled
|
||||
:else type)
|
||||
:on-press #(when (not loading-routes?)
|
||||
(cond
|
||||
(= type :add)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[networks-drawer
|
||||
{:theme theme
|
||||
:on-save on-save}])}])
|
||||
(open-preferences)
|
||||
on-press (on-press chain-id total-amount)))}]])
|
||||
network-values)])
|
||||
|
||||
@ -180,12 +175,13 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [token theme input-value valid-input?
|
||||
on-press-to-network current-screen-id]}]
|
||||
on-press-to-network current-screen-id
|
||||
token-not-supported-in-receiver-networks?]}]
|
||||
(let [token-symbol (:symbol token)
|
||||
nav-current-screen-id (rf/sub [:view-id])
|
||||
active-screen? (= nav-current-screen-id current-screen-id)
|
||||
loading-suggested-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
loading-routes? (rf/sub
|
||||
[:wallet/wallet-send-loading-suggested-routes?])
|
||||
sender-network-values (rf/sub
|
||||
[:wallet/wallet-send-sender-network-values])
|
||||
receiver-network-values (rf/sub
|
||||
@ -220,23 +216,27 @@
|
||||
:container-style style/section-label-right}]])
|
||||
[rn/view {:style style/routes-inner-container}
|
||||
[render-network-values
|
||||
{:token-symbol token-symbol
|
||||
:network-values sender-network-values
|
||||
:on-press #(disable-chain %1
|
||||
disabled-from-chain-ids
|
||||
token-available-networks-for-suggested-routes)
|
||||
:to? false
|
||||
:theme theme
|
||||
:loading-suggested-routes? loading-suggested-routes?}]
|
||||
{:token-symbol token-symbol
|
||||
:network-values sender-network-values
|
||||
:on-press (fn [chain-id-to-disable]
|
||||
(disable-chain
|
||||
chain-id-to-disable
|
||||
disabled-from-chain-ids
|
||||
token-available-networks-for-suggested-routes))
|
||||
:receiver? false
|
||||
:theme theme
|
||||
:loading-routes? loading-routes?
|
||||
:token-not-supported-in-receiver-networks? false}]
|
||||
[render-network-links
|
||||
{:network-links network-links
|
||||
:sender-network-values sender-network-values}]
|
||||
[render-network-values
|
||||
{:token-symbol token-symbol
|
||||
:network-values receiver-network-values
|
||||
:on-press on-press-to-network
|
||||
:to? true
|
||||
:loading-suggested-routes? loading-suggested-routes?
|
||||
:theme theme
|
||||
:on-save #(fetch-routes input-value valid-input? 0)}]]]))
|
||||
{:token-symbol token-symbol
|
||||
:network-values receiver-network-values
|
||||
:on-press on-press-to-network
|
||||
:receiver? true
|
||||
:loading-routes? loading-routes?
|
||||
:theme theme
|
||||
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
|
||||
:on-save #(fetch-routes input-value valid-input? 0)}]]]))
|
||||
|
||||
|
@ -43,21 +43,22 @@
|
||||
(money/wei->ether (reduce money/add (map calculate-gas-fee route))))
|
||||
|
||||
(defn network-amounts-by-chain
|
||||
[{:keys [route token-decimals native-token? to?]}]
|
||||
(reduce (fn [acc path]
|
||||
(let [amount-hex (if to? (:amount-in path) (:amount-out path))
|
||||
amount-units (native-module/hex-to-number
|
||||
(utils.hex/normalize-hex amount-hex))
|
||||
amount (money/with-precision
|
||||
(if native-token?
|
||||
(money/wei->ether amount-units)
|
||||
(money/token->unit amount-units
|
||||
token-decimals))
|
||||
6)
|
||||
chain-id (if to? (get-in path [:to :chain-id]) (get-in path [:from :chain-id]))]
|
||||
(update acc chain-id money/add amount)))
|
||||
{}
|
||||
route))
|
||||
[{:keys [route token-decimals native-token? receiver?]}]
|
||||
(reduce
|
||||
(fn [acc path]
|
||||
(let [amount-hex (if receiver? (:amount-in path) (:amount-out path))
|
||||
amount-units (native-module/hex-to-number
|
||||
(utils.hex/normalize-hex amount-hex))
|
||||
amount (money/with-precision
|
||||
(if native-token?
|
||||
(money/wei->ether amount-units)
|
||||
(money/token->unit amount-units
|
||||
token-decimals))
|
||||
6)
|
||||
chain-id (if receiver? (get-in path [:to :chain-id]) (get-in path [:from :chain-id]))]
|
||||
(update acc chain-id money/add amount)))
|
||||
{}
|
||||
route))
|
||||
|
||||
(defn network-values-for-ui
|
||||
[amounts]
|
||||
@ -93,62 +94,103 @@
|
||||
network-amounts))
|
||||
|
||||
(defn network-amounts
|
||||
[network-values disabled-chain-ids receiver-networks to?]
|
||||
(let [disabled-set (set disabled-chain-ids)
|
||||
receiver-networks-set (set receiver-networks)
|
||||
network-values-keys (set (keys network-values))
|
||||
routes-found? (pos? (count network-values-keys))
|
||||
updated-network-values (when routes-found?
|
||||
(reduce (fn [acc k]
|
||||
(if (or (contains? network-values-keys k)
|
||||
(and to?
|
||||
(not (contains? receiver-networks-set k))))
|
||||
acc
|
||||
(assoc acc k (money/bignumber "0"))))
|
||||
network-values
|
||||
disabled-chain-ids))]
|
||||
(cond-> (->> updated-network-values
|
||||
(map
|
||||
(fn [[k v]]
|
||||
{:chain-id k
|
||||
:total-amount v
|
||||
:type (if (or to? (not (contains? disabled-set k))) :default :disabled)}))
|
||||
(sort-by #(get network-priority-score (network-utils/id->network (:chain-id %))))
|
||||
(filter
|
||||
#(or (and to?
|
||||
(or (contains? receiver-networks-set (:chain-id %))
|
||||
(money/greater-than (:total-amount %) (money/bignumber "0"))))
|
||||
(not to?)))
|
||||
(vec))
|
||||
(and to?
|
||||
[{:keys [network-values disabled-chain-ids receiver-networks token-networks-ids receiver?]}]
|
||||
(let [disabled-set (set disabled-chain-ids)
|
||||
receiver-networks-set (set receiver-networks)
|
||||
network-values-keys (set (keys network-values))
|
||||
routes-found? (pos? (count network-values-keys))
|
||||
token-networks-ids-set (set token-networks-ids)
|
||||
not-available-networks (if receiver?
|
||||
(filter #(not (token-networks-ids-set %))
|
||||
receiver-networks)
|
||||
[])
|
||||
not-available-networks-set (set not-available-networks)
|
||||
network-values-with-disabled-chains (when routes-found?
|
||||
(reduce
|
||||
(fn [acc k]
|
||||
(if (or (contains? network-values-keys k)
|
||||
(and receiver?
|
||||
(not (contains? receiver-networks-set
|
||||
k))))
|
||||
acc
|
||||
(assoc acc k (money/bignumber "0"))))
|
||||
network-values
|
||||
disabled-chain-ids))
|
||||
network-values-with-not-available-chains (if (and receiver? routes-found?)
|
||||
(let [network-values-keys
|
||||
(set (keys
|
||||
network-values-with-disabled-chains))]
|
||||
(reduce
|
||||
(fn [acc k]
|
||||
(if (not (contains? network-values-keys k))
|
||||
(assoc acc k nil)
|
||||
acc))
|
||||
network-values-with-disabled-chains
|
||||
not-available-networks))
|
||||
network-values-with-disabled-chains)]
|
||||
(cond-> (->>
|
||||
network-values-with-not-available-chains
|
||||
(map
|
||||
(fn [[chain-id amount]]
|
||||
{:chain-id chain-id
|
||||
:total-amount amount
|
||||
:type (cond
|
||||
(contains? not-available-networks-set chain-id) :not-available
|
||||
(or receiver? (not (contains? disabled-set chain-id))) :default
|
||||
(and (not receiver?) (contains? disabled-set chain-id)) :disabled)}))
|
||||
(sort-by (fn [network-amount]
|
||||
(get network-priority-score
|
||||
(network-utils/id->network (:chain-id network-amount)))))
|
||||
(filter
|
||||
(fn [network-amount]
|
||||
(or (and receiver?
|
||||
(or (contains? receiver-networks-set (:chain-id network-amount))
|
||||
(money/greater-than (:total-amount network-amount) (money/bignumber "0"))))
|
||||
(not receiver?))))
|
||||
(vec))
|
||||
(and receiver?
|
||||
routes-found?
|
||||
(< (count updated-network-values) available-networks-count))
|
||||
(< (count network-values-with-not-available-chains) available-networks-count))
|
||||
(conj {:type :add}))))
|
||||
|
||||
(defn loading-network-amounts
|
||||
[valid-networks disabled-chain-ids receiver-networks to?]
|
||||
(let [disabled-set (set disabled-chain-ids)
|
||||
receiver-networks-set (set receiver-networks)
|
||||
receiver-networks-count (count receiver-networks)
|
||||
valid-networks (concat valid-networks disabled-chain-ids)]
|
||||
[{:keys [valid-networks disabled-chain-ids receiver-networks token-networks-ids receiver?]}]
|
||||
(let [disabled-set (set disabled-chain-ids)
|
||||
receiver-networks-set (set receiver-networks)
|
||||
receiver-networks-count (count receiver-networks)
|
||||
token-networks-ids-set (set token-networks-ids)
|
||||
valid-networks-set (set valid-networks)
|
||||
not-available-networks (if receiver?
|
||||
(filter #(not (token-networks-ids-set %)) receiver-networks)
|
||||
[])
|
||||
not-available-networks-set (set not-available-networks)
|
||||
valid-networks (concat valid-networks
|
||||
disabled-chain-ids
|
||||
(when receiver?
|
||||
(filter #(not (valid-networks-set %))
|
||||
not-available-networks)))]
|
||||
(cond-> (->> valid-networks
|
||||
(map (fn [k]
|
||||
(cond-> {:chain-id k
|
||||
:type (if (or to?
|
||||
(not (contains? disabled-set k)))
|
||||
:loading
|
||||
:disabled)}
|
||||
(and (not to?) (contains? disabled-set k))
|
||||
(assoc :total-amount (money/bignumber "0")))))
|
||||
(sort-by (fn [item]
|
||||
(map
|
||||
(fn [chain-id]
|
||||
(cond->
|
||||
{:chain-id chain-id
|
||||
:type (cond
|
||||
(contains? not-available-networks-set chain-id) :not-available
|
||||
(or receiver?
|
||||
(not (contains? disabled-set chain-id))) :loading
|
||||
(and (not receiver?) (contains? disabled-set chain-id)) :disabled)}
|
||||
(and (not receiver?) (contains? disabled-set chain-id))
|
||||
(assoc :total-amount (money/bignumber "0")))))
|
||||
(sort-by (fn [network-amount]
|
||||
(get network-priority-score
|
||||
(network-utils/id->network (:chain-id item)))))
|
||||
(network-utils/id->network (:chain-id network-amount)))))
|
||||
(filter
|
||||
#(or (and to? (contains? receiver-networks-set (:chain-id %)))
|
||||
(and (not to?)
|
||||
(not (contains? disabled-chain-ids (:chain-id %))))))
|
||||
(fn [network-amount]
|
||||
(or (and receiver? (contains? receiver-networks-set (:chain-id network-amount)))
|
||||
(and (not receiver?)
|
||||
(not (contains? disabled-chain-ids (:chain-id network-amount)))))))
|
||||
(vec))
|
||||
(and to? (< receiver-networks-count available-networks-count)) (conj {:type :add}))))
|
||||
(and receiver? (< receiver-networks-count available-networks-count)) (conj {:type :add}))))
|
||||
|
||||
(defn network-links
|
||||
[route from-values-by-chain to-values-by-chain]
|
||||
|
@ -38,11 +38,11 @@
|
||||
:to {:chain-id "2"}}]
|
||||
token-decimals 18
|
||||
native-token? true
|
||||
to? true
|
||||
receiver? true
|
||||
result (utils/network-amounts-by-chain {:route route
|
||||
:token-decimals token-decimals
|
||||
:native-token? native-token?
|
||||
:to? to?})
|
||||
:receiver? receiver?})
|
||||
expected {"1" (money/bignumber "1")
|
||||
"2" (money/bignumber "1")}]
|
||||
(doseq [[chain-id exp-value] expected]
|
||||
@ -56,11 +56,11 @@
|
||||
:to {:chain-id "1"}}]
|
||||
token-decimals 18
|
||||
native-token? true
|
||||
to? true
|
||||
receiver? true
|
||||
result (utils/network-amounts-by-chain {:route route
|
||||
:token-decimals token-decimals
|
||||
:native-token? native-token?
|
||||
:to? to?})
|
||||
:receiver? receiver?})
|
||||
expected {"1" (money/bignumber "2")}]
|
||||
(doseq [[chain-id exp-value] expected]
|
||||
(is (money/equal-to (get result chain-id) exp-value)))))
|
||||
@ -72,11 +72,11 @@
|
||||
:from {:chain-id "2"}}]
|
||||
token-decimals 6
|
||||
native-token? false
|
||||
to? false
|
||||
receiver? false
|
||||
result (utils/network-amounts-by-chain {:route route
|
||||
:token-decimals token-decimals
|
||||
:native-token? native-token?
|
||||
:to? to?})
|
||||
:receiver? receiver?})
|
||||
expected {"1" (money/bignumber "2")
|
||||
"2" (money/bignumber "2")}]
|
||||
(doseq [[chain-id exp-value] expected]
|
||||
@ -268,12 +268,13 @@
|
||||
(is (every? identity comparisons)))))
|
||||
|
||||
(deftest test-network-amounts
|
||||
(testing "Handles disabled and receiver networks correctly when to? is true"
|
||||
(testing "Handles disabled and receiver networks correctly when receiver? is true"
|
||||
(let [network-values {"1" (money/bignumber "100")
|
||||
"10" (money/bignumber "200")}
|
||||
disabled-chain-ids ["1"]
|
||||
receiver-networks ["10"]
|
||||
to? true
|
||||
token-networks-ids ["1" "10" "42161"]
|
||||
receiver? true
|
||||
expected [{:chain-id "1"
|
||||
:total-amount (money/bignumber "100")
|
||||
:type :default}
|
||||
@ -281,39 +282,44 @@
|
||||
:total-amount (money/bignumber "200")
|
||||
:type :default}
|
||||
{:type :add}]
|
||||
result (utils/network-amounts network-values
|
||||
disabled-chain-ids
|
||||
receiver-networks
|
||||
to?)]
|
||||
result (utils/network-amounts {:network-values network-values
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})]
|
||||
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
|
||||
|
||||
(testing "Adds default amount for non-disabled non-receiver networks when to? is false"
|
||||
(testing "Adds default amount for non-disabled non-receiver networks when receiver? is false"
|
||||
(let [network-values {"1" (money/bignumber "100")}
|
||||
disabled-chain-ids ["10"]
|
||||
receiver-networks []
|
||||
to? false
|
||||
token-networks-ids ["1" "10" "42161"]
|
||||
receiver? false
|
||||
expected [{:chain-id "1"
|
||||
:total-amount (money/bignumber "100")
|
||||
:type :default}
|
||||
{:chain-id "10"
|
||||
:total-amount (money/bignumber "0")
|
||||
:type :disabled}]
|
||||
result (utils/network-amounts network-values
|
||||
disabled-chain-ids
|
||||
receiver-networks
|
||||
to?)]
|
||||
result (utils/network-amounts {:network-values network-values
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})]
|
||||
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
|
||||
|
||||
(testing "Handles empty inputs correctly"
|
||||
(let [network-values {}
|
||||
disabled-chain-ids []
|
||||
receiver-networks []
|
||||
to? true
|
||||
token-networks-ids []
|
||||
receiver? true
|
||||
expected []
|
||||
result (utils/network-amounts network-values
|
||||
disabled-chain-ids
|
||||
receiver-networks
|
||||
to?)]
|
||||
result (utils/network-amounts {:network-values network-values
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})]
|
||||
(is (= expected result))))
|
||||
|
||||
(testing "Processes case with multiple network interactions"
|
||||
@ -322,7 +328,8 @@
|
||||
"42161" (money/bignumber "500")}
|
||||
disabled-chain-ids ["1" "42161"]
|
||||
receiver-networks ["10"]
|
||||
to? true
|
||||
token-networks-ids ["1" "10" "42161"]
|
||||
receiver? true
|
||||
expected [{:chain-id "1"
|
||||
:total-amount (money/bignumber "300")
|
||||
:type :default}
|
||||
@ -332,10 +339,50 @@
|
||||
{:chain-id "42161"
|
||||
:total-amount (money/bignumber "500")
|
||||
:type :default}]
|
||||
result (utils/network-amounts network-values
|
||||
disabled-chain-ids
|
||||
receiver-networks
|
||||
to?)]
|
||||
result (utils/network-amounts {:network-values network-values
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})]
|
||||
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
|
||||
|
||||
(testing "Does not assign :not-available type when receiver? is false"
|
||||
(let [network-values {"1" (money/bignumber "100")}
|
||||
disabled-chain-ids ["10"]
|
||||
receiver-networks ["1"]
|
||||
token-networks-ids ["1" "10"]
|
||||
receiver? false
|
||||
expected [{:chain-id "1"
|
||||
:total-amount (money/bignumber "100")
|
||||
:type :default}
|
||||
{:chain-id "10"
|
||||
:total-amount (money/bignumber "0")
|
||||
:type :disabled}]
|
||||
result (utils/network-amounts {:network-values network-values
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})]
|
||||
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
|
||||
|
||||
(testing
|
||||
"Assigns :not-available type to networks not available in token-networks-ids when receiver? is true"
|
||||
(let [network-values {"1" (money/bignumber "100")}
|
||||
disabled-chain-ids []
|
||||
receiver-networks ["1" "10"]
|
||||
token-networks-ids ["1"]
|
||||
receiver? false
|
||||
expected [{:chain-id "1"
|
||||
:total-amount (money/bignumber "100")
|
||||
:type :default}
|
||||
{:chain-id "10"
|
||||
:total-amount nil
|
||||
:type :not-available}]
|
||||
result (utils/network-amounts {:network-values network-values
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})]
|
||||
(is (every? identity (map #(map/deep-compare %1 %2) expected result))))))
|
||||
|
||||
(deftest test-loading-network-amounts
|
||||
@ -343,63 +390,109 @@
|
||||
(let [valid-networks ["1" "10" "42161"]
|
||||
disabled-chain-ids ["42161"]
|
||||
receiver-networks ["1" "10"]
|
||||
to? true
|
||||
token-networks-ids ["1" "10" "42161"]
|
||||
receiver? true
|
||||
expected [{:chain-id "1" :type :loading}
|
||||
{:chain-id "10" :type :loading}
|
||||
{:type :add}]
|
||||
result (utils/loading-network-amounts valid-networks
|
||||
disabled-chain-ids
|
||||
receiver-networks
|
||||
to?)
|
||||
result (utils/loading-network-amounts {:valid-networks valid-networks
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})
|
||||
comparisons (map #(map/deep-compare %1 %2)
|
||||
expected
|
||||
result)]
|
||||
(is (every? identity comparisons))))
|
||||
|
||||
(testing "Assigns :disabled type with zero total-amount to disabled networks when to? is false"
|
||||
(testing "Assigns :disabled type with zero total-amount to disabled networks when receiver? is false"
|
||||
(let [valid-networks ["1" "10" "42161"]
|
||||
disabled-chain-ids ["10" "42161"]
|
||||
receiver-networks ["1"]
|
||||
to? false
|
||||
token-networks-ids ["1" "10" "42161"]
|
||||
receiver? false
|
||||
expected [{:chain-id "1" :type :loading}
|
||||
{:chain-id "10" :type :disabled :total-amount (money/bignumber "0")}
|
||||
{:chain-id "42161" :type :disabled :total-amount (money/bignumber "0")}]
|
||||
result (utils/loading-network-amounts valid-networks
|
||||
disabled-chain-ids
|
||||
receiver-networks
|
||||
to?)
|
||||
result (utils/loading-network-amounts {:valid-networks valid-networks
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})
|
||||
comparisons (map #(map/deep-compare %1 %2)
|
||||
expected
|
||||
result)]
|
||||
(is (every? identity comparisons))))
|
||||
|
||||
(testing "Filters out networks not in receiver networks when to? is true"
|
||||
(testing "Filters out networks not in receiver networks when receiver? is true"
|
||||
(let [valid-networks ["1" "10" "42161" "59144"]
|
||||
disabled-chain-ids ["10"]
|
||||
receiver-networks ["1" "42161"]
|
||||
to? true
|
||||
token-networks-ids ["1" "10" "42161"]
|
||||
receiver? true
|
||||
expected [{:chain-id "1" :type :loading}
|
||||
{:chain-id "42161" :type :loading}]
|
||||
result (utils/loading-network-amounts valid-networks
|
||||
disabled-chain-ids
|
||||
receiver-networks
|
||||
to?)
|
||||
result (utils/loading-network-amounts {:valid-networks valid-networks
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})
|
||||
comparisons (map #(map/deep-compare %1 %2)
|
||||
expected
|
||||
result)]
|
||||
(is (every? identity comparisons))))
|
||||
|
||||
(testing "Appends :add type if receiver network count is less than available networks and to? is true"
|
||||
(testing
|
||||
"Appends :add type if receiver network count is less than available networks and receiver? is true"
|
||||
(let [valid-networks ["1" "10" "42161"]
|
||||
disabled-chain-ids ["10"]
|
||||
receiver-networks ["1"]
|
||||
to? true
|
||||
token-networks-ids ["1" "10" "42161"]
|
||||
receiver? true
|
||||
expected [{:chain-id "1" :type :loading}
|
||||
{:type :add}]
|
||||
result (utils/loading-network-amounts valid-networks
|
||||
disabled-chain-ids
|
||||
receiver-networks
|
||||
to?)
|
||||
result (utils/loading-network-amounts {:valid-networks valid-networks
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})
|
||||
comparisons (map #(map/deep-compare %1 %2)
|
||||
expected
|
||||
result)]
|
||||
(is (every? identity comparisons))))
|
||||
|
||||
(testing
|
||||
"Assigns :not-available type to networks not available in token-networks-ids when receiver? is false"
|
||||
(let [valid-networks ["42161"]
|
||||
disabled-chain-ids []
|
||||
receiver-networks ["1"]
|
||||
token-networks-ids ["42161"]
|
||||
receiver? false
|
||||
expected [{:chain-id "42161" :type :loading}]
|
||||
result (utils/loading-network-amounts {:valid-networks valid-networks
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})
|
||||
comparisons (map #(map/deep-compare %1 %2)
|
||||
expected
|
||||
result)]
|
||||
(is (every? identity comparisons))))
|
||||
|
||||
(testing
|
||||
"Assigns :not-available type to networks not available in token-networks-ids when receiver? is true"
|
||||
(let [valid-networks ["42161"]
|
||||
disabled-chain-ids []
|
||||
receiver-networks ["1"]
|
||||
token-networks-ids ["42161"]
|
||||
receiver? true
|
||||
expected [{:chain-id "1" :type :not-available}
|
||||
{:type :add}]
|
||||
result (utils/loading-network-amounts {:valid-networks valid-networks
|
||||
:disabled-chain-ids disabled-chain-ids
|
||||
:receiver-networks receiver-networks
|
||||
:token-networks-ids token-networks-ids
|
||||
:receiver? receiver?})
|
||||
comparisons (map #(map/deep-compare %1 %2)
|
||||
expected
|
||||
result)]
|
||||
|
@ -12,3 +12,26 @@
|
||||
(def data-item
|
||||
{:margin-horizontal 20
|
||||
:margin-vertical 8})
|
||||
|
||||
(defn warning-container
|
||||
[sending-to-unpreferred-networks?]
|
||||
{:flex-direction :row
|
||||
:margin-horizontal 20
|
||||
:margin-bottom (when sending-to-unpreferred-networks? 8)
|
||||
:align-items :center})
|
||||
|
||||
(defn sending-to-unpreferred-networks-alert-container
|
||||
[theme]
|
||||
{:height 76
|
||||
:flex-direction :row
|
||||
:background-color (colors/resolve-color :blue theme 5)
|
||||
:border-color (colors/resolve-color :blue theme 10)
|
||||
:border-width 1
|
||||
:border-radius 12
|
||||
:margin-horizontal 20
|
||||
:padding 10})
|
||||
|
||||
(def sending-to-unpreferred-networks-text
|
||||
{:flex 1
|
||||
:height 54.6
|
||||
:margin-left 8})
|
||||
|
@ -3,6 +3,7 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
@ -11,12 +12,14 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [selected-networks account watch-only?]}]
|
||||
[{:keys [title first-section-label second-section-label selected-networks
|
||||
receiver-preferred-networks account watch-only?]}]
|
||||
(let [state (reagent/atom :default)
|
||||
{:keys [color address
|
||||
network-preferences-names]} (or account (rf/sub [:wallet/current-viewing-account]))
|
||||
initial-network-preferences-names (or selected-networks network-preferences-names)
|
||||
network-preferences-names-state (reagent/atom #{})
|
||||
receiver? (boolean (not-empty receiver-preferred-networks))
|
||||
network-preferences-names-state (reagent/atom (if receiver? selected-networks #{}))
|
||||
toggle-network (fn [network-name]
|
||||
(reset! state :changed)
|
||||
(let [contains-network? (contains?
|
||||
@ -34,15 +37,30 @@
|
||||
(if (= @state :default)
|
||||
initial-network-preferences-names
|
||||
@network-preferences-names-state))]
|
||||
(fn [{:keys [on-save blur? button-label]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
network-details (rf/sub [:wallet/network-details])
|
||||
mainnet (first network-details)
|
||||
layer-2-networks (rest network-details)
|
||||
current-networks (filter (fn [network]
|
||||
(contains? (get-current-preferences-names)
|
||||
(:network-name network)))
|
||||
network-details)]
|
||||
(fn [{:keys [on-save on-change blur? button-label first-section-warning-label
|
||||
second-section-warning-label]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
network-details (rf/sub [:wallet/network-details])
|
||||
first-section-networks (filter (fn [network]
|
||||
(if receiver-preferred-networks
|
||||
(some (fn [chain-id]
|
||||
(= (:chain-id network) chain-id))
|
||||
receiver-preferred-networks)
|
||||
(= (:network-name network) :mainnet)))
|
||||
network-details)
|
||||
second-section-networks (remove (fn [network]
|
||||
(some (fn [chain-id]
|
||||
(= (:chain-id network) chain-id))
|
||||
(map :chain-id first-section-networks)))
|
||||
network-details)
|
||||
current-networks (filter (fn [network]
|
||||
(contains? (get-current-preferences-names)
|
||||
(:network-name network)))
|
||||
network-details)
|
||||
sending-to-unpreferred-networks? (and receiver?
|
||||
(some #(contains? @network-preferences-names-state
|
||||
(:network-name %))
|
||||
second-section-networks))]
|
||||
[:<>
|
||||
;; quo/overlay isn't compatible with sheets
|
||||
(when blur?
|
||||
@ -51,52 +69,103 @@
|
||||
:blur-amount 20
|
||||
:blur-radius 25}])
|
||||
[quo/drawer-top
|
||||
{:title (i18n/label :t/network-preferences)
|
||||
:description (if watch-only?
|
||||
(i18n/label :t/network-preferences-desc-1)
|
||||
(i18n/label :t/network-preferences-desc-2))
|
||||
{:title (or title (i18n/label :t/network-preferences))
|
||||
:description (when-not receiver?
|
||||
(if watch-only?
|
||||
(i18n/label :t/network-preferences-desc-1)
|
||||
(i18n/label :t/network-preferences-desc-2)))
|
||||
:blur? blur?}]
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:size :default
|
||||
:description :default
|
||||
:label :none
|
||||
:blur? blur?
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (fn []
|
||||
[quo/address-text
|
||||
{:networks current-networks
|
||||
:address address
|
||||
:blur? blur?
|
||||
:format :long}])
|
||||
:container-style (merge style/data-item
|
||||
{:background-color (colors/theme-colors colors/neutral-2_5
|
||||
colors/neutral-90
|
||||
theme)})}]
|
||||
(when-not receiver?
|
||||
[quo/data-item
|
||||
{:status :default
|
||||
:size :default
|
||||
:description :default
|
||||
:label :none
|
||||
:blur? blur?
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:custom-subtitle (fn []
|
||||
[quo/address-text
|
||||
{:networks current-networks
|
||||
:address address
|
||||
:blur? blur?
|
||||
:format :long}])
|
||||
:container-style (merge style/data-item
|
||||
{:background-color (colors/theme-colors colors/neutral-2_5
|
||||
colors/neutral-90
|
||||
theme)})}])
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:blur? blur?
|
||||
:data [(utils/make-network-item {:state @state
|
||||
:network-name (:network-name mainnet)
|
||||
:color color
|
||||
:blur? blur?
|
||||
:networks (get-current-preferences-names)
|
||||
:on-change #(toggle-network (:network-name
|
||||
mainnet))})]}]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:blur? blur?
|
||||
:label (i18n/label :t/layer-2)
|
||||
:label (when first-section-label first-section-label)
|
||||
:data (mapv (fn [network]
|
||||
(utils/make-network-item {:state @state
|
||||
:network-name (:network-name network)
|
||||
:color color
|
||||
:blur? blur?
|
||||
:networks (get-current-preferences-names)
|
||||
:on-change #(toggle-network (:network-name
|
||||
network))}))
|
||||
layer-2-networks)}]
|
||||
(utils/make-network-item
|
||||
{:state @state
|
||||
:network-name (:network-name network)
|
||||
:color color
|
||||
:normal-checkbox? receiver?
|
||||
:networks (get-current-preferences-names)
|
||||
:type :checkbox
|
||||
:on-change (fn []
|
||||
(toggle-network (:network-name
|
||||
network))
|
||||
(when on-change
|
||||
(let [chain-ids (map :chain-id current-networks)]
|
||||
(on-change chain-ids))))}))
|
||||
first-section-networks)}]
|
||||
(when first-section-warning-label
|
||||
[rn/view
|
||||
{:style (style/warning-container false)}
|
||||
[quo/icon :i/alert
|
||||
{:size 16
|
||||
:color colors/danger-50}]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style {:margin-left 4
|
||||
:color colors/danger-50}}
|
||||
first-section-warning-label]])
|
||||
(when (not-empty second-section-networks)
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:blur? blur?
|
||||
:label (or second-section-label (i18n/label :t/layer-2))
|
||||
:data (mapv (fn [network]
|
||||
(utils/make-network-item
|
||||
{:state @state
|
||||
:network-name (:network-name network)
|
||||
:color color
|
||||
:normal-checkbox? receiver?
|
||||
:networks (get-current-preferences-names)
|
||||
:type :checkbox
|
||||
:on-change (fn []
|
||||
(toggle-network (:network-name
|
||||
network))
|
||||
(when on-change
|
||||
(let [chain-ids (map :chain-id current-networks)]
|
||||
(on-change chain-ids))))}))
|
||||
second-section-networks)}])
|
||||
(when second-section-warning-label
|
||||
[rn/view
|
||||
{:style (style/warning-container sending-to-unpreferred-networks?)}
|
||||
[quo/icon :i/alert
|
||||
{:size 16
|
||||
:color colors/danger-50}]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style {:margin-left 4
|
||||
:color colors/danger-50}}
|
||||
second-section-warning-label]])
|
||||
(when sending-to-unpreferred-networks?
|
||||
[rn/view {:style (style/sending-to-unpreferred-networks-alert-container theme)}
|
||||
[rn/view
|
||||
[quo/icon :i/alert
|
||||
{:size 16
|
||||
:color (colors/resolve-color :blue theme)
|
||||
:container-style {:margin-top 2}}]]
|
||||
[quo/text
|
||||
{:style style/sending-to-unpreferred-networks-text
|
||||
:size :paragraph-2}
|
||||
(i18n/label :t/sending-to-networks-the-receiver-does-not-prefer)]])
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:blur? blur?
|
||||
|
@ -0,0 +1,10 @@
|
||||
(ns status-im.contexts.wallet.sheets.unpreferred-networks-alert.style)
|
||||
|
||||
(def sending-to-unpreferred-networks-title
|
||||
{:margin-horizontal 20})
|
||||
|
||||
(def sending-to-unpreferred-networks-text
|
||||
{:flex 1
|
||||
:height 66
|
||||
:margin-horizontal 20
|
||||
:margin-vertical 4})
|
@ -0,0 +1,28 @@
|
||||
(ns status-im.contexts.wallet.sheets.unpreferred-networks-alert.view
|
||||
(:require [quo.core :as quo]
|
||||
[re-frame.core :as rf]
|
||||
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.style :as style]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-confirm]}]
|
||||
[:<>
|
||||
[quo/text
|
||||
{:style style/sending-to-unpreferred-networks-title
|
||||
:size :heading-2
|
||||
:weight :semi-bold}
|
||||
(i18n/label :t/sending-to-unpreferred-networks)]
|
||||
[quo/text
|
||||
{:style style/sending-to-unpreferred-networks-text
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/sending-to-networks-the-receiver-does-not-prefer)]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:on-press #(rf/dispatch [:hide-bottom-sheet])
|
||||
:type :grey}
|
||||
:button-one-label (i18n/label :t/proceed-anyway)
|
||||
:button-one-props {:on-press (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(when on-confirm (on-confirm)))
|
||||
:customization-color :danger}}]])
|
@ -42,3 +42,8 @@
|
||||
(= sender current-viewing-account-address))
|
||||
activities)]
|
||||
(set (map :recipient users-sent-transactions)))))
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/send-token-not-supported-in-receiver-networks?
|
||||
:<- [:wallet/wallet-send]
|
||||
:-> :token-not-supported-in-receiver-networks?)
|
||||
|
@ -88,6 +88,11 @@
|
||||
:<- [:wallet/wallet-send]
|
||||
:-> :receiver-networks)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-receiver-preferred-networks
|
||||
:<- [:wallet/wallet-send]
|
||||
:-> :receiver-preferred-networks)
|
||||
|
||||
(rf/reg-sub
|
||||
:wallet/wallet-send-route
|
||||
:<- [:wallet/wallet-send]
|
||||
|
@ -2624,7 +2624,14 @@
|
||||
"this-account-has-no-activity": "This account has no activity",
|
||||
"this-address-has-activity": "This address has activity",
|
||||
"scanning-for-activity": "Scanning for activity...",
|
||||
"send-community-link": "Send community link",
|
||||
"at-least-one-network-must-be-activated": "At least 1 network must be activated",
|
||||
"status-is-a-secure-messaging-app": "Status is a secure messaging app, crypto wallet and web3 browser built with the state of the art technology"
|
||||
"send-community-link": "Send community link",
|
||||
"status-is-a-secure-messaging-app": "Status is a secure messaging app, crypto wallet and web3 browser built with the state of the art technology",
|
||||
"token-not-available-on-receiver-networks": "{{token-symbol}} is not available on the recipient’s desired networks. Proceed with caution.",
|
||||
"add-networks-token-can-be-sent-to": "Add networks {{token-symbol}} can be sent to",
|
||||
"not-available": "Not available",
|
||||
"token-not-available-on-networks": "{{token-symbol}} is not available on {{networks}}.",
|
||||
"sending-to-networks-the-receiver-does-not-prefer": "Sending to networks the receiver does not prefer may result in recipient having difficulty accessing the sent tokens.",
|
||||
"proceed-anyway": "Proceed anyway",
|
||||
"sending-to-unpreferred-networks": "Sending to unpreferred networks"
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user