Compare commits

..
Author SHA1 Message Date
Omar Basem b311c8be5c lint 2024-05-17 11:48:41 +04:00
75 changed files with 954 additions and 1363 deletions
+1 -1
View File
@@ -255,7 +255,7 @@ status-go-ios: ##@status-go Compile status-go for iOS app
status-go-library: SHELL := /bin/sh
status-go-library: ##@status-go Compile status-go for node-js
unzip -j -o -d ./result/ status-go-library.zip
nix/scripts/build.sh targets.status-go.library
#--------------
# Watch, Build & Review changes
@@ -6,26 +6,24 @@
(h/describe "Drawers: drawer-action"
(h/test "default render"
(h/render-with-theme-provider [drawer-action/view {:accessibility-label :container}])
(h/render-with-theme-provider [drawer-action/view {}])
(h/is-truthy (h/query-by-label-text :container)))
(h/test "on-press-in changes internal state to :pressed"
(h/render-with-theme-provider [drawer-action/view {:accessibility-label :container}])
(h/render-with-theme-provider [drawer-action/view {}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})))
(h/test "render default action with state :selected"
(h/render-with-theme-provider [drawer-action/view
{:state :selected :accessibility-label :container}])
(h/render-with-theme-provider [drawer-action/view {:state :selected}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})
(h/is-truthy (h/query-by-label-text :check-icon)))
(h/test "call on-press"
(let [on-press (h/mock-fn)]
(h/render-with-theme-provider [drawer-action/view
{:on-press on-press :accessibility-label :container}])
(h/render-with-theme-provider [drawer-action/view {:on-press on-press}])
(h/fire-event :on-press (h/get-by-label-text :container))
(h/was-called on-press)))
@@ -40,9 +38,8 @@
(h/test "render :toggle action with state :selected"
(h/render-with-theme-provider [drawer-action/view
{:accessibility-label :container
:action :toggle
:state :selected}])
{:action :toggle
:state :selected}])
(h/is-truthy (h/query-by-label-text "toggle-on"))
(h/has-style (h/query-by-label-text :container)
{:backgroundColor :transparent}))
@@ -54,5 +51,4 @@
:description "Just a small desc"}])
(h/is-truthy (h/query-by-label-text :left-icon))
(h/is-truthy (h/query-by-text "Check contact"))
(h/has-style (h/query-by-text "Check contact") {:color colors/neutral-100})
(h/is-truthy (h/query-by-text "Just a small desc"))))
@@ -4,8 +4,6 @@
[:=>
[:cat
[:map {:closed true}
[:accessibility-label {:optional true} [:maybe :keyword]]
[:type {:optional true} [:maybe [:enum :main :danger]]]
[:action {:optional true} [:maybe [:enum :arrow :toggle]]]
[:icon {:optional true} [:maybe :keyword]]
[:description {:optional true} [:maybe :string]]
@@ -28,23 +28,6 @@
{:flex 1
:margin-right 12})
(defn text
[{:keys [theme blur? type]}]
(let [base {:weight :medium}
theme-with-blur (if blur? :blue theme)
matcher [theme-with-blur type]
color
(case matcher
([:dark :main] [:light :main]) (colors/theme-colors colors/neutral-100
colors/white
theme)
[:blur :main] colors/white-70-blur
([:dark :danger] [:light :danger]) (colors/theme-colors colors/danger-50
colors/danger-60
theme)
[:blur :danger] colors/danger-60)]
(assoc-in base [:style :color] color)))
(defn- neutral-color
[theme blur?]
(if blur?
@@ -58,14 +41,8 @@
:margin-top 1})
(defn icon-color
[{:keys [theme blur? type]}]
(let [theme-with-blur (if blur? :blue theme)
matcher [theme-with-blur type]]
(case matcher
([:dark :main] [:light :main]) (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
[:blur :main] colors/white-70-blur
([:dark :danger] [:light :danger]) (colors/theme-colors colors/danger-50 colors/danger-60 theme)
[:blur :danger] colors/danger-60)))
[{:keys [theme blur?]}]
(neutral-color theme blur?))
(defn desc
[{:keys [theme blur?]}]
@@ -10,13 +10,11 @@
[schema.core :as schema]))
(defn view-internal
[{:keys [action icon description state title on-press customization-color
blur? accessibility-label]
action-type :type
:or {customization-color :blue
blur? false}}]
[{:keys [action icon description state title on-press
customization-color blur?]
:or {customization-color :blue
blur? false}}]
(let [theme (quo.theme/use-theme)
action-type (or action-type :main)
[pressed? set-pressed] (rn/use-state false)
on-press-in (rn/use-callback #(set-pressed true))
on-press-out (rn/use-callback #(set-pressed false))]
@@ -31,21 +29,16 @@
:pressed? pressed?
:description? (not-empty description)
:blur? blur?})
:accessibility-label accessibility-label}
:accessibility-label :container}
(when icon
[icon/icon icon
{:accessibility-label :left-icon
:container-style (style/left-icon)
:color (style/icon-color {:theme theme
:type action-type
:blur? blur?})}])
[rn/view
{:style (style/text-container)}
[text/text
(style/text {:theme theme
:type action-type
:blur? blur?})
[rn/view {:style (style/text-container)}
[text/text {:weight :medium}
title]
(when (seq description)
@@ -68,7 +61,6 @@
[icon/icon :i/chevron-right
{:accessibility-label :arrow-icon
:color (style/icon-color {:theme theme
:type action-type
:blur? blur?})}]
(= state :selected)
@@ -133,7 +133,8 @@
:on-focus on-focus
:on-blur on-blur
:on-change-text on-change}]
(when (empty? value)
(when (or (= status :default)
(= status :active))
[rn/view
{:style style/buttons-container
:accessibility-label :paste-scan-buttons-container}
@@ -154,9 +155,7 @@
:inner-style (style/accessory-button blur? theme)
:on-press on-scan}
:main-icons/scan])])
(when (or (= status :typing)
(and (= status :active)
(not-empty value)))
(when (= status :typing)
[rn/view
{:style style/buttons-container
:accessibility-label :clear-button-container}
@@ -169,10 +168,7 @@
{:style style/buttons-container
:accessibility-label :loading-button-container}
[loading-icon blur? theme]])
(when (and (or (= status :loading)
(= status :default))
valid-ens-or-address?
(not-empty value))
(when (and (= status :loading) valid-ens-or-address?)
[rn/view
{:style style/buttons-container
:accessibility-label :positive-button-container}
+42 -17
View File
@@ -3,14 +3,39 @@
[quo.foundations.colors :as colors]
[react-native.platform :as platform]))
(defn- primary-name-top-offset
[size]
(when (= size 15)
(cond platform/ios? 1
platform/android? -0.5
:else 0)))
(defn- primary-name-margin-bottom-offset
[size]
(when (and (= size 15)
(or platform/ios? platform/android?))
-0.25))
(defn- primary-name-layout-offsets
[size]
;; NOTE(seanstrom): We need to sometimes offset the primary-name to align the baseline of the text
;; while avoiding shifting elements downward.
{:top (primary-name-top-offset size)
:margin-bottom (primary-name-margin-bottom-offset size)})
(defn container
[size]
(cond->
{:flex-shrink 1
:flex-wrap :nowrap
:flex-direction :row
:align-items :center
:height (if (= size 15) 22 18)}))
{:flex-shrink 1
:flex-wrap :nowrap
:flex-direction :row
:align-items :baseline
;; NOTE(seanstrom): Because we're offseting the primary-name we need to inverse the offset on the
;; container to avoid shifting elements downward
:top (* -1 (primary-name-top-offset size))})
(def details-container
{:flex-direction :row
:margin-left 8})
(defn middle-dot
[theme]
@@ -23,15 +48,11 @@
(defn primary-name
[muted? theme size]
{:color (if muted?
colors/neutral-50
(colors/theme-colors colors/neutral-100 colors/white theme))
;; iOS: primary-name height is 22.3 / 18.7
;; Android: primary-name height is 21.8 / 18.5
:margin-vertical (if (= size 15)
(if platform/ios? -0.15 0)
(if platform/ios? -0.35 -0.25))
:flex-shrink 1})
(merge (primary-name-layout-offsets size)
{:color (if muted?
colors/neutral-50
(colors/theme-colors colors/neutral-100 colors/white theme))
:flex-shrink 1}))
(defn secondary-name
[theme]
@@ -39,9 +60,13 @@
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(defn icon-container
[is-first? size]
[is-first?]
{:margin-left (if is-first? 4 2)
:padding-top (if (= size 15) 6 4)})
;; NOTE(seanstrom): Because we're using flex baseline to align elements
;; we need to offset the icon container to match the designs.
:top (cond platform/ios? 1
platform/android? 2
:else 0)})
(defn time-text
[theme]
+28 -40
View File
@@ -13,35 +13,7 @@
[{:keys [primary-name secondary-name style short-chat-key time-str contact? verified? untrustworthy?
muted? size]
:or {size 13}}]
(let [theme (quo.theme/use-theme)
short-chat-key-component
(when (and (not verified?) short-chat-key)
[text/text
{:weight :monospace
:size :label
:number-of-lines 1
:style (style/chat-key-text theme)}
short-chat-key])
time-str-component
(when time-str
[text/text
{:monospace true
:size :label
:accessibility-label :message-timestamp
:number-of-lines 1
:style (style/time-text theme)}
time-str])
middle-dot-seperator-component
(when (and short-chat-key-component time-str-component)
[text/text
{:monospace true
:size :label
:number-of-lines 1
:style (style/middle-dot theme)}
middle-dot])]
(let [theme (quo.theme/use-theme)]
[rn/view
{:style (merge (style/container size) style)}
[text/text
@@ -51,7 +23,7 @@
:accessibility-label :author-primary-name
:style (style/primary-name muted? theme size)}
primary-name]
(when-not (string/blank? secondary-name)
(when (not (string/blank? secondary-name))
[:<>
[text/text
{:size :label
@@ -69,22 +41,38 @@
[icons/icon :main-icons2/contact
{:size 12
:no-color true
:container-style (style/icon-container true size)}])
:container-style (style/icon-container true)}])
(cond
verified?
[icons/icon :main-icons2/verified
{:size 12
:no-color true
:container-style (style/icon-container contact? size)}]
:container-style (style/icon-container contact?)}]
untrustworthy?
[icons/icon :main-icons2/untrustworthy
{:size 12
:no-color true
:container-style (style/icon-container contact? size)}])
(when (or short-chat-key-component time-str-component)
[rn/view {:style {:width 8}}])
short-chat-key-component
middle-dot-seperator-component
time-str-component]))
:container-style (style/icon-container contact?)}])
[rn/view {:style style/details-container}
(when (and (not verified?) short-chat-key)
[text/text
{:weight :monospace
:size :label
:number-of-lines 1
:style (style/chat-key-text theme)}
short-chat-key])
(when (and (not verified?) time-str short-chat-key)
[text/text
{:monospace true
:size :label
:number-of-lines 1
:style (style/middle-dot theme)}
middle-dot])
(when time-str
[text/text
{:monospace true
:size :label
:accessibility-label :message-timestamp
:number-of-lines 1
:style (style/time-text theme)}
time-str])]]))
@@ -261,10 +261,7 @@
{:opacity center-opacity}
nil)
(style/center-content-container
(case type
:title (= text-align :center)
(:dropdown :wallet-networks) true
false)))
(and (= type :title) (= text-align :center))))
props-with-style (assoc props
:center-content-container-style
center-content-container-style)]
+2 -3
View File
@@ -5,8 +5,7 @@
[react-native.core :as rn]))
(defn view
[{:keys [reactions on-press on-long-press hide-new-reaction-button? on-press-add use-case
container-style]}]
[{:keys [reactions on-press on-long-press add-reaction? on-press-add use-case container-style]}]
[rn/view {:style (merge style/container container-style)}
(for [emoji-reaction reactions
:let [{:keys [emoji emoji-id emoji-reaction-id quantity own]} emoji-reaction]]
@@ -20,7 +19,7 @@
:on-press #(on-press emoji-reaction)
:on-long-press #(on-long-press emoji-reaction)
:accessibility-label (str "emoji-reaction-" emoji-id)}])
(when-not hide-new-reaction-button?
(when add-reaction?
[react-selector/view
{:on-press on-press-add
:state :add-reaction
@@ -1,31 +1,12 @@
(ns quo.components.selectors.reactions-selector.style
(:require
[quo.foundations.colors :as colors]
[react-native.platform :as platform]))
[quo.foundations.colors :as colors]))
(defn container
[pressed? theme]
(merge
{:border-radius 12
:border-width 1
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color (when pressed?
(colors/theme-colors colors/neutral-10 colors/neutral-80-opa-40 theme))}
(if platform/ios?
{:padding 9.5
:padding-horizontal 8}
{:padding 8})))
(def emoji-text-style
(merge
{:line-height 20
:text-align :center}
(if platform/ios?
{:line-height 20
:font-size 17
:text-align :center}
{:font-size 18
:height 24
:width 24
:text-align :center
:text-align-vertical :center})))
{:padding 10
:border-radius 12
:border-width 1
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:background-color (when pressed?
(colors/theme-colors colors/neutral-10 colors/neutral-80-opa-40 theme))})
@@ -20,6 +20,4 @@
:style (merge (style/container pressed? theme)
container-style)
:on-press on-press}
[rn/text
{:style style/emoji-text-style}
(reactions.resource/system-emojis emoji)]]))
[rn/text (reactions.resource/system-emojis emoji)]]))
@@ -6,8 +6,7 @@
[:props
[:map {:closed true}
[:status {:optional true} [:maybe [:enum :default :error]]]
[:on-inc-press {:optional true} [:maybe fn?]]
[:on-dec-press {:optional true} [:maybe fn?]]
[:on-change-text {:optional true} [:maybe fn?]]
[:container-style {:optional true} [:maybe :map]]
[:min-value {:optional true} [:maybe :int]]
[:max-value {:optional true} [:maybe :int]]
@@ -13,7 +13,7 @@
:name "Trip to Vegas"
:address "0x0ah...71a"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]
{:network-name :optimism :short-name "opt"}]
:action :none}])
(def default-details
@@ -48,7 +48,7 @@
(when show-optimism?
[network-amount
{:network :optimism
:amount (str (:amount optimism) " " (or (:token-symbol optimism) "OETH"))
:amount (str (:amount optimism) " " (or (:token-symbol optimism) "OPT"))
:divider? show-arbitrum?
:theme theme}])
(when show-arbitrum?
@@ -6,16 +6,14 @@
(h/describe "Wallet: Token Input"
(h/test "Token label renders"
(h/render-with-theme-provider [token-input/view
{:token :snt
:currency :eur
:currency-symbol "€"
:conversion 1}])
{:token :snt
:currency :eur
:conversion 1}])
(h/is-truthy (h/get-by-text "SNT")))
(h/test "Amount renders"
(h/render-with-theme-provider [token-input/view
{:token :snt
:currency :eur
:currency-symbol "€"
:conversion 1}])
{:token :snt
:currency :eur
:conversion 1}])
(h/is-truthy (h/get-by-text "€0.00"))))
@@ -12,22 +12,30 @@
{:padding-horizontal 20
:padding-bottom 4
:height 36
:flex-direction :row})
:flex-direction :row
:justify-content :space-between})
(defn token-name
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:padding-bottom 3})
:margin-right 8
:padding-bottom 2})
(def text-input-container
{:flex-direction :row
(def token-label-container
{:position :absolute
:left 40 ; token image size + margin
:right 0
:bottom 0
:top 0
:flex-direction :row
:align-items :flex-end})
(defn input-container
[window-width]
{:width (- window-width 120)
:margin-left 8
:margin-right 8})
(def text-input-container
{:position :absolute
:top 0
:bottom 0
:left 40 ; token image size + margin
:right 0})
(def text-input-dimensions
(-> typography/heading-1
@@ -46,8 +54,7 @@
:color
(if error?
(colors/resolve-color :danger theme)
(colors/theme-colors colors/neutral-100 colors/white theme))
:flex-shrink 1))
(colors/theme-colors colors/neutral-100 colors/white theme))))
(defn placeholder-text
[theme]
+61 -51
View File
@@ -9,34 +9,32 @@
[quo.components.utilities.token.view :as token]
[quo.components.wallet.token-input.schema :as component-schema]
[quo.components.wallet.token-input.style :as style]
[quo.foundations.common :as common]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[schema.core :as schema]
[utils.number :as number]))
[schema.core :as schema]))
(defn fiat-format
[currency-symbol num-value conversion]
(str currency-symbol (.toFixed (* num-value conversion) 2)))
[currency num-value conversion]
(str (get common/currency-label currency) (.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)))
(str (.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]}]
[{:keys [crypto? currency 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)
(fiat-format currency 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?]}]
[{:keys [theme token crypto-decimals conversion networks title crypto? currency amount error?]}]
[rn/view {:style style/data-container}
[network-tag/view
{:networks networks
@@ -47,7 +45,7 @@
:weight :medium
:style (style/fiat-amount theme)}
(calc-value {:crypto? crypto?
:currency-symbol currency-symbol
:currency currency
:token token
:value amount
:conversion conversion
@@ -61,6 +59,20 @@
:weight :semi-bold}
(string/upper-case (or (clj->js text) ""))])
(defn- token-label
[{:keys [theme value text]}]
[rn/view
{:style style/token-label-container
:pointer-events :none}
[rn/text-input
{:max-length 12
:style style/text-input-dimensions
:editable false
:placeholder "0"
:opacity 0
:value value}]
[token-name-text theme text]])
(defn input-section
[{:keys [on-change-text value value-internal set-value-internal on-selection-change
on-token-press]}]
@@ -80,45 +92,36 @@
(oops/oget "nativeEvent.selection")
(js->clj :keywordize-keys true)
(on-selection-change))))]
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection
handle-on-swap]
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection]
:or {show-keyboard? true}}]
(let [theme (quo.theme/use-theme)
window-width (:width (rn/get-window))]
[rn/pressable
{:style {:width "100%"
:flex-direction :row}
: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)}
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]]))))
(let [theme (quo.theme/use-theme)]
[rn/view {:style {:flex 1}}
[rn/pressable {:on-press on-token-press}
[token/view
{:token token
:size :size-32}]]
[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
:max-length 12
: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)}
controlled-input? (assoc :value value)
(not controlled-input?) (assoc :default-value value-internal))]]
[token-label
{:theme theme
:text (if crypto? token currency)
:value (if controlled-input? value value-internal)}]]))))
(defn- view-internal
[{:keys [container-style value on-swap] :as props}]
@@ -138,8 +141,15 @@
:value-internal value-internal
:theme theme
:set-value-internal set-value-internal
:handle-on-swap handle-on-swap
:crypto? crypto?)]]
:crypto? crypto?)]
[button/button
{:icon true
:icon-only? true
:size 32
:on-press handle-on-swap
:type :outline
:accessibility-label :reorder}
:i/reorder]]
[divider-line/view {:container-style (style/divider theme)}]
[data-info
(assoc props
+1 -1
View File
@@ -257,7 +257,7 @@
(def ^:private get-network-full-name
{:eth :ethereum
:oeth :optimism
:opt :optimism
:arb1 :arbitrum})
(def ^:private networks-short-name
+5
View File
@@ -0,0 +1,5 @@
(ns quo.foundations.common)
(def currency-label
{:eur "€"
:usd "$"})
@@ -8,6 +8,7 @@
(defn sheet
[{:keys [max-height]}]
{:position :absolute
:overflow :hidden
:bottom 0
:left 0
:right 0
@@ -37,7 +37,7 @@
[state]
(set-input-error state (upper-limit-exceeded? state)))
(defn set-input-value
(defn- set-input-value
[state value]
(-> state
(assoc :value value)
@@ -58,7 +58,7 @@
(defn view
[{:keys [header footer customization-color footer-container-padding header-container-style
gradient-cover? keyboard-should-persist-taps]
gradient-cover?]
:or {footer-container-padding (safe-area/get-top)}}
& children]
(reagent/with-let [scroll-view-ref (atom nil)
@@ -108,8 +108,7 @@
:padding-bottom (when @keyboard-did-show?
@footer-container-height)}
:always-bounce-vertical @keyboard-did-show?
:shows-vertical-scroll-indicator false
:keyboard-should-persist-taps keyboard-should-persist-taps}
:shows-vertical-scroll-indicator false}
(into [rn/view {:on-layout set-content-container-height}]
children)]
[rn/keyboard-avoiding-view
@@ -33,8 +33,6 @@
args-with-biometric-btn])
:on-success #(rf/dispatch [:standard-auth/on-biometric-success on-auth-success])
:on-fail (fn [err]
(rf/dispatch [:standard-auth/authorize-with-password
args-with-biometric-btn])
(when on-auth-fail (on-auth-fail err))
(rf/dispatch [:standard-auth/on-biometric-fail err]))}]]]}))
+4 -11
View File
@@ -251,7 +251,7 @@
(def regx-community-universal-link #"((^https?://status.app/)|(^status-app://))c/([\x00-\x7F]+)$")
(def regx-deep-link #"((^ethereum:.*)|(^status-app://[\x00-\x7F]+$))")
(def regx-ens #"^(?=.{5,255}$)([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.[a-zA-Z]{2,}$")
(def regx-multichain-address #"^(?:(?:eth:|arb1:|oeth:)(?=:|))*0x[0-9a-fA-F]{40}$")
(def regx-multichain-address #"^(?:(?:eth:|arb1:|opt:)(?=:|))*0x[0-9a-fA-F]{40}$")
(def regx-address-contains #"(?i)0x[a-fA-F0-9]{40}")
(def regx-starts-with-uuid #"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}")
@@ -468,13 +468,13 @@
(def ^:const mainnet-short-name "eth")
(def ^:const ethereum-short-name "eth")
(def ^:const optimism-short-name "oeth")
(def ^:const optimism-short-name "opt")
(def ^:const arbitrum-short-name "arb1")
(def ^:const default-multichain-address-prefix "eth:oeth:arb1:")
(def ^:const default-multichain-address-prefix "eth:opt:arb1:")
(def ^:const mainnet-abbreviated-name "Eth.")
(def ^:const optimism-abbreviated-name "Oeth.")
(def ^:const optimism-abbreviated-name "Opt.")
(def ^:const arbitrum-abbreviated-name "Arb1.")
(def ^:const mainnet-network-name :mainnet)
@@ -506,18 +506,11 @@
(def ^:const send-type-stickers-buy 4)
(def ^:const send-type-bridge 5)
(def ^:const send-type-erc-721-transfer 6)
(def ^:const send-type-erc-1155-transfer 7)
(def ^:const bridge-name-transfer "Transfer")
(def ^:const bridge-name-erc-721-transfer "ERC721Transfer")
(def ^:const bridge-name-erc-1155-transfer "ERC1155Transfer")
(def ^:const bridge-name-hop "Hop")
(def ^:const wallet-contract-type-uknown 0)
(def ^:const wallet-contract-type-erc-20 1)
(def ^:const wallet-contract-type-erc-721 2)
(def ^:const wallet-contract-type-erc-1155 3)
(def ^:const alert-banner-height 40)
(def ^:const status-hostname "status.app")
@@ -15,7 +15,7 @@
:emoji-id emoji-id}])))
(defn- on-long-press
[{:keys [message-id emoji-id user-message-content-render-fn reactions-order theme]}]
[{:keys [message-id emoji-id user-message-content reactions-order theme]}]
(rf/dispatch
[:reactions/get-authors-by-message-id
{:message-id message-id
@@ -31,19 +31,19 @@
[drawers/reaction-authors
{:reactions-order reactions-order
:theme theme}])
:selected-item (fn [] [user-message-content-render-fn
{:hide-reactions? true}])
:selected-item (fn [] user-message-content)
:padding-bottom-override 0}]))}]))
(defn- on-press-add
[{:keys [chat-id message-id user-message-content-render-fn]}]
[{:keys [chat-id message-id user-message-content]}]
(rf/dispatch [:dismiss-keyboard])
(rf/dispatch
[:show-bottom-sheet
{:content (fn [] [drawers/reactions
{:chat-id chat-id
:message-id message-id}])
:selected-item (fn [] [user-message-content-render-fn])}]))
:selected-item (fn []
user-message-content)}]))
(defn- add-emoji-key
[reaction]
@@ -52,25 +52,23 @@
(get constants/reactions (:emoji-id reaction))))
(defn message-reactions-row
[{:keys [message-id chat-id pinned-by hide-new-reaction-button?]} user-message-content-render-fn]
[{:keys [message-id chat-id pinned-by preview?]} user-message-content]
(let [theme (quo.theme/use-theme)
reactions (rf/sub [:chats/message-reactions message-id chat-id])]
(when (seq reactions)
[quo/react
{:container-style {:margin-left 44
:margin-top 8}
:reactions (map add-emoji-key reactions)
:hide-new-reaction-button? hide-new-reaction-button?
:use-case (when pinned-by :pinned)
:on-press #(on-press (assoc % :message-id message-id))
:on-long-press #(on-long-press (assoc %
:message-id message-id
:theme theme
:reactions-order (map :emoji-id
reactions)
:user-message-content-render-fn
user-message-content-render-fn))
:on-press-add #(on-press-add {:chat-id chat-id
:message-id message-id
:user-message-content-render-fn
user-message-content-render-fn})}])))
[:<>
(when (seq reactions)
[quo/react
{:container-style {:margin-left 44
:margin-top 8}
:reactions (map add-emoji-key reactions)
:add-reaction? (not preview?)
:use-case (when pinned-by :pinned)
:on-press #(on-press (assoc % :message-id message-id))
:on-long-press #(on-long-press (assoc %
:message-id message-id
:theme theme
:reactions-order (map :emoji-id reactions)
:user-message-content user-message-content))
:on-press-add #(on-press-add {:chat-id chat-id
:message-id message-id
:user-message-content user-message-content})}])]))
@@ -16,20 +16,22 @@
(assoc :margin-top 4)))
(defn user-message-content
[{:keys [outgoing outgoing-status six-reactions? window-scale small-screen?]}]
[{:keys [outgoing outgoing-status six-reactions? window-scale small-screen? preview?]}]
{:border-radius 16
:padding-horizontal 8
:padding-top 4
:padding-bottom (if (or small-screen?
(and
(> 3 window-scale)
six-reactions?))
(* message-padding-scaling-ratio window-scale)
4)
:padding-horizontal (if preview? 12 8)
:padding-top (if preview? 8 4)
:padding-bottom (if preview?
12
(if (or small-screen?
(and
(> 3 window-scale)
six-reactions?))
(* message-padding-scaling-ratio window-scale)
4))
:opacity (if (and outgoing (= outgoing-status :sending))
0.5
1)})
(def drawer-message-container
{:padding-top 4
:padding-bottom 4})
:padding-bottom 8})
@@ -35,19 +35,19 @@
(def delivery-state-showing-time-ms 3000)
(defn avatar-container
[{:keys [content last-in-group? pinned-by quoted-message from]} hide-reactions?
in-reaction-or-action-menu? show-user-info? in-pinned-view?]
[{:keys [content last-in-group? pinned-by quoted-message from]} show-reactions?
in-reaction-and-action-menu? show-user-info? in-pinned-view?]
(if (or (and (seq (:response-to content))
quoted-message)
last-in-group?
show-user-info?
pinned-by
hide-reactions?
in-reaction-or-action-menu?)
(not show-reactions?)
in-reaction-and-action-menu?)
[avatar/avatar
{:public-key from
:size :small
:hide-ring? (or in-pinned-view? in-reaction-or-action-menu?)}]
:hide-ring? (or in-pinned-view? in-reaction-and-action-menu?)}]
[rn/view {:padding-top 4 :width 32}]))
(defn author
@@ -58,15 +58,15 @@
quoted-message
from
timestamp]}
hide-reactions?
in-reaction-or-action-menu?
show-reactions?
in-reaction-and-action-menu?
show-user-info?]
(when (or (and (seq (:response-to content)) quoted-message)
last-in-group?
pinned-by
show-user-info?
hide-reactions?
in-reaction-or-action-menu?)
(not show-reactions?)
in-reaction-and-action-menu?)
(let [[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity from])
{:keys [ens-verified added?]} (rf/sub [:contacts/contact-by-address from])]
[quo/author
@@ -158,8 +158,8 @@
(defn user-message-content
[]
(let [show-delivery-state? (reagent/atom false)]
(fn [{:keys [message-data context keyboard-shown? hide-reactions?
in-reaction-or-action-menu? show-user-info?]}]
(fn [{:keys [message-data context keyboard-shown? show-reactions? in-reaction-and-action-menu?
show-user-info? preview?]}]
(let [theme (quo.theme/use-theme)
{:keys [content-type quoted-message content outgoing outgoing-status pinned-by pinned
last-in-group? message-id chat-id]} message-data
@@ -198,13 +198,13 @@
:message-sent)
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)
:style (style/user-message-content
{:first-in-group? (:first-in-group? message-data)
:outgoing outgoing
:outgoing-status outgoing-status
:small-screen? rn/small-screen?
:window-scale window-scale
:six-reactions? six-reactions?
:in-reaction-or-action-menu? in-reaction-or-action-menu?})
{:first-in-group? (:first-in-group? message-data)
:outgoing outgoing
:outgoing-status outgoing-status
:small-screen? rn/small-screen?
:window-scale window-scale
:six-reactions? six-reactions?
:preview? preview?})
:on-press (fn []
(if (and platform/ios? keyboard-shown?)
(do
@@ -226,16 +226,18 @@
[rn/view
{:style {:padding-horizontal 4
:flex-direction :row}}
[avatar-container message-data hide-reactions? in-reaction-or-action-menu? show-user-info?
[avatar-container message-data show-reactions? in-reaction-and-action-menu? show-user-info?
(:in-pinned-view? context)]
(into
(if hide-reactions?
[gesture/scroll-view]
[rn/view])
(if show-reactions?
[rn/view]
[gesture/scroll-view])
[{:style {:margin-left 8
:flex 1
:max-height (when hide-reactions? (* 0.4 height))}}
[author message-data hide-reactions? in-reaction-or-action-menu? show-user-info?]
:gap 1
:max-height (when-not show-reactions?
(* 0.4 height))}}
[author message-data show-reactions? in-reaction-and-action-menu? show-user-info?]
(condp = content-type
constants/content-type-text
[content.text/text-content message-data context]
@@ -270,19 +272,17 @@
(when @show-delivery-state?
[status/status outgoing-status])])]
(when-not hide-reactions?
[reactions/message-reactions-row (assoc message-data :hide-new-reaction-button? true)
(fn [override-opts]
[rn/view
{:pointer-events :none
:style style/drawer-message-container}
[user-message-content
(merge {:theme theme
:message-data message-data
:context context
:in-reaction-or-action-menu? true
:keyboard-shown? keyboard-shown?}
override-opts)]])])]]))))
(when show-reactions?
[reactions/message-reactions-row (assoc message-data :preview? preview?)
[rn/view {:pointer-events :none}
[user-message-content
{:theme theme
:message-data message-data
:context context
:in-reaction-and-action-menu? true
:keyboard-shown? keyboard-shown?
:preview? true
:show-reactions? true}]]])]]))))
(defn on-long-press
[{:keys [deleted? deleted-for-me?] :as message-data} context keyboard-shown?]
@@ -299,11 +299,12 @@
{:pointer-events :none
:style style/drawer-message-container}
[user-message-content
{:message-data message-data
:context context
:keyboard-shown? keyboard-shown?
:in-reaction-or-action-menu? true
:show-user-info? false}]]))}]))
{:message-data message-data
:context context
:keyboard-shown? keyboard-shown?
:in-reaction-and-action-menu? true
:show-user-info? false
:show-reactions? true}]]))}]))
(defn check-if-system-message?
[content-type]
@@ -348,4 +349,5 @@
[user-message-content
{:message-data message-data
:context context
:keyboard-shown? keyboard-shown?}])]))
:keyboard-shown? keyboard-shown?
:show-reactions? true}])]))
@@ -105,67 +105,61 @@
;; https://github.com/status-im/status-mobile/issues/15298 is implemented
(not= content-type constants/content-type-image)
(not= content-type constants/content-type-audio))
[{:type :main
:on-press #(rf/dispatch [:chat.ui/edit-message message-data])
:label (i18n/label :t/edit-message)
:icon :i/edit
:accessibility-label :edit-message
:id :edit}])
[{:type :main
:on-press #(rf/dispatch [:chat.ui/edit-message message-data])
:label (i18n/label :t/edit-message)
:icon :i/edit
:id :edit}])
(when (and able-to-send-message? (not= outgoing-status :sending) (not (or deleted? deleted-for-me?)))
[{:type :main
:on-press #(rf/dispatch [:chat.ui/reply-to-message message-data])
:label (i18n/label :t/message-reply)
:icon :i/reply
:accessibility-label :reply-message
:id :reply}])
[{:type :main
:on-press #(rf/dispatch [:chat.ui/reply-to-message message-data])
:label (i18n/label :t/message-reply)
:icon :i/reply
:id :reply}])
(when (and (not (or deleted? deleted-for-me?))
(not= content-type constants/content-type-audio))
[{:type :main
:on-press #(clipboard/set-string
(reply/get-quoted-text-with-mentions
(get content :parsed-text)))
:label (i18n/label :t/copy-text)
:accessibility-label :copy-text
:icon :i/copy
:id :copy}])
[{:type :main
:on-press #(clipboard/set-string
(reply/get-quoted-text-with-mentions
(get content :parsed-text)))
:label (i18n/label :t/copy-text)
:icon :i/copy
:id :copy}])
;; pinning images are temporarily disabled
(when (and message-pin-enabled
(not= content-type constants/content-type-image))
[{:type :main
:on-press #(pin-message message-data)
:label (i18n/label (if pinned-by
(if community? :t/unpin-from-channel :t/unpin-from-chat)
(if community? :t/pin-to-channel :t/pin-to-chat)))
:accessibility-label (if pinned-by :unpin-message :pin-message)
:icon :i/pin
:id (if pinned-by :unpin :pin)}])
[{:type :main
:on-press #(pin-message message-data)
:label (i18n/label (if pinned-by
(if community? :t/unpin-from-channel :t/unpin-from-chat)
(if community? :t/pin-to-channel :t/pin-to-chat)))
:icon :i/pin
:id (if pinned-by :unpin :pin)}])
(when-not (or deleted? deleted-for-me?)
[{:type :danger
:on-press (fn []
(rf/dispatch
[:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message-for-me message-data
config/delete-message-for-me-undo-time-limit-ms]))
[{:type :danger
:on-press (fn []
(rf/dispatch
[:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message-for-me message-data
config/delete-message-for-me-undo-time-limit-ms]))
:label (i18n/label :t/delete-for-me)
:accessibility-label :delete-for-me
:icon :i/delete
:id :delete-for-me}])
:label (i18n/label :t/delete-for-me)
:icon :i/delete
:id :delete-for-me}])
(when (cond
deleted? false
outgoing true
community? can-delete-message-for-everyone?
group-chat group-admin?
:else false)
[{:type :danger
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message message-data
config/delete-message-undo-time-limit-ms]))
:label (i18n/label :t/delete-for-everyone)
:accessibility-label :delete-for-everyone
:icon :i/delete
:id :delete-for-all}])))
[{:type :danger
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:chat.ui/delete-message message-data
config/delete-message-undo-time-limit-ms]))
:label (i18n/label :t/delete-for-everyone)
:icon :i/delete
:id :delete-for-all}])))
(defn extract-id
[reactions id]
@@ -186,7 +180,7 @@
[rn/view
{:style {:flex-direction :row
:justify-content :space-between
:padding-horizontal 22
:padding-horizontal 30
:padding-top 5
:padding-bottom 15}}
(for [[id reaction-name] constants/reactions
@@ -227,10 +221,10 @@
(for [action main-actions]
(let [on-press (:on-press action)]
^{:key (:id action)}
[quo/drawer-action
[quo/menu-item
{:type :main
:title (:label action)
:accessibility-label (:accessibility-label action)
:accessibility-label (:label action)
:icon (:icon action)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
@@ -244,10 +238,10 @@
(for [action danger-actions]
(let [on-press (:on-press action)]
^{:key (:id action)}
[quo/drawer-action
[quo/menu-item
{:type :danger
:title (:label action)
:accessibility-label (:accessibility-label action)
:accessibility-label (:label action)
:icon (:icon action)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
@@ -261,10 +255,10 @@
(for [action admin-actions]
(let [on-press (:on-press action)]
^{:key (:id action)}
[quo/drawer-action
[quo/menu-item
{:type :danger
:title (:label action)
:accessibility-label (:accessibility-label action)
:accessibility-label (:label action)
:icon (:icon action)
:on-press (fn []
(rf/dispatch [:hide-bottom-sheet])
@@ -114,20 +114,20 @@
(defn list-footer-avatar
[{:keys [distance-from-list-top display-name online? profile-picture theme group-chat color
emoji chat-type chat-name empty-chat?]}]
emoji chat-type chat-name last-message]}]
(let [scale (reanimated/interpolate
distance-from-list-top
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[1 0.4]
messages.constants/default-extrapolation-option)
top (reanimated/interpolate
distance-from-list-top
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[-44 -12]
messages.constants/default-extrapolation-option)
left (reanimated/interpolate
distance-from-list-top
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[16 -8]
messages.constants/default-extrapolation-option)
community-channel? (= chat-type constants/community-chat-type)]
@@ -155,15 +155,15 @@
:size :big}])]))
(defn chat-display-name
[{:keys [distance-from-list-top display-name contact theme empty-chat?]}]
[{:keys [distance-from-list-top display-name contact theme last-message]}]
(let [top (reanimated/interpolate
distance-from-list-top
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[0 -35]
messages.constants/default-extrapolation-option)
left (reanimated/interpolate
distance-from-list-top
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[0 40]
messages.constants/default-extrapolation-option)]
[reanimated/view
@@ -212,11 +212,11 @@
muted?)))}]}]))
(defn bio-and-actions
[{:keys [distance-from-list-top bio chat-id customization-color empty-chat? description]}]
[{:keys [distance-from-list-top bio chat-id customization-color last-message description]}]
(let [has-bio (seq (or bio description))
top (reanimated/interpolate
distance-from-list-top
[0 (if empty-chat? 0 messages.constants/header-container-top-margin)]
[0 (if (seq last-message) messages.constants/header-container-top-margin 0)]
[(if has-bio 8 16) (if has-bio -28 -20)]
messages.constants/default-extrapolation-option)]
[reanimated/view
@@ -227,43 +227,43 @@
(defn footer-component
[{:keys [chat distance-from-list-top customization-color]}]
(let [theme (quo.theme/use-theme)
(let [theme (quo.theme/use-theme)
{:keys [chat-id chat-name emoji chat-type
group-chat color description
empty-chat?]} chat
display-name (cond
(= chat-type constants/one-to-one-chat-type)
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
(= chat-type constants/community-chat-type)
(str "# " chat-name)
:else (str emoji chat-name))
{:keys [bio]} (rf/sub [:contacts/contact-by-identity chat-id])
online? (rf/sub [:visibility-status-updates/online? chat-id])
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))
photo-path (if group-chat
(rf/sub [:chats/group-chat-image chat-id])
(rf/sub [:chats/photo-path chat-id]))
top-margin (+ (safe-area/get-top)
messages.constants/top-bar-height
messages.constants/header-container-top-margin
32)
background-color (colors/theme-colors
(colors/resolve-color customization-color theme 20)
(colors/resolve-color customization-color theme 40)
theme)
bottom (reanimated/interpolate
distance-from-list-top
[0 messages.constants/header-container-top-margin]
[32 -4]
messages.constants/default-extrapolation-option)
background-opacity (reanimated/interpolate
distance-from-list-top
[messages.constants/header-container-top-margin
(+ messages.constants/header-animation-distance
messages.constants/header-container-top-margin)]
[1 0]
messages.constants/default-extrapolation-option)]
last-message]} chat
display-name (cond
(= chat-type constants/one-to-one-chat-type)
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
(= chat-type constants/community-chat-type)
(str "# " chat-name)
:else (str emoji chat-name))
{:keys [bio]} (rf/sub [:contacts/contact-by-identity chat-id])
online? (rf/sub [:visibility-status-updates/online? chat-id])
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))
photo-path (if group-chat
(rf/sub [:chats/group-chat-image chat-id])
(rf/sub [:chats/photo-path chat-id]))
top-margin (+ (safe-area/get-top)
messages.constants/top-bar-height
messages.constants/header-container-top-margin
32)
background-color (colors/theme-colors
(colors/resolve-color customization-color theme 20)
(colors/resolve-color customization-color theme 40)
theme)
bottom (reanimated/interpolate
distance-from-list-top
[0 messages.constants/header-container-top-margin]
[32 -4]
messages.constants/default-extrapolation-option)
background-opacity (reanimated/interpolate
distance-from-list-top
[messages.constants/header-container-top-margin
(+ messages.constants/header-animation-distance
messages.constants/header-container-top-margin)]
[1 0]
messages.constants/default-extrapolation-option)]
[:<>
[reanimated/view
{:style (style/background-container background-color background-opacity top-margin)}]
@@ -281,21 +281,21 @@
:emoji emoji
:chat-type chat-type
:chat-name chat-name
:empty-chat? empty-chat?}]
:last-message last-message}]
[chat-display-name
{:distance-from-list-top distance-from-list-top
:display-name display-name
:theme theme
:contact contact
:group-chat group-chat
:empty-chat? empty-chat?}]
:last-message last-message}]
[bio-and-actions
{:distance-from-list-top distance-from-list-top
:bio bio
:chat-id chat-id
:customization-color customization-color
:description description
:empty-chat? empty-chat?}]]]]))
:last-message last-message}]]]]))
(defn list-footer
[props]
@@ -50,26 +50,18 @@
messages.constants/top-bar-height
(if platform/ios?
messages.constants/content-animation-start-position-ios
messages.constants/content-animation-start-position-android))
community-channel? (= chat-type constants/community-chat-type)]
messages.constants/content-animation-start-position-android))]
[reanimated/view
{:style (style/header-content-container header-opacity header-position)}
(cond
community-channel?
[quo/channel-avatar
{:size :size-32
:full-name chat-name
:customization-color color
:emoji (when-not (string/blank? emoji)
(string/trim emoji))}]
group-chat
(if group-chat
[quo/group-avatar
{:customization-color color
:size :size-32
:picture photo-path
:override-theme :dark
:emoji (when-not (string/blank? emoji)
(string/trim emoji))
:chat-name chat-name}]
:else
[quo/user-avatar
{:full-name display-name
:online? online?
@@ -13,15 +13,13 @@
(defn- chat-screen
[{:keys [insets] :as props}]
(let [alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
chat-exist? (rf/sub [:chats/current-chat-exist?])]
(when chat-exist?
[rn/keyboard-avoiding-view
{:style style/keyboard-avoiding-container
:keyboard-vertical-offset (- (if platform/ios? alert-banners-top-margin 0) (:bottom insets))}
[list.view/messages-list-content props]
[messages.navigation/view props]
[composer.view/composer props]])))
(let [alert-banners-top-margin (rf/sub [:alert-banners/top-margin])]
[rn/keyboard-avoiding-view
{:style style/keyboard-avoiding-container
:keyboard-vertical-offset (- (if platform/ios? alert-banners-top-margin 0) (:bottom insets))}
[list.view/messages-list-content props]
[messages.navigation/view props]
[composer.view/composer props]]))
(defn lazy-chat-screen
[chat-screen-layout-calculations-complete?]
@@ -6,7 +6,6 @@
[react-native.reanimated :as reanimated]
[react-native.safe-area :as safe-area]
[status-im.contexts.chat.messenger.placeholder.style :as style]
[utils.re-frame :as rf]
[utils.worklets.chat.messenger.placeholder :as worklets]))
(defn- loading-skeleton
@@ -18,14 +17,9 @@
(defn view
[chat-screen-layout-calculations-complete?]
(let [theme (quo.theme/use-theme)
top (safe-area/get-top)
chat-exist? (rf/sub [:chats/current-chat-exist?])
opacity (worklets/placeholder-opacity chat-screen-layout-calculations-complete?)
z-index (worklets/placeholder-z-index chat-screen-layout-calculations-complete?)]
(let [theme (quo.theme/use-theme)
top (safe-area/get-top)
opacity (worklets/placeholder-opacity chat-screen-layout-calculations-complete?)
z-index (worklets/placeholder-z-index chat-screen-layout-calculations-complete?)]
[reanimated/view {:style (style/container top opacity z-index theme)}
(when-not chat-exist?
[quo/page-nav
{:icon-name :i/arrow-left
:on-press #(rf/dispatch [:navigate-back])}])
[loading-skeleton]]))
@@ -1,7 +1,7 @@
(ns status-im.contexts.preview.quo.counter.step
(:require
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
@@ -17,13 +17,13 @@
(defn view
[]
(let [[state set-state] (rn/use-state {:value "5"
:type :neutral
:in-blur-view? false})]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor
:blur? (:in-blur-view? state)
:show-blur-background? (:in-blur-view? state)}
[quo/step (dissoc state :value) (:value state)]]))
(let [state (reagent/atom {:value "5"
:type :neutral
:in-blur-view? false})]
(fn []
[preview/preview-container
{:state state
:descriptor descriptor
:blur? (:in-blur-view? @state)
:show-blur-background? (:in-blur-view? @state)}
[quo/step (dissoc @state :value) (:value @state)]])))
@@ -16,7 +16,7 @@
:blur? false
:title "Collectibles vault"
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]
{:network-name :optimism :short-name "opt"}]
:description "0x0ah...78b"
:account-avatar-emoji "🍿"
:customization-color (or customization-color :blue)}]
@@ -21,7 +21,7 @@
:name "Trip to Vegas"
:address "0x0ah...78b"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]
{:network-name :optimism :short-name "opt"}]
:action :none
:on-press (fn [] (js/alert "Item pressed"))
:on-options-press (fn [] (js/alert "Options pressed"))
@@ -14,7 +14,7 @@
[]
(let [state (reagent/atom {:address "0x0ah...78b"
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]})]
{:network-name :optimism :short-name "opt"}]})]
(fn []
[preview/preview-container
{:state state
+72 -118
View File
@@ -46,94 +46,70 @@
(str (humanize k) ":"))
(defn- customizer-boolean
[{:keys [label state set-state] :as args}]
(let [theme (quo.theme/use-theme)
label (or label (key->boolean-label (:key args)))
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))]
[{:keys [label state] :as args}]
(let [theme (quo.theme/use-theme)
label (or label (key->boolean-label (:key args)))
field-value (reagent/cursor state [(:key args)])
active? @field-value]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style (style/boolean-container)}
[rn/pressable
{:style (style/boolean-button {:active? field-value :left? true} theme)
:on-press #(set-field-value true)}
[rn/text {:style (style/field-text field-value theme)}
{:style (style/boolean-button {:active? active? :left? true} theme)
:on-press #(reset! field-value true)}
[rn/text {:style (style/field-text active? theme)}
"True"]]
[rn/pressable
{:style (style/boolean-button {:active? (not field-value) :left? false} theme)
:on-press #(set-field-value false)}
[rn/text {:style (style/field-text (not field-value) theme)}
{:style (style/boolean-button {:active? (not active?) :left? false} theme)
:on-press #(reset! field-value false)}
[rn/text {:style (style/field-text (not active?) theme)}
"False"]]]]))
(defn- customizer-text
[{:keys [label state set-state limit suffix] :as args} theme]
(let [label (or label (key->text-label (:key args)))
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))]
[{:keys [label state limit suffix] :as args} theme]
(let [label (or label (key->text-label (:key args)))
field-value (reagent/cursor state [(:key args)])]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style style/field-column}
[rn/text-input
(merge
{:value field-value
{:value @field-value
:show-cancel false
:style (style/field-container false theme)
:keyboard-appearance theme
:on-change-text (fn [text]
(set-field-value (if (and suffix
(> (count text) (count field-value)))
(str (string/replace text suffix "") suffix)
text))
(when-not (fn? set-state)
(reagent/flush)))}
(reset! field-value (if (and suffix
(> (count text) (count @field-value)))
(str (string/replace text suffix "") suffix)
text))
(reagent/flush))}
(when limit
{:max-length limit}))]]]))
(defn- customizer-number
[{:keys [label state set-state default] :as args} theme]
(let [label (or label (key->text-label (:key args)))
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))]
[{:keys [label state default] :as args} theme]
(let [label (or label (key->text-label (:key args)))
field-value (reagent/cursor state [(:key args)])]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style style/field-column}
[rn/text-input
{:value (str field-value)
:show-cancel false
:style (style/field-container false theme)
:keyboard-appearance theme
:on-change-text (fn [text]
(set-field-value (utils.number/parse-int text default))
(when-not (fn? set-state)
(reagent/flush)))}]]]))
(merge
{:value (str @field-value)
:show-cancel false
:style (style/field-container false theme)
:keyboard-appearance theme
:on-change-text (fn [text]
(reset! field-value (utils.number/parse-int text default))
(reagent/flush))})]]]))
(defn- find-selected-option
[id v]
(first (filter #(= (:key %) id) v)))
(defn- customizer-select-modal
[{:keys [open options field-value set-field-value]}]
[{:keys [open options field-value]}]
(let [theme (quo.theme/use-theme)]
[rn/modal
{:visible @open
@@ -149,17 +125,17 @@
:let [v (or v (humanize k))]]
^{:key k}
[rn/pressable
{:style (style/select-option (= field-value k) theme)
{:style (style/select-option (= @field-value k) theme)
:on-press (fn []
(reset! open false)
(set-field-value k))}
[rn/text {:style (style/field-text (= field-value k) theme)}
(reset! field-value k))}
[rn/text {:style (style/field-text (= @field-value k) theme)}
v]]))]
[rn/view {:style (style/footer theme)}
[rn/pressable
{:style (style/select-button theme)
:on-press (fn []
(set-field-value nil)
(reset! field-value nil)
(reset! open false))}
[rn/text {:style (style/field-text false theme)}
"Clear"]]
@@ -187,31 +163,22 @@
(defn- customizer-select
[]
(let [open (reagent/atom nil)]
(fn [{:keys [label state set-state options] :as args}]
(fn [{:keys [label state options] :as args}]
(let [theme (quo.theme/use-theme)
label (or label (key->text-label (:key args)))
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))
selected-option (find-selected-option field-value options)]
field-value (reagent/cursor state [(:key args)])
selected-option (find-selected-option @field-value options)]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style style/field-column}
[customizer-select-modal
{:open open
:options options
:field-value field-value
:set-field-value set-field-value}]
{:open open
:options options
:field-value field-value}]
[customizer-select-button {:open open :selected-option selected-option} theme]]]))))
(defn- customizer-multi-select-modal
[{:keys [open-atom options field-value set-field-value]}]
[{:keys [open-atom options selected-keys-atom]}]
(let [theme (quo.theme/use-theme)]
[rn/modal
{:visible @open-atom
@@ -226,13 +193,13 @@
(for [{k :key v :value} options
:let [v (or v (humanize k))]]
^{:key k}
(let [checked? (boolean (some #(= k %) field-value))
(let [checked? (boolean (some #(= k %) @selected-keys-atom))
remove-key (fn [v] (filterv #(not= % k) v))
on-press (fn []
(set-field-value
(if checked?
(remove-key field-value)
(conj field-value k))))]
(swap! selected-keys-atom
(if checked? remove-key conj)
k))]
[rn/pressable
{:style (style/multi-select-option theme)
:on-press on-press}
@@ -245,7 +212,7 @@
[rn/pressable
{:style (style/select-button theme)
:on-press (fn []
(set-field-value nil)
(reset! selected-keys-atom nil)
(reset! open-atom false))}
[rn/text {:style (style/field-text false theme)}
"Clear"]]
@@ -279,51 +246,41 @@
(defn- customizer-multi-select
[]
(let [open (reagent/atom nil)]
(fn [{:keys [label state set-state options] :as args}]
(fn [{:keys [label state options] :as args}]
(let [theme (quo.theme/use-theme)
label (or label (key->text-label (:key args)))
field-cursor (when-not (fn? set-state)
(reagent/cursor state [(:key args)]))
field-value (if (fn? set-state)
(get state (:key args))
@field-cursor)
set-field-value (fn [value]
(if (fn? set-state)
(set-state (assoc state (:key args) value))
(reset! field-cursor value)))
selected-options (filter-by-keys options field-value)]
selected-keys (reagent/cursor state [(:key args)])
selected-options (filter-by-keys options @selected-keys)]
[rn/view {:style style/field-row}
[label-view state label theme]
[rn/view {:style style/field-column}
[customizer-multi-select-modal
{:open-atom open
:field-value field-value
:set-field-value set-field-value
:options options}]
{:open-atom open
:selected-keys-atom selected-keys
:options options}]
[customizer-multi-select-button {:open open :selected-options selected-options} theme]]]))))
(defn customizer
[state set-state descriptors theme]
[state descriptors theme]
[rn/view
{:style {:flex-shrink 1
:padding-horizontal 20}}
(doall
(for [desc descriptors
:let [desc-path (:path desc)
descriptor (if (fn? set-state)
(assoc desc :state state :set-state set-state)
(let [new-state (if desc-path
(reagent/cursor state desc-path)
state)]
(assoc desc :state new-state)))]]
new-state (if desc-path
(reagent/cursor state desc-path)
state)
descriptor (assoc desc :state new-state)]]
^{:key (:key desc)}
(case (:type desc)
:boolean [customizer-boolean descriptor]
:text [customizer-text descriptor theme]
:number [customizer-number descriptor theme]
:select [customizer-select descriptor]
:multi-select [customizer-multi-select descriptor]
nil)))])
[:<>
(case (:type desc)
:boolean [customizer-boolean descriptor]
:text [customizer-text descriptor theme]
:number [customizer-number descriptor theme]
:select [customizer-select descriptor]
:multi-select [customizer-multi-select descriptor]
nil)]))])
(defn customization-color-option
([]
@@ -368,7 +325,7 @@
children)])
(defn- f-preview-container
[{:keys [title state set-state descriptor blur? blur-dark-only?
[{:keys [title state descriptor blur? blur-dark-only?
component-container-style
blur-container-style blur-view-props blur-height show-blur-background? full-screen?]
:or {blur-height 200}}
@@ -395,7 +352,7 @@
:on-press rn/dismiss-keyboard!}
(when descriptor
[rn/view {:style style/customizer-container}
[customizer state set-state descriptor theme]])
[customizer state descriptor theme]])
(if blur?
[rn/view {:style (merge style/component-container component-container-style)}
(into [blur-view
@@ -414,11 +371,8 @@
(into [rn/view {:style (merge style/component-container component-container-style)}]
children))]
(when state
(let [actual-state (if (fn? set-state) state @state)
decr-state (if descriptor
(select-keys actual-state (mapv :key (flatten descriptor)))
actual-state)
state-str (with-out-str (cljs.pprint/pprint decr-state))]
(let [decr-state (if descriptor (select-keys @state (mapv :key (flatten descriptor))) @state)
state-str (with-out-str (cljs.pprint/pprint decr-state))]
[rn/view {:style {:margin 50}}
[quo/text {:style {:margin-bottom 10}} "State map (click on map to copy)"]
[rn/pressable
@@ -4,17 +4,18 @@
[quo.core :as quo]
[quo.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.constants :as constants]
[status-im.contexts.preview.quo.preview :as preview]))
(defn gen-quantity
(defn- gen-quantity
[max-count _]
(rand-int max-count))
(def memo-gen-quantity (memoize gen-quantity))
(def ^:private memo-gen-quantity (memoize gen-quantity))
(def descriptor
[{:key :hide-new-reaction-button?
(def ^:private descriptor
[{:key :add-reaction?
:type :boolean}
{:label "Reactions"
:key :reaction-ids
@@ -36,44 +37,40 @@
(defn preview-react
[]
(let [[state set-state]
(rn/use-state {:hide-new-reaction-button? true
:max-count 1000
:reaction-ids [1 2 3]
:use-case :default})
(let [state (reagent/atom {:add-reaction? true
:max-count 1000
:reaction-ids [1 2 3]
:use-case :default})
pressed-reactions (reagent/atom #{1})]
[pressed-reactions set-pressed-reactions] (rn/use-state #{1})
reactions (mapv (fn [reaction-id]
{:emoji-reaction-id reaction-id
:emoji-id reaction-id
:emoji (get constants/reactions reaction-id)
:quantity (memo-gen-quantity (:max-count state) reaction-id)
:own (contains? pressed-reactions reaction-id)})
(:reaction-ids state))
on-press (fn [reaction]
(let [reaction-id (:emoji-id reaction)]
(if (contains? pressed-reactions reaction-id)
(set-pressed-reactions (disj pressed-reactions reaction-id))
(set-pressed-reactions (conj pressed-reactions
reaction-id)))))]
[preview/preview-container
{:state state
:set-state set-state
:descriptor descriptor}
[rn/view
{:padding-bottom 150
:padding-vertical 60
:padding-horizontal 20
:border-radius 16
:background-color (when (= :pinned (:use-case state))
(colors/custom-color :blue 50 10))
:align-items :flex-start}
[quo/react
{:reactions reactions
:hide-new-reaction-button? (:hide-new-reaction-button? state)
:use-case (:use-case state)
:on-press on-press
:on-long-press identity
:on-press-new identity}]]]))
(fn []
(let [reactions (mapv (fn [reaction-id]
{:emoji-reaction-id reaction-id
:emoji-id reaction-id
:emoji (get constants/reactions reaction-id)
:quantity (memo-gen-quantity (:max-count @state) reaction-id)
:own (contains? @pressed-reactions reaction-id)})
(:reaction-ids @state))]
[preview/preview-container
{:state state
:descriptor descriptor}
[rn/view
{:padding-bottom 150
:padding-vertical 60
:padding-horizontal 20
:border-radius 16
:background-color (when (= :pinned (:use-case @state))
(colors/custom-color :blue 50 10))
:align-items :flex-start}
[quo/react
{:reactions reactions
:add-reaction? (:add-reaction? @state)
:use-case (:use-case @state)
:on-press (fn [reaction]
(let [reaction-id (:emoji-id reaction)
change-pressed (partial swap! pressed-reactions)]
(if (contains? @pressed-reactions reaction-id)
(change-pressed disj reaction-id)
(change-pressed conj reaction-id))))
:on-long-press identity
:on-press-new identity}]]]))))
@@ -82,7 +82,7 @@
[network]
(case network
:ethereum "eth:"
:optimism "oeth:"
:optimism "opt:"
:arbitrum "arb1:"
(str (name network) ":")))
@@ -13,7 +13,7 @@
:name "Trip to Vegas"
:address "0x0ah...71a"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]
{:network-name :optimism :short-name "opt"}]
:state :default
:action :none}
{:account-props {:customization-color :purple
@@ -23,7 +23,7 @@
:name "My savings"
:address "0x0ah...72b"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]
{:network-name :optimism :short-name "opt"}]
:state :default
:action :none}
{:account-props {:customization-color :army
@@ -33,7 +33,7 @@
:name "Coin vault"
:address "0x0ah...73c"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]
{:network-name :optimism :short-name "opt"}]
:state :default
:action :none}
{:account-props {:customization-color :orange
@@ -43,7 +43,7 @@
:name "Crypto fortress"
:address "0x0ah...74e"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]
{:network-name :optimism :short-name "opt"}]
:state :default
:action :none}
{:account-props {:customization-color :yellow
@@ -53,7 +53,7 @@
:name "Block treasure"
:address "0x0ah...75f"}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}]
{:network-name :optimism :short-name "opt"}]
:state :default
:action :none}])
@@ -50,5 +50,5 @@
(-> (h/wait-for #(h/get-by-label-text :share-qr-code-settings))
(.then (fn []
(h/is-truthy (h/get-by-text "eth:"))
(h/is-truthy (h/get-by-text "oeth:"))
(h/is-truthy (h/get-by-text "opt:"))
(h/is-truthy (h/get-by-text "arb1:"))))))))))
@@ -27,8 +27,8 @@
config/mainnet-chain-explorer-link
address])}
{:icon :i/link
:accessibility-label :view-on-oeth
:label (i18n/label :t/view-on-oeth)
:accessibility-label :view-on-opt
:label (i18n/label :t/view-on-opt)
:right-icon :i/external
:on-press #(rf/dispatch
[:wallet/navigate-to-chain-explorer-from-bottom-sheet
@@ -27,7 +27,7 @@
{:db (-> db
(assoc-in [:wallet :ui :create-account :seed-phrase] seed-phrase)
(assoc-in [:wallet :ui :create-account :random-phrase] random-phrase))
:fx [[:dispatch-later [{:ms 20 :dispatch [:navigate-to :screen/wallet.confirm-backup]}]]]})
:fx [[:dispatch-later [{:ms 20 :dispatch [:navigate-to :screen/wallet.check-your-backup]}]]]})
(rf/reg-event-fx :wallet/store-seed-phrase store-seed-phrase)
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.add-account.create-account.new-keypair.confirm-backup.style)
(ns status-im.contexts.wallet.add-account.create-account.new-keypair.check-your-backup.style)
(def header-container
{:margin-horizontal 20
@@ -1,9 +1,9 @@
(ns status-im.contexts.wallet.add-account.create-account.new-keypair.confirm-backup.view
(ns status-im.contexts.wallet.add-account.create-account.new-keypair.check-your-backup.view
(:require
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.wallet.add-account.create-account.new-keypair.confirm-backup.style :as style]
[status-im.contexts.wallet.add-account.create-account.new-keypair.check-your-backup.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.security.core :as security]))
@@ -95,7 +95,7 @@
:on-press #(rf/dispatch [:navigate-back])
:accessibility-label :top-bar}]
[quo/page-top
{:title (i18n/label :t/confirm-backup)
{:title (i18n/label :t/check-your-backup)
:description :text
:description-text (i18n/label :t/confirm-the-position)}]
[rn/flat-list
@@ -42,7 +42,7 @@
:name name
:address address}
:networks [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}
{:network-name :optimism :short-name "opt"}
{:network-name :arbitrum :short-name "arb1"}]
:state :default
:action :none}))))
@@ -7,5 +7,4 @@
:skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :bridge-to-chain-id])))}
{:screen-id :screen/wallet.bridge-input-amount
:skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :amount])))}
{:screen-id :screen/wallet.transaction-confirmation}
{:screen-id :screen/wallet.transaction-progress}])
{:screen-id :screen/wallet.transaction-confirmation}])
@@ -6,7 +6,7 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def ^:private supported-networks #{:eth :arb1 :oeth})
(def ^:private supported-networks #{:eth :arb1 :opt})
(defn- contains-supported-address?
[s]
@@ -4,7 +4,7 @@
[status-im.common.qr-codes.view :as qr-codes]
[status-im.constants :as constants]
[utils.money :as money]
[utils.number :as number]))
[utils.number]))
(defn get-first-name
[full-name]
@@ -56,6 +56,16 @@
(inc max-decimals)
max-decimals)))
(defn remove-trailing-zeroes
[num]
(let [parts (clojure.string/split (str num) #"\.")]
(str (first parts)
(if-let [decimals (second parts)]
(if (seq (clojure.string/replace decimals #"0+$" ""))
(str "." (clojure.string/replace decimals #"0+$" ""))
"")
""))))
(defn get-crypto-decimals-count
[{:keys [market-values-per-currency]}]
(let [price (get-in market-values-per-currency [:usd :price])
@@ -73,8 +83,8 @@
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))))))
(str "<" (remove-trailing-zeroes (.toFixed one-cent-value decimals-count)))
(remove-trailing-zeroes (.toFixed token-units decimals-count))))))
(defn get-market-value
[currency {:keys [market-values-per-currency]}]
@@ -12,9 +12,9 @@
constants/ethereum-sepolia-chain-id))
(is (= (utils/network->chain-id {:network "optimism" :testnet-enabled? true :goerli-enabled? false})
constants/optimism-sepolia-chain-id))
(is (= (utils/network->chain-id {:network "oeth" :testnet-enabled? false :goerli-enabled? true})
(is (= (utils/network->chain-id {:network "opt" :testnet-enabled? false :goerli-enabled? true})
constants/optimism-mainnet-chain-id))
(is (= (utils/network->chain-id {:network :oeth :testnet-enabled? true :goerli-enabled? true})
(is (= (utils/network->chain-id {:network :opt :testnet-enabled? true :goerli-enabled? true})
constants/optimism-goerli-chain-id))
(is (= (utils/network->chain-id {:network :arb1 :testnet-enabled? false :goerli-enabled? false})
constants/arbitrum-mainnet-chain-id))
@@ -25,24 +25,24 @@
(testing "network-preference-prefix->network-names function"
(is (= (utils/network-preference-prefix->network-names "eth")
(seq [:mainnet])))
(is (= (utils/network-preference-prefix->network-names "eth:oeth")
(is (= (utils/network-preference-prefix->network-names "eth:opt")
(seq [:mainnet :optimism])))
(is (= (utils/network-preference-prefix->network-names "eth:oeth:arb1")
(is (= (utils/network-preference-prefix->network-names "eth:opt:arb1")
(seq [:mainnet :optimism :arbitrum])))))
(deftest short-names->network-preference-prefix-test
(are [expected short-names]
(= expected (utils/short-names->network-preference-prefix short-names))
"eth:" ["eth"]
"eth:oeth:" ["eth" "oeth"]
"eth:oeth:arb1:" ["eth" "oeth" "arb1"]))
"eth:" ["eth"]
"eth:opt:" ["eth" "opt"]
"eth:opt:arb1:" ["eth" "opt" "arb1"]))
(deftest network-preference-prefix->network-names-test
(are [expected short-names]
(= expected (utils/network-preference-prefix->network-names short-names))
(seq [:mainnet]) "eth"
(seq [:mainnet :optimism]) "eth:oeth"
(seq [:mainnet :optimism :arbitrum]) "eth:oeth:arb1"))
(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"
@@ -102,7 +102,7 @@
:address "x000"}]
(is (= (utils/get-wallet-qr wallet-multichain)
"eth:oeth:x000"))
"eth:opt:x000"))
(is (= (utils/get-wallet-qr wallet-singlechain)
"x000")))))
+2 -2
View File
@@ -250,7 +250,7 @@
{:db (-> db
(assoc-in [:wallet :ui :send :token] token)
(assoc-in [:wallet :ui :send :to-address] to-address)
(assoc-in [:wallet :ui :send :tx-type] :tx/bridge))
(assoc-in [:wallet :ui :send :tx-type] :bridge))
:fx [[:dispatch
[:wallet/wizard-navigate-forward
{:current-screen stack-id
@@ -259,7 +259,7 @@
(rf/reg-event-fx :wallet/start-bridge
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :send :tx-type] :tx/bridge)
{:db (assoc-in db [:wallet :ui :send :tx-type] :bridge)
:fx [[:dispatch [:open-modal :screen/wallet.bridge-select-asset]]]}))
(rf/reg-event-fx :wallet/select-bridge-network
@@ -12,7 +12,7 @@
name ""
ens ""
test? false
;; the chain short names should be a string like eth: or eth:arb:oeth:
;; the chain short names should be a string like eth: or eth:arb:opt:
chain-short-names (str constants/mainnet-short-name ":")}}]]
(let [address-to-save {:address address
:name name
+14 -48
View File
@@ -35,7 +35,6 @@
receiver-networks (get-in db [:wallet :ui :send :receiver-networks])
receiver-network-values (get-in db [:wallet :ui :send :receiver-network-values])
sender-network-values (get-in db [:wallet :ui :send :sender-network-values])
tx-type (get-in db [:wallet :ui :send :tx-type])
disabled-from-chain-ids (or (get-in db [:wallet :ui :send :disabled-from-chain-ids]) [])
token-decimals (if collectible 0 (:decimals token))
native-token? (and token (= token-display-name "ETH"))
@@ -62,7 +61,6 @@
:disabled-chain-ids disabled-from-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? false})
(send-utils/reset-network-amounts-to-zero
sender-network-values))
@@ -72,7 +70,6 @@
:disabled-chain-ids disabled-from-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? true})
(send-utils/reset-network-amounts-to-zero
receiver-network-values))
@@ -117,7 +114,6 @@
dissoc
:suggested-routes
:route
:amount
:from-values-by-chain
:to-values-by-chain
:sender-network-values
@@ -148,8 +144,7 @@
{:prefix prefix
:testnet-enabled? testnet-enabled?
:goerli-enabled? goerli-enabled?})
collectible-tx? (send-utils/tx-type-collectible?
(-> db :wallet :ui :send :tx-type))
collectible-tx? (= (-> db :wallet :ui :send :tx-type) :collectible)
collectible (when collectible-tx?
(-> db :wallet :ui :send :collectible))
one-collectible? (when collectible-tx?
@@ -240,19 +235,13 @@
:collectible
:token-display-name
:amount
(when (send-utils/tx-type-collectible?
transaction-type)
:tx-type))})))
(when (= transaction-type :collectible) :tx-type))})))
(rf/reg-event-fx
:wallet/set-collectible-to-send
(fn [{db :db} [{:keys [collectible current-screen]}]]
(let [collection-data (:collection-data collectible)
collectible-data (:collectible-data collectible)
contract-type (:contract-type collectible)
tx-type (if (= contract-type constants/wallet-contract-type-erc-1155)
:tx/collectible-erc-1155
:tx/collectible-erc-721)
collectible-id (get-in collectible [:id :token-id])
one-collectible? (= (collectible.utils/collectible-balance collectible) 1)
token-display-name (cond
@@ -266,7 +255,7 @@
(update-in [:wallet :ui :send] dissoc :token)
(assoc-in [:wallet :ui :send :collectible] collectible)
(assoc-in [:wallet :ui :send :token-display-name] token-display-name)
(assoc-in [:wallet :ui :send :tx-type] tx-type))
(assoc-in [:wallet :ui :send :tx-type] :collectible))
recipient-set? (-> db :wallet :ui :send :recipient)]
{:db (cond-> collectible-tx
one-collectible? (assoc-in [:wallet :ui :send :amount] 1))
@@ -325,7 +314,7 @@
amount-in (send-utils/amount-in-hex amount (if token token-decimal 0))
from-address wallet-address
disabled-from-chain-ids disabled-from-chain-ids
disabled-to-chain-ids (if (= transaction-type :tx/bridge)
disabled-to-chain-ids (if (= transaction-type :bridge)
(filter #(not= % bridge-to-chain-id) network-chain-ids)
(filter (fn [chain-id]
(not (some #(= chain-id %)
@@ -333,9 +322,8 @@
network-chain-ids))
from-locked-amount {}
transaction-type-param (case transaction-type
:tx/collectible-erc-721 constants/send-type-erc-721-transfer
:tx/collectible-erc-1155 constants/send-type-erc-1155-transfer
:tx/bridge constants/send-type-bridge
:collectible constants/send-type-erc-721-transfer
:bridge constants/send-type-bridge
constants/send-type-transfer)
balances-per-chain (when token (:balances-per-chain token))
token-available-networks-for-suggested-routes
@@ -347,28 +335,18 @@
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
{:valid-networks (if (= transaction-type :tx/bridge)
(filter
#(not= bridge-to-chain-id %)
token-available-networks-for-suggested-routes)
token-available-networks-for-suggested-routes)
{: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
:tx-type transaction-type
:receiver? false}))
receiver-network-values (when token-available-networks-for-suggested-routes
(send-utils/loading-network-amounts
{:valid-networks (if (= transaction-type :tx/bridge)
(filter
#(= bridge-to-chain-id %)
token-available-networks-for-suggested-routes)
token-available-networks-for-suggested-routes)
{:valid-networks token-available-networks-for-suggested-routes
:disabled-chain-ids disabled-from-chain-ids
:receiver-networks receiver-networks
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type transaction-type
:receiver? true}))
:receiver? true}))
request-params [transaction-type-param
from-address
to-address
@@ -409,10 +387,7 @@
{:db (-> db
(assoc-in [:wallet :transactions] transaction-details)
(assoc-in [:wallet :ui :send :transaction-ids] transaction-ids))
:fx [[:dispatch
[:wallet/wizard-navigate-forward
{:current-screen :screen/wallet.transaction-confirmation
:flow-id :wallet-send-flow}]]]})))
:fx [[:dispatch [:dismiss-modal :screen/wallet.transaction-confirmation]]]})))
(rf/reg-event-fx :wallet/close-transaction-progress-page
(fn [_]
@@ -421,7 +396,7 @@
[:dispatch [:wallet/clean-send-address]]
[:dispatch [:wallet/clean-disabled-from-networks]]
[:dispatch [:wallet/select-address-tab nil]]
[:dispatch [:dismiss-modal :screen/wallet.transaction-progress]]]}))
[:dispatch [:dismiss-modal :screen/wallet.transaction-confirmation]]]}))
(defn- transaction-data
[{:keys [from-address to-address token-address route data eth-transfer?]}]
@@ -477,14 +452,6 @@
:TokenID token-id
:ChainID to-chain-id))
(= bridge-name constants/bridge-name-erc-1155-transfer)
(assoc :ERC1155TransferTx
(assoc tx-data
:Recipient to-address
:TokenID token-id
:ChainID to-chain-id
:Amount amount-in))
(= bridge-name constants/bridge-name-transfer)
(assoc :TransferTx tx-data)
@@ -524,9 +491,8 @@
from-address (get-in db [:wallet :current-viewing-account-address])
transaction-type (get-in db [:wallet :ui :send :tx-type])
transaction-type-param (case transaction-type
:tx/collectible-erc-721 constants/send-type-erc-721-transfer
:tx/collectible-erc-1155 constants/send-type-erc-1155-transfer
:tx/bridge constants/send-type-bridge
:collectible constants/send-type-erc-721-transfer
:bridge constants/send-type-bridge
constants/send-type-transfer)
token (get-in db [:wallet :ui :send :token])
collectible (get-in db [:wallet :ui :send :collectible])
@@ -1,13 +1,11 @@
(ns status-im.contexts.wallet.send.flow-config
(:require
[status-im.contexts.wallet.send.utils :as send-utils]))
(ns status-im.contexts.wallet.send.flow-config)
(defn- collectible-selected?
[db]
(let [collectible-stored (-> db :wallet :ui :send :collectible)
tx-type (-> db :wallet :ui :send :tx-type)]
(and (some? collectible-stored)
(send-utils/tx-type-collectible? tx-type))))
(= tx-type :collectible))))
(defn- token-selected?
[db]
@@ -21,11 +19,9 @@
{:screen-id :screen/wallet.select-asset
:skip-step? (fn [db] (or (token-selected? db) (collectible-selected? db)))}
{:screen-id :screen/wallet.send-input-amount
:skip-step? (fn [db]
(send-utils/tx-type-collectible? (get-in db [:wallet :ui :send :tx-type])))}
:skip-step? (fn [db] (= (get-in db [:wallet :ui :send :tx-type]) :collectible))}
{:screen-id :screen/wallet.select-collectible-amount
:skip-step? (fn [db]
(or (not (collectible-selected? db))
(some? (get-in db [:wallet :ui :send :amount]))))}
{:screen-id :screen/wallet.transaction-confirmation}
{:screen-id :screen/wallet.transaction-progress}])
{:screen-id :screen/wallet.transaction-confirmation}])
@@ -53,7 +53,6 @@
"2500")
:has-error false}}
:total-balance 100
:available-balance 100
:market-values-per-currency {:usd {:price 10}}}
:wallet/wallet-send-loading-suggested-routes? false
:wallet/wallet-send-route [{:from {:chainid 1
@@ -69,7 +68,6 @@
:view-id :screen/wallet.send-input-amount
:wallet/wallet-send-to-address "0x04371e2d9d66b82f056bc128064"
:profile/currency-symbol "$"
:profile/currency :usd
:wallet/token-by-symbol {:symbol :eth
:total-balance 100
:market-values-per-currency {:usd {:price 10}}}
@@ -79,16 +77,7 @@
:wallet/wallet-send-sender-network-values nil
:wallet/wallet-send-receiver-network-values nil
:wallet/wallet-send-network-links nil
:wallet/wallet-send-receiver-preferred-networks [1]
:wallet/wallet-send-enabled-networks [{:source 879
:short-name "eth"
:network-name :mainnet
:abbreviated-name "Eth."
:chain-id 1
:related-chain-id 1
:layer 1}]
:wallet/wallet-send-enabled-from-chain-ids [1]
:wallet/wallet-send-amount nil})
:wallet/wallet-send-receiver-preferred-networks [1]})
(h/describe "Send > input amount screen"
(h/setup-restorable-re-frame)
@@ -175,6 +164,6 @@
(h/is-truthy (h/get-by-label-text :container-error))
(h/fire-event :press (h/query-by-label-text :reorder))
(-> (h/wait-for #(h/get-by-text "Max: $1000.00"))
(-> (h/wait-for #(h/get-by-text "Max: 1000.00 USD"))
(.then (fn []
(h/wait-for #(h/is-truthy (h/get-by-label-text :container))))))))
@@ -16,13 +16,11 @@
[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.debounce :as debounce]
[utils.i18n :as i18n]
[utils.money :as money]
[utils.number :as number]
[utils.re-frame :as rf]))
(defn- make-limit-label-crypto
(defn- make-limit-label
[amount currency]
(str amount
" "
@@ -30,10 +28,6 @@
name
string/upper-case)))
(defn- make-limit-label-fiat
[amount currency-symbol]
(str currency-symbol amount))
(defn- estimated-fees
[{:keys [loading-routes? fees amount receiver]}]
[rn/view {:style style/estimated-fees-container}
@@ -67,7 +61,6 @@
(every? (fn [{:keys [total-amount]}]
(and
total-amount
(money/bignumber? total-amount)
(money/equal-to total-amount
(money/bignumber "0"))))
sender-network-values))
@@ -134,138 +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)
[just-toggled-mode? set-just-toggled-mode?] (rn/use-state false)
clear-input! #(set-input-state controlled-input/delete-all)
handle-on-confirm (fn []
(rf/dispatch [:wallet/set-token-amount-to-send
{:amount
(controlled-input/input-value
input-state)
:stack-id current-screen-id}]))
{fiat-currency :currency} (rf/sub [:profile/profile])
(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
token-decimals :decimals} (rf/sub [:wallet/wallet-send-token])
send-enabled-networks (rf/sub [:wallet/wallet-send-enabled-networks])
enabled-from-chain-ids (rf/sub
[:wallet/wallet-send-enabled-from-chain-ids])
token-networks :networks} (rf/sub [:wallet/wallet-send-token])
{token-balance :total-balance
available-balance :available-balance
:as
token} (rf/sub
[:wallet/current-viewing-account-tokens-filtered
(str token-symbol) enabled-from-chain-ids])
currency-symbol (rf/sub [:profile/currency-symbol])
currency (rf/sub [:profile/currency])
conversion-rate (-> token :market-values-per-currency currency :price)
loading-routes? (rf/sub
[:wallet/wallet-send-loading-suggested-routes?])
route (rf/sub [:wallet/wallet-send-route])
to-address (rf/sub [:wallet/wallet-send-to-address])
on-confirm (or default-on-confirm handle-on-confirm)
crypto-decimals (or token-decimals default-crypto-decimals)
current-crypto-limit (or default-limit-crypto
(utils/get-standard-crypto-format
token
token-balance))
available-crypto-limit (or default-limit-crypto
(utils/get-standard-crypto-format
token
available-balance))
current-fiat-limit (.toFixed (* token-balance conversion-rate) 2)
available-fiat-limit (.toFixed (* available-balance conversion-rate) 2)
current-limit (if @crypto-currency?
current-crypto-limit
current-fiat-limit)
available-limit (if @crypto-currency?
available-crypto-limit
available-fiat-limit)
valid-input? (not (or (string/blank?
(controlled-input/input-value
input-state))
(<= (controlled-input/numeric-value
input-state)
0)
(> (controlled-input/numeric-value
input-state)
available-limit)))
input-num-value (controlled-input/numeric-value input-state)
input-amount (controlled-input/input-value input-state)
confirm-disabled? (or (nil? route)
(empty? route)
(string/blank? (controlled-input/input-value
input-state))
(<= input-num-value 0)
(> input-num-value current-limit))
amount (if @crypto-currency?
input-amount
(number/remove-trailing-zeroes
(.toFixed (/ input-amount conversion-rate)
crypto-decimals)))
send-amount (rf/sub [:wallet/wallet-send-amount])
amount-text (str (number/remove-trailing-zeroes
(.toFixed (js/parseFloat send-amount)
(min token-decimals 6)))
" "
token-symbol)
first-route (first route)
native-currency-symbol (when-not confirm-disabled?
(get-in first-route
[:from :native-currency-symbol]))
native-token (when native-currency-symbol
(rf/sub [:wallet/token-by-symbol
native-currency-symbol]))
fee-in-native-token (when-not confirm-disabled?
(send-utils/calculate-full-route-gas-fee route))
fee-in-crypto-formatted (when fee-in-native-token
(utils/get-standard-crypto-format
native-token
fee-in-native-token))
fee-in-fiat (when-not confirm-disabled?
(utils/calculate-token-fiat-value
{:currency fiat-currency
:balance fee-in-native-token
:token native-token}))
fee-formatted (when fee-in-fiat
(utils/get-standard-fiat-format
fee-in-crypto-formatted
currency-symbol
fee-in-fiat))
show-select-asset-sheet #(rf/dispatch
[:show-bottom-sheet
{:content (fn []
[select-asset-bottom-sheet
clear-input!])}])
sender-network-values (rf/sub
[:wallet/wallet-send-sender-network-values])
receiver-network-values (rf/sub
[:wallet/wallet-send-receiver-network-values])
token} (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])
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))
input-error (controlled-input/input-error input-state)
limit-insufficient? (> (controlled-input/numeric-value input-state)
current-limit)
should-try-again? (and (not limit-insufficient?) no-routes-found?)]
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!))
@@ -275,9 +242,6 @@
(fn []
(set-input-state #(controlled-input/set-upper-limit % current-limit)))
[current-limit])
(rn/use-effect
#(when input-error (debounce/clear-all))
[input-error])
[rn/view
{:style style/screen
:accessibility-label (str "container"
@@ -289,40 +253,22 @@
[quo/token-input
{:container-style style/input-container
:token token-symbol
:currency fiat-currency
:currency-symbol currency-symbol
:crypto-decimals (min token-decimals 6)
:currency current-currency
:crypto-decimals crypto-decimals
:error? (controlled-input/input-error input-state)
:networks (seq send-enabled-networks)
:title (i18n/label
:t/send-limit
{:limit (if @crypto-currency?
(make-limit-label-crypto current-limit token-symbol)
(make-limit-label-fiat current-limit currency-symbol))})
:networks (seq token-networks)
:title (i18n/label :t/send-limit
{:limit (make-limit-label current-limit current-currency)})
:conversion conversion-rate
:show-keyboard? false
:value input-amount
:on-swap (fn [swap-to-crypto-currency?]
(set-just-toggled-mode? true)
(reset! crypto-currency? swap-to-crypto-currency?)
(set-input-state
(fn [input-state]
(controlled-input/set-input-value
input-state
(let [value (controlled-input/input-value input-state)
new-value (if swap-to-crypto-currency?
(.toFixed (/ value conversion-rate)
crypto-decimals)
(.toFixed (* value conversion-rate) 12))]
(number/remove-trailing-zeroes new-value))))))
:value (controlled-input/input-value input-state)
:on-swap #(reset! crypto-currency? %)
:on-token-press show-select-asset-sheet}]
[routes/view
{:token token
:input-value input-amount
:value amount
:input-value (controlled-input/input-value input-state)
:valid-input? valid-input?
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
:lock-fetch-routes? just-toggled-mode?
:current-screen-id current-screen-id}]
(when (and (not loading-routes?)
sender-network-values
@@ -334,7 +280,7 @@
:fees fee-formatted
:amount amount-text
:receiver (address/get-shortened-key to-address)}])
(when (or no-routes-found? limit-insufficient?)
(when no-routes-found?
[rn/view {:style style/no-routes-found-container}
[quo/info-message
{:type :error
@@ -344,49 +290,32 @@
(i18n/label :t/no-routes-found)]])
[quo/bottom-actions
{:actions :one-action
:button-one-label (if should-try-again?
:button-one-label (if no-routes-found?
(i18n/label :t/try-again)
button-one-label)
:button-one-props (merge (when-not should-try-again? button-one-props)
{:disabled? (and (not should-try-again?) confirm-disabled?)
:button-one-props (merge button-one-props
{:disabled? (and (not no-routes-found?) confirm-disabled?)
:on-press (cond
should-try-again?
#(let [input-amount (controlled-input/input-value
input-state)
amount (if @crypto-currency?
input-amount
(.toFixed (* token-balance
conversion-rate)
2))]
(rf/dispatch [:wallet/get-suggested-routes
{:amount amount}]))
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 should-try-again?
(when no-routes-found?
{:type :grey}))}]
[quo/numbered-keyboard
{:container-style (style/keyboard-container bottom)
:left-action :dot
:delete-key? true
:on-press (fn [c]
(let [new-text (str input-amount c)
max-decimals (if @crypto-currency? crypto-decimals 2)
regex-pattern (str "^\\d*\\.?\\d{0," max-decimals "}$")
regex (re-pattern regex-pattern)]
(when (and (not loading-routes?)
(re-matches regex new-text))
(debounce/clear-all)
(set-just-toggled-mode? false)
(set-input-state #(controlled-input/add-character % c)))))
(when-not loading-routes?
(set-input-state #(controlled-input/add-character % c))))
:on-delete (fn []
(when-not loading-routes?
(debounce/clear-all)
(set-just-toggled-mode? false)
(set-input-state controlled-input/delete-last)))
:on-long-press-delete (fn []
(when-not loading-routes?
(debounce/clear-all)
(set-just-toggled-mode? false)
(set-input-state controlled-input/delete-all)))}]]))))
@@ -16,8 +16,8 @@
(def network-link-1x-height 56)
(def network-link-2x-height 111)
(defn- fetch-routes
[{:keys [amount bounce-duration-ms valid-input?]}]
(defn fetch-routes
[amount valid-input? bounce-duration-ms]
(if valid-input?
(debounce/debounce-and-dispatch
[:wallet/get-suggested-routes {:amount amount}]
@@ -174,8 +174,8 @@
:text (i18n/label :t/at-least-one-network-must-be-activated)}]))))
(defn view
[{:keys [token theme input-value value valid-input?
lock-fetch-routes? on-press-to-network current-screen-id
[{:keys [token theme input-value valid-input?
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])
@@ -198,21 +198,12 @@
:disabled-chain-ids disabled-from-chain-ids})
show-routes? (not-empty sender-network-values)]
(rn/use-effect
(fn []
(when (and active-screen?
(> (count token-available-networks-for-suggested-routes) 0)
(not lock-fetch-routes?))
(fetch-routes
{:amount value
:valid-input? valid-input?
:bounce-duration-ms 2000})))
#(when (and active-screen? (> (count token-available-networks-for-suggested-routes) 0))
(fetch-routes input-value valid-input? 2000))
[input-value valid-input?])
(rn/use-effect
#(when (and active-screen? (> (count token-available-networks-for-suggested-routes) 0))
(fetch-routes
{:amount value
:valid-input? valid-input?
:bounce-duration-ms 0}))
(fetch-routes input-value valid-input? 0))
[disabled-from-chain-ids])
[rn/scroll-view {:content-container-style style/routes-container}
(when show-routes?
@@ -247,8 +238,5 @@
:loading-routes? loading-routes?
:theme theme
:token-not-supported-in-receiver-networks? token-not-supported-in-receiver-networks?
:on-save #(fetch-routes
{:amount input-value
:valid-input? valid-input?
:bounce-duration-ms 0})}]]]))
:on-save #(fetch-routes input-value valid-input? 0)}]]]))
@@ -156,26 +156,24 @@
local-suggestion-address (rf/sub [:wallet/local-suggestions->full-address])
color (rf/sub [:wallet/current-viewing-account-color])]
[floating-button-page/view
{:footer-container-padding 0
:keyboard-should-persist-taps true
:header [account-switcher/view
{:on-press on-close
:margin-top (safe-area/get-top)
:switcher-type :select-account}]
:footer (when (> (count @input-value) 0)
[quo/button
{:accessibility-label :continue-button
:type :primary
:disabled? (not valid-ens-or-address?)
:on-press #(rf/dispatch
[:wallet/select-send-address
{:address (or
local-suggestion-address
@input-value)
:stack-id
:screen/wallet.select-address}])
:customization-color color}
(i18n/label :t/continue)])}
{:footer-container-padding 0
:header [account-switcher/view
{:on-press on-close
:margin-top (safe-area/get-top)
:switcher-type :select-account}]
:footer (when (> (count @input-value) 0)
[quo/button
{:accessibility-label :continue-button
:type :primary
:disabled? (not valid-ens-or-address?)
:on-press #(rf/dispatch
[:wallet/select-send-address
{:address (or local-suggestion-address
@input-value)
:stack-id
:screen/wallet.select-address}])
:customization-color color}
(i18n/label :t/continue)])}
[quo/page-top
{:title (i18n/label :t/send-to)
:title-accessibility-label :title-label}]
@@ -3,6 +3,7 @@
[clojure.string :as string]
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
[status-im.contexts.wallet.common.asset-list.view :as asset-list]
[status-im.contexts.wallet.common.collectibles-tab.view :as collectibles-tab]
@@ -58,32 +59,33 @@
(defn view
[]
(let [[selected-tab set-selected-tab] (rn/use-state (:id (first tabs-data)))
[search-text set-search-text] (rn/use-state "")
on-change-text #(set-search-text %)
on-change-tab #(set-selected-tab %)
on-close (fn []
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])
(rf/dispatch [:navigate-back]))]
(let [selected-tab (reagent/atom (:id (first tabs-data)))
search-text (reagent/atom "")
on-change-text #(reset! search-text %)
on-change-tab #(reset! selected-tab %)
on-close (fn []
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])
(rf/dispatch [:navigate-back]))]
(rn/use-unmount (fn []
(rf/dispatch [:wallet/clean-selected-token])
(rf/dispatch [:wallet/clean-selected-collectible])))
[rn/safe-area-view {:style style/container}
[account-switcher/view
{:icon-name :i/arrow-left
:on-press on-close
:switcher-type :select-account}]
[quo/page-top
{:title (i18n/label :t/select-asset)
:title-accessibility-label :title-label}]
[quo/segmented-control
{:size 32
:blur? false
:symbol false
:default-active :tab/assets
:container-style {:margin-horizontal 20
:margin-vertical 8}
:data tabs-data
:on-change on-change-tab}]
[tab-view search-text selected-tab on-change-text]]))
(fn []
[rn/safe-area-view {:style style/container}
[account-switcher/view
{:icon-name :i/arrow-left
:on-press on-close
:switcher-type :select-account}]
[quo/page-top
{:title (i18n/label :t/select-asset)
:title-accessibility-label :title-label}]
[quo/segmented-control
{:size 32
:blur? false
:symbol false
:default-active :tab/assets
:container-style {:margin-horizontal 20
:margin-vertical 8}
:data tabs-data
:on-change on-change-tab}]
[tab-view @search-text @selected-tab on-change-text]])))
@@ -26,7 +26,7 @@
:weight :semi-bold
:style style/title-container
:accessibility-label :send-label}
(if (= transaction-type :tx/bridge)
(if (= transaction-type :bridge)
(i18n/label :t/bridge)
(i18n/label :t/send))]
[quo/summary-tag
@@ -34,7 +34,7 @@
:label (str amount " " token-display-name)
:type (if collectible? :collectible :token)
:image-source (if collectible? image-url :eth)}]]
(if (= transaction-type :tx/bridge)
(if (= transaction-type :bridge)
(map-indexed
(fn [idx path]
(let [from-network (:from path)
@@ -98,7 +98,7 @@
:style style/title-container
:accessibility-label :send-label}
(i18n/label :t/to)]
(if (= transaction-type :tx/bridge)
(if (= transaction-type :bridge)
[quo/summary-tag
{:type :network
:image-source (:source to-network)
@@ -107,7 +107,7 @@
[quo/summary-tag
{:type :address
:label (utils/get-shortened-address to-address)}])]
(when (= transaction-type :tx/bridge)
(when (= transaction-type :bridge)
[rn/view
{:style {:flex-direction :row
:margin-top 4}}
@@ -198,7 +198,7 @@
{:amount (str max-fees)
:symbol currency-symbol})}]
[data-item
{:title (if (= transaction-type :tx/bridge)
{:title (if (= transaction-type :bridge)
(i18n/label :t/bridged-to
{:network (:abbreviated-name to-network)})
(i18n/label :t/user-gets {:name (utils/get-shortened-address to-address)}))
@@ -249,7 +249,7 @@
:footer (when (and route (seq route))
[standard-auth/slide-button
{:size :size-48
:track-text (if (= transaction-type :tx/bridge)
:track-text (if (= transaction-type :bridge)
(i18n/label :t/slide-to-bridge)
(i18n/label :t/slide-to-send))
:container-style {:z-index 2}
@@ -282,12 +282,12 @@
:theme theme}]
[user-summary
{:token-display-name token-display-name
:summary-type (if (= transaction-type :tx/bridge)
:summary-type (if (= transaction-type :bridge)
:status-account
:account)
:accessibility-label :summary-to-label
:label (i18n/label :t/to-capitalized)
:account-props (if (= transaction-type :tx/bridge)
:account-props (if (= transaction-type :bridge)
from-account-props
user-props)
:network-values to-values-by-chain
+14 -27
View File
@@ -94,7 +94,7 @@
network-amounts))
(defn network-amounts
[{:keys [network-values disabled-chain-ids receiver-networks token-networks-ids tx-type receiver?]}]
[{: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))
@@ -150,12 +150,11 @@
(vec))
(and receiver?
routes-found?
(< (count network-values-with-not-available-chains) available-networks-count)
(not= tx-type :tx/bridge))
(< (count network-values-with-not-available-chains) available-networks-count))
(conj {:type :add}))))
(defn loading-network-amounts
[{:keys [valid-networks disabled-chain-ids receiver-networks token-networks-ids tx-type receiver?]}]
[{: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)
@@ -165,13 +164,11 @@
(filter #(not (token-networks-ids-set %)) receiver-networks)
[])
not-available-networks-set (set not-available-networks)
valid-networks (-> (concat valid-networks
(when (not (and receiver? (= tx-type :tx/bridge)))
disabled-chain-ids)
(when receiver?
(filter #(not (valid-networks-set %))
not-available-networks)))
(distinct))]
valid-networks (concat valid-networks
disabled-chain-ids
(when receiver?
(filter #(not (valid-networks-set %))
not-available-networks)))]
(cond-> (->> valid-networks
(map
(fn [chain-id]
@@ -184,18 +181,16 @@
(and (not receiver?) (contains? disabled-set chain-id)) :disabled)}
(and (not receiver?) (contains? disabled-set chain-id))
(assoc :total-amount (money/bignumber "0")))))
(filter
(fn [network-amount]
(or (and receiver?
(or (= tx-type :tx/bridge)
(contains? receiver-networks-set (:chain-id network-amount))))
(not receiver?))))
(sort-by (fn [network-amount]
(get network-priority-score
(network-utils/id->network (:chain-id network-amount)))))
(filter
(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 receiver? (< receiver-networks-count available-networks-count) (not= tx-type :tx/bridge))
(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]
@@ -213,11 +208,3 @@
:position-diff position-diff})))
[]
route))
(def ^:private collectible-tx-set
#{:tx/collectible-erc-721
:tx/collectible-erc-1155})
(defn tx-type-collectible?
[tx-type]
(contains? collectible-tx-set tx-type))
+133 -237
View File
@@ -33,9 +33,9 @@
(deftest test-network-amounts-by-chain
(testing "Correctly calculates network amounts for transaction with native token"
(let [route [{:amount-in "0xde0b6b3a7640000"
:to {:chain-id 1}}
:to {:chain-id "1"}}
{:amount-in "0xde0b6b3a7640000"
:to {:chain-id 10}}]
:to {:chain-id "2"}}]
token-decimals 18
native-token? true
receiver? true
@@ -43,17 +43,17 @@
:token-decimals token-decimals
:native-token? native-token?
:receiver? receiver?})
expected {1 (money/bignumber "1")
10 (money/bignumber "1")}]
expected {"1" (money/bignumber "1")
"2" (money/bignumber "1")}]
(doseq [[chain-id exp-value] expected]
(is (money/equal-to (get result chain-id) exp-value)))))
(testing
"Correctly calculates network amounts for transaction with native token and multiple routes to same chain-id"
(let [route [{:amount-in "0xde0b6b3a7640000"
:to {:chain-id 1}}
:to {:chain-id "1"}}
{:amount-in "0xde0b6b3a7640000"
:to {:chain-id 1}}]
:to {:chain-id "1"}}]
token-decimals 18
native-token? true
receiver? true
@@ -61,15 +61,15 @@
:token-decimals token-decimals
:native-token? native-token?
:receiver? receiver?})
expected {1 (money/bignumber "2")}]
expected {"1" (money/bignumber "2")}]
(doseq [[chain-id exp-value] expected]
(is (money/equal-to (get result chain-id) exp-value)))))
(testing "Correctly calculates network amounts for transaction with non-native token"
(let [route [{:amount-out "0x1e8480"
:from {:chain-id 1}}
:from {:chain-id "1"}}
{:amount-out "0x1e8480"
:from {:chain-id 10}}]
:from {:chain-id "2"}}]
token-decimals 6
native-token? false
receiver? false
@@ -77,20 +77,20 @@
:token-decimals token-decimals
:native-token? native-token?
:receiver? receiver?})
expected {1 (money/bignumber "2")
10 (money/bignumber "2")}]
expected {"1" (money/bignumber "2")
"2" (money/bignumber "2")}]
(doseq [[chain-id exp-value] expected]
(is (money/equal-to (get result chain-id) exp-value))))))
(deftest test-network-values-for-ui
(testing "Sanitizes values correctly for display"
(let [amounts {1 (money/bignumber "0")
10 (money/bignumber "2.5")
42161 (money/bignumber "0.005")}
(let [amounts {"1" (money/bignumber "0")
"2" (money/bignumber "2.5")
"3" (money/bignumber "0.005")}
result (utils/network-values-for-ui amounts)
expected {1 "<0.01"
10 (money/bignumber "2.5")
42161 (money/bignumber "0.005")}]
expected {"1" "<0.01"
"2" (money/bignumber "2.5")
"3" (money/bignumber "0.005")}]
(doseq [[chain-id exp-value] expected]
(is #(or (= (get result chain-id) exp-value)
(money/equal-to (get result chain-id) exp-value)))))))
@@ -168,32 +168,32 @@
(deftest test-token-available-networks-for-suggested-routes
(testing "Excludes disabled chain-ids correctly"
(let [balances-per-chain {1 {:chain-id 1 :balance 100}
10 {:chain-id 10 :balance 200}
42161 {:chain-id 42161 :balance 300}}
disabled-chain-ids [10]
expected [1 42161]]
(let [balances-per-chain {"1" {:chain-id "1" :balance 100}
"10" {:chain-id "10" :balance 200}
"42161" {:chain-id "42161" :balance 300}}
disabled-chain-ids ["10"]
expected ["1" "42161"]]
(is (= expected
(utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain
:disabled-chain-ids
disabled-chain-ids})))))
(testing "Returns all chains when no disabled chains are specified"
(let [balances-per-chain {1 {:chain-id 1 :balance 100}
10 {:chain-id 10 :balance 200}
42161 {:chain-id 42161 :balance 300}}
(let [balances-per-chain {"1" {:chain-id "1" :balance 100}
"10" {:chain-id "10" :balance 200}
"42161" {:chain-id "42161" :balance 300}}
disabled-chain-ids []
expected [1 10 42161]]
expected ["1" "10" "42161"]]
(is (= expected
(utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain
:disabled-chain-ids
disabled-chain-ids})))))
(testing "Returns empty list when all chains are disabled"
(let [balances-per-chain {1 {:chain-id 1 :balance 100}
10 {:chain-id 10 :balance 200}
42161 {:chain-id 42161 :balance 300}}
disabled-chain-ids [1 10 42161]
(let [balances-per-chain {"1" {:chain-id "1" :balance 100}
"10" {:chain-id "10" :balance 200}
"42161" {:chain-id "42161" :balance 300}}
disabled-chain-ids ["1" "10" "42161"]
expected []]
(is (= expected
(utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain
@@ -201,9 +201,9 @@
disabled-chain-ids})))))
(testing "Handles non-existent chain-ids gracefully"
(let [balances-per-chain {59144 {:chain-id 59144 :balance 400}}
disabled-chain-ids [1 10 42161]
expected [59144]]
(let [balances-per-chain {"59144" {:chain-id "59144" :balance 400}}
disabled-chain-ids ["1" "10" "42161"]
expected ["59144"]]
(is (= expected
(utils/token-available-networks-for-suggested-routes {:balances-per-chain balances-per-chain
:disabled-chain-ids
@@ -211,10 +211,10 @@
(deftest test-reset-network-amounts-to-zero
(testing "Correctly resets loading network amounts to zero and changes type to default"
(let [network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}]
expected [{:chain-id 1 :total-amount (money/bignumber "0") :type :default}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}]
(let [network-amounts [{:chain-id "1" :total-amount (money/bignumber "100") :type :loading}
{:chain-id "10" :total-amount (money/bignumber "200") :type :default}]
expected [{:chain-id "1" :total-amount (money/bignumber "0") :type :default}
{:chain-id "10" :total-amount (money/bignumber "200") :type :default}]
result (utils/reset-network-amounts-to-zero network-amounts)
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -222,10 +222,10 @@
(is (every? identity comparisons))))
(testing "Leaves non-loading types unchanged"
(let [network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :default}
{:chain-id 10 :total-amount (money/bignumber "0") :type :disabled}]
expected [{:chain-id 1 :total-amount (money/bignumber "100") :type :default}
{:chain-id 10 :total-amount (money/bignumber "0") :type :disabled}]
(let [network-amounts [{:chain-id "1" :total-amount (money/bignumber "100") :type :default}
{:chain-id "10" :total-amount (money/bignumber "0") :type :disabled}]
expected [{:chain-id "1" :total-amount (money/bignumber "100") :type :default}
{:chain-id "10" :total-amount (money/bignumber "0") :type :disabled}]
result (utils/reset-network-amounts-to-zero network-amounts)
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -242,10 +242,10 @@
(is (every? identity comparisons))))
(testing "Applies transformations to multiple loading entries"
(let [network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}
{:chain-id 10 :total-amount (money/bignumber "200") :type :loading}]
expected [{:chain-id 1 :total-amount (money/bignumber "0") :type :default}
{:chain-id 10 :total-amount (money/bignumber "0") :type :default}]
(let [network-amounts [{:chain-id "1" :total-amount (money/bignumber "100") :type :loading}
{:chain-id "10" :total-amount (money/bignumber "200") :type :loading}]
expected [{:chain-id "1" :total-amount (money/bignumber "0") :type :default}
{:chain-id "10" :total-amount (money/bignumber "0") :type :default}]
result (utils/reset-network-amounts-to-zero network-amounts)
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -253,14 +253,14 @@
(is (every? identity comparisons))))
(testing "Mix of loading and non-loading types"
(let [network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}
{:chain-id 42161 :total-amount (money/bignumber "300") :type :loading}
{:chain-id 59144 :total-amount (money/bignumber "0") :type :disabled}]
expected [{:chain-id 1 :total-amount (money/bignumber "0") :type :default}
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}
{:chain-id 42161 :total-amount (money/bignumber "0") :type :default}
{:chain-id 59144 :total-amount (money/bignumber "0") :type :disabled}]
(let [network-amounts [{:chain-id "1" :total-amount (money/bignumber "100") :type :loading}
{:chain-id "10" :total-amount (money/bignumber "200") :type :default}
{:chain-id "42161" :total-amount (money/bignumber "300") :type :loading}
{:chain-id "59144" :total-amount (money/bignumber "0") :type :disabled}]
expected [{:chain-id "1" :total-amount (money/bignumber "0") :type :default}
{:chain-id "10" :total-amount (money/bignumber "200") :type :default}
{:chain-id "42161" :total-amount (money/bignumber "0") :type :default}
{:chain-id "59144" :total-amount (money/bignumber "0") :type :disabled}]
result (utils/reset-network-amounts-to-zero network-amounts)
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -269,46 +269,42 @@
(deftest test-network-amounts
(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]
token-networks-ids [1 10 42161]
(let [network-values {"1" (money/bignumber "100")
"10" (money/bignumber "200")}
disabled-chain-ids ["1"]
receiver-networks ["10"]
token-networks-ids ["1" "10" "42161"]
receiver? true
expected [{:chain-id 1
expected [{:chain-id "1"
:total-amount (money/bignumber "100")
:type :default}
{:chain-id 10
{:chain-id "10"
:total-amount (money/bignumber "200")
:type :default}
{:type :add}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
(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]
(let [network-values {"1" (money/bignumber "100")}
disabled-chain-ids ["10"]
receiver-networks []
token-networks-ids [1 10 42161]
token-networks-ids ["1" "10" "42161"]
receiver? false
expected [{:chain-id 1
expected [{:chain-id "1"
:total-amount (money/bignumber "100")
:type :default}
{:chain-id 10
{:chain-id "10"
:total-amount (money/bignumber "0")
:type :disabled}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
@@ -319,139 +315,90 @@
token-networks-ids []
receiver? true
expected []
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (= expected result))))
(testing "Processes case with multiple network interactions"
(let [network-values {1 (money/bignumber "300")
10 (money/bignumber "400")
42161 (money/bignumber "500")}
disabled-chain-ids [1 42161]
receiver-networks [10]
token-networks-ids [1 10 42161]
(let [network-values {"1" (money/bignumber "300")
"10" (money/bignumber "400")
"42161" (money/bignumber "500")}
disabled-chain-ids ["1" "42161"]
receiver-networks ["10"]
token-networks-ids ["1" "10" "42161"]
receiver? true
expected [{:chain-id 1
expected [{:chain-id "1"
:total-amount (money/bignumber "300")
:type :default}
{:chain-id 10
{:chain-id "10"
:total-amount (money/bignumber "400")
:type :default}
{:chain-id 42161
{:chain-id "42161"
:total-amount (money/bignumber "500")
:type :default}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
: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]
(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
expected [{:chain-id "1"
:total-amount (money/bignumber "100")
:type :default}
{:chain-id 10
{:chain-id "10"
:total-amount (money/bignumber "0")
:type :disabled}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
: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")}
(let [network-values {"1" (money/bignumber "100")}
disabled-chain-ids []
receiver-networks [1 10]
token-networks-ids [1]
receiver-networks ["1" "10"]
token-networks-ids ["1"]
receiver? false
expected [{:chain-id 1
expected [{:chain-id "1"
:total-amount (money/bignumber "100")
:type :default}
{:chain-id 10
{:chain-id "10"
:total-amount nil
:type :not-available}]
tx-type :send
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
(testing "Handles disabled and receiver networks correctly when to? is false and tx-type is :tx/bridge"
(let [network-values {10 (money/bignumber "200")}
disabled-chain-ids [1]
receiver-networks [10]
token-networks-ids [1 10]
tx-type :tx/bridge
receiver? false
expected [{:chain-id 1
:total-amount (money/bignumber "0")
:type :disabled}
{:chain-id 10
:total-amount (money/bignumber "200")
:type :default}]
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result)))))
(testing "Handles disabled and receiver networks correctly when to? is true and tx-type is :tx/bridge"
(let [network-values {10 (money/bignumber "200")}
disabled-chain-ids [1]
receiver-networks [10]
token-networks-ids [1 10]
tx-type :tx/bridge
receiver? true
expected [{:chain-id 10
:total-amount (money/bignumber "200")
:type :default}]
result (utils/network-amounts {:network-values network-values
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})]
(is (every? identity (map #(map/deep-compare %1 %2) expected result))))))
(deftest test-loading-network-amounts
(testing "Assigns :loading type to valid networks except for disabled ones"
(let [valid-networks [1 10 42161]
disabled-chain-ids [42161]
receiver-networks [1 10]
token-networks-ids [1 10 42161]
(let [valid-networks ["1" "10" "42161"]
disabled-chain-ids ["42161"]
receiver-networks ["1" "10"]
token-networks-ids ["1" "10" "42161"]
receiver? true
expected [{:chain-id 1 :type :loading}
{:chain-id 10 :type :loading}
expected [{:chain-id "1" :type :loading}
{:chain-id "10" :type :loading}
{:type :add}]
tx-type :send
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
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -459,20 +406,18 @@
(is (every? identity comparisons))))
(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]
token-networks-ids [1 10 42161]
(let [valid-networks ["1" "10" "42161"]
disabled-chain-ids ["10" "42161"]
receiver-networks ["1"]
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")}]
tx-type :send
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 valid-networks
:disabled-chain-ids disabled-chain-ids
:receiver-networks receiver-networks
:token-networks-ids token-networks-ids
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -480,19 +425,17 @@
(is (every? identity comparisons))))
(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]
token-networks-ids [1 10 42161]
(let [valid-networks ["1" "10" "42161" "59144"]
disabled-chain-ids ["10"]
receiver-networks ["1" "42161"]
token-networks-ids ["1" "10" "42161"]
receiver? true
expected [{:chain-id 1 :type :loading}
{:chain-id 42161 :type :loading}]
tx-type :send
expected [{:chain-id "1" :type :loading}
{: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
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -501,19 +444,17 @@
(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]
token-networks-ids [1 10 42161]
(let [valid-networks ["1" "10" "42161"]
disabled-chain-ids ["10"]
receiver-networks ["1"]
token-networks-ids ["1" "10" "42161"]
receiver? true
expected [{:chain-id 1 :type :loading}
expected [{:chain-id "1" :type :loading}
{:type :add}]
tx-type :send
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
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -522,18 +463,16 @@
(testing
"Assigns :not-available type to networks not available in token-networks-ids when receiver? is false"
(let [valid-networks [42161]
(let [valid-networks ["42161"]
disabled-chain-ids []
receiver-networks [1]
token-networks-ids [42161]
receiver-networks ["1"]
token-networks-ids ["42161"]
receiver? false
expected [{:chain-id 42161 :type :loading}]
tx-type :send
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
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -542,60 +481,17 @@
(testing
"Assigns :not-available type to networks not available in token-networks-ids when receiver? is true"
(let [valid-networks [42161]
(let [valid-networks ["42161"]
disabled-chain-ids []
receiver-networks [1]
token-networks-ids [42161]
receiver-networks ["1"]
token-networks-ids ["42161"]
receiver? true
expected [{:chain-id 1 :type :not-available}
expected [{:chain-id "1" :type :not-available}
{:type :add}]
tx-type :send
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
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
result)]
(is (every? identity comparisons))))
(testing
"Assigns :loading type to valid networks and :disabled for disabled ones when tx-type is :tx/bridge and to? false"
(let [valid-networks [1 10]
disabled-chain-ids [10]
receiver-networks []
token-networks-ids [1 10]
tx-type :tx/bridge
receiver? false
expected [{:chain-id 1 :type :loading}
{:chain-id 10 :type :disabled :total-amount (money/bignumber "0")}]
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
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
result)]
(is (every? identity comparisons))))
(testing
"Assigns :loading type to valid networks, ignore disabled ones and do not add {:type :add} when tx-type is :tx/bridge and to? true"
(let [valid-networks [1]
disabled-chain-ids [10]
receiver-networks []
token-networks-ids [1 10]
tx-type :tx/bridge
receiver? true
expected [{:chain-id 1 :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
:tx-type tx-type
:receiver? receiver?})
comparisons (map #(map/deep-compare %1 %2)
expected
@@ -604,22 +500,22 @@
(deftest test-network-links
(testing "Calculates position differences correctly"
(let [route [{:from {:chain-id 1} :to {:chain-id 42161}}
{:from {:chain-id 10} :to {:chain-id 1}}
{:from {:chain-id 42161} :to {:chain-id 10}}]
from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
to-values-by-chain [{:chain-id 42161} {:chain-id 1} {:chain-id 10}]
expected [{:from-chain-id 1 :to-chain-id 42161 :position-diff 0}
{:from-chain-id 10 :to-chain-id 1 :position-diff 0}
{:from-chain-id 42161 :to-chain-id 10 :position-diff 0}]
(let [route [{:from {:chain-id "1"} :to {:chain-id "42161"}}
{:from {:chain-id "10"} :to {:chain-id "1"}}
{:from {:chain-id "42161"} :to {:chain-id "10"}}]
from-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
to-values-by-chain [{:chain-id "42161"} {:chain-id "1"} {:chain-id "10"}]
expected [{:from-chain-id "1" :to-chain-id "42161" :position-diff 0}
{:from-chain-id "10" :to-chain-id "1" :position-diff 0}
{:from-chain-id "42161" :to-chain-id "10" :position-diff 0}]
result (utils/network-links route from-values-by-chain to-values-by-chain)]
(is (= expected result))))
(testing "Handles cases with no position difference"
(let [route [{:from {:chain-id 1} :to {:chain-id 1}}]
from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
to-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
expected [{:from-chain-id 1 :to-chain-id 1 :position-diff 0}]
(let [route [{:from {:chain-id "1"} :to {:chain-id "1"}}]
from-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
to-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
expected [{:from-chain-id "1" :to-chain-id "1" :position-diff 0}]
result (utils/network-links route from-values-by-chain to-values-by-chain)]
(is (= expected result))))
@@ -632,9 +528,9 @@
(is (= expected result))))
(testing "Verifies negative position differences"
(let [route [{:from {:chain-id 1} :to {:chain-id 42161}}]
from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
to-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
expected [{:from-chain-id 1 :to-chain-id 42161 :position-diff -2}]
(let [route [{:from {:chain-id "1"} :to {:chain-id "42161"}}]
from-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
to-values-by-chain [{:chain-id "1"} {:chain-id "10"} {:chain-id "42161"}]
expected [{:from-chain-id "1" :to-chain-id "42161" :position-diff -2}]
result (utils/network-links route from-values-by-chain to-values-by-chain)]
(is (= expected result)))))
+4 -4
View File
@@ -85,8 +85,8 @@
wallet-key-pair-name]
[status-im.contexts.wallet.add-account.create-account.new-keypair.backup-recovery-phrase.view :as
wallet-backup-recovery-phrase]
[status-im.contexts.wallet.add-account.create-account.new-keypair.confirm-backup.view :as
wallet-confirm-backup]
[status-im.contexts.wallet.add-account.create-account.new-keypair.check-your-backup.view :as
wallet-check-your-backup]
[status-im.contexts.wallet.add-account.create-account.select-keypair.view :as wallet-select-keypair]
[status-im.contexts.wallet.add-account.create-account.view :as wallet-create-account]
[status-im.contexts.wallet.bridge.bridge-to.view :as wallet-bridge-to]
@@ -430,9 +430,9 @@
:options {:insets {:top? true :bottom? true}}
:component wallet-backup-recovery-phrase/view}
{:name :screen/wallet.confirm-backup
{:name :screen/wallet.check-your-backup
:options {:insets {:top? true :bottom? true}}
:component wallet-confirm-backup/view}
:component wallet-check-your-backup/view}
{:name :screen/wallet.keypair-name
:options {:insets {:top? true}}
+17 -25
View File
@@ -169,31 +169,23 @@
:chats/current-chat-chat-view
:<- [:chats/current-chat]
(fn [current-chat]
(assoc
(select-keys current-chat
[:chat-id
:able-to-send-message?
:group-chat
:admins
:invitation-admin
:public?
:chat-type
:color
:contact-request-state
:chat-name
:synced-to
:synced-from
:community-id
:emoji
:description])
:empty-chat?
(not (:last-message current-chat)))))
(re-frame/reg-sub
:chats/current-chat-exist?
:<- [:chats/current-chat-chat-view]
(fn [current-chat]
(boolean (:chat-id current-chat))))
(select-keys current-chat
[:chat-id
:able-to-send-message?
:group-chat
:admins
:invitation-admin
:public?
:chat-type
:color
:contact-request-state
:chat-name
:synced-to
:synced-from
:community-id
:emoji
:description
:last-message])))
(re-frame/reg-sub
:chats/current-chat-color
-15
View File
@@ -192,18 +192,3 @@
chats)
(let [result (rf/sub [sub-name chat-id])]
(= image-data result)))))
(h/deftest-sub :chats/current-chat-exist?
[sub-name]
(testing "current chat without chat-id"
(let [chats {chat-id (dissoc one-to-one-chat :chat-id)}]
(swap! rf-db/app-db assoc
:chats chats
:current-chat-id chat-id)
(is (false? (rf/sub [sub-name])))))
(testing "current chat with chat-id"
(let [chats {chat-id one-to-one-chat}]
(swap! rf-db/app-db assoc
:chats chats
:current-chat-id chat-id)
(is (true? (rf/sub [sub-name]))))))
+6 -6
View File
@@ -21,7 +21,7 @@
:chain-id 4
:layer 2}
{:test? true
:short-name "oeth"
:short-name "opt"
:related-chain-id 10
:chain-id 5
:layer 2}]
@@ -34,7 +34,7 @@
:chain-id 42161
:layer 2}
{:test? false
:short-name "oeth"
:short-name "opt"
:chain-id 10
:layer 2}]})
@@ -54,8 +54,8 @@
:chain-id 42161
:layer 2}
{:network-name :optimism
:short-name "oeth"
:abbreviated-name "Oeth."
:short-name "opt"
:abbreviated-name "Opt."
:chain-id 10
:layer 2}]
(map #(dissoc % :source :related-chain-id) (rf/sub [sub-name]))))))
@@ -77,8 +77,8 @@
:chain-id 42161
:layer 2}
:optimism {:network-name :optimism
:short-name "oeth"
:abbreviated-name "Oeth."
:short-name "opt"
:abbreviated-name "Opt."
:chain-id 10
:layer 2}}
(rf/sub [sub-name])))))
-5
View File
@@ -24,11 +24,6 @@
:<- [:wallet/wallet-send]
:-> :transaction-ids)
(rf/reg-sub
:wallet/wallet-send-amount
:<- [:wallet/wallet-send]
:-> :amount)
(rf/reg-sub
:wallet/send-transaction-progress
:<- [:wallet/send-transaction-ids]
+3 -21
View File
@@ -290,13 +290,11 @@
:wallet/current-viewing-account-tokens-filtered
:<- [:wallet/current-viewing-account]
:<- [:wallet/network-details]
(fn [[account networks] [_ query chain-ids]]
(fn [[account networks] [_ query]]
(let [tokens (map (fn [token]
(assoc token
:networks (network-utils/network-list token networks)
:available-balance (utils/calculate-total-token-balance token)
:total-balance (utils/calculate-total-token-balance token
chain-ids)))
:networks (network-utils/network-list token networks)
:total-balance (utils/calculate-total-token-balance token)))
(:tokens account))
sorted-tokens (sort-by :name compare tokens)]
(if query
@@ -454,19 +452,3 @@
:wallet/public-address
:<- [:wallet/create-account]
:-> :public-address)
(rf/reg-sub
:wallet/wallet-send-enabled-networks
:<- [:wallet/wallet-send-token]
:<- [:wallet/wallet-send-disabled-from-chain-ids]
(fn [[{:keys [networks]} disabled-from-chain-ids]]
(->> networks
(filter #(not (contains? (set disabled-from-chain-ids)
(:chain-id %))))
set)))
(rf/reg-sub
:wallet/wallet-send-enabled-from-chain-ids
:<- [:wallet/wallet-send-enabled-networks]
(fn [send-enabled-networks]
(map :chain-id send-enabled-networks)))
+5 -5
View File
@@ -163,7 +163,7 @@
:related-chain-id 42161
:layer 2}
{:test? true
:short-name "oeth"
:short-name "opt"
:related-chain-id 10
:layer 2}]
:prod [{:test? false
@@ -175,7 +175,7 @@
:chain-id 42161
:layer 2}
{:test? false
:short-name "oeth"
:short-name "opt"
:chain-id 10
:layer 2}]})
@@ -477,9 +477,9 @@
:chain-id 42161
:related-chain-id nil
:layer 2}
{:short-name "oeth"
{:short-name "opt"
:network-name :optimism
:abbreviated-name "Oeth."
:abbreviated-name "Opt."
:chain-id 10
:related-chain-id nil
:layer 2}]
@@ -625,7 +625,7 @@
address
emoji]} wallet-account
network-options [{:network-name :ethereum :short-name "eth"}
{:network-name :optimism :short-name "oeth"}
{:network-name :optimism :short-name "opt"}
{:network-name :arbitrum :short-name "arb1"}]
size-option 20]
(is
+1 -12
View File
@@ -1,5 +1,4 @@
(ns utils.number
(:require [clojure.string :as string]))
(ns utils.number)
(defn naive-round
"Quickly and naively round number `n` up to `decimal-places`.
@@ -30,13 +29,3 @@
if `num` exceeds a given bound, then returns the bound exceeded."
[number lower-bound upper-bound]
(max lower-bound (min number upper-bound)))
(defn remove-trailing-zeroes
[num]
(let [parts (string/split (str num) #"\.")]
(str (first parts)
(if-let [decimals (second parts)]
(if (seq (string/replace decimals #"0+$" ""))
(str "." (string/replace decimals #"0+$" ""))
"")
""))))
Binary file not shown.
+3 -3
View File
@@ -3,7 +3,7 @@
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
"owner": "status-im",
"repo": "status-go",
"version": "v0.179.19",
"commit-sha1": "3103c298015483cb4d1ee90c8f432fcefe21927d",
"src-sha256": "0ks0ks1fxfn1vdnl5j1pygvyv8gbiixihxrc1ac39yi5q61hwccb"
"version": "v0.179.17",
"commit-sha1": "0dbbf7c641691b3b5b6f4eb241d133aa7d42bf82",
"src-sha256": "0fp6zwb35pwmgb88xyqilw5dj8007cq9m186s915glnf94a45b7x"
}
+2 -2
View File
@@ -2447,7 +2447,7 @@
"opensea": "OpenSea",
"mainnet": "Mainnet",
"view-on-eth": "View on Etherscan",
"view-on-oeth": "View on Optimism Explorer",
"view-on-opt": "View on Optimism Explorer",
"view-on-arb": "View on Arbiscan",
"copy-address": "Copy address",
"show-address-qr": "Show address QR",
@@ -2557,7 +2557,7 @@
"watched-account-removed": "Watched address has been removed",
"account-removed": "Account has been removed",
"share-address-title": "{{address}} address",
"confirm-backup": "Confirm backup",
"check-your-backup": "Check your backup",
"confirm-the-position": "Confirm the position of certain words in your recovery phrase",
"do-not-cheat": "Don't try to cheat",
"do-not-cheat-description": "These 12 words give access to all of your funds so it is important that you write them in the correct order, take it seriously.",