Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
627bb19313 | ||
|
|
6f3ef8c76b |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 8.7 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 25 KiB |
|
Before Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 23 KiB |
|
Before Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 61 KiB |
|
Before Width: | Height: | Size: 114 KiB |
|
Before Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
Before Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 30 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 30 KiB |
@@ -19,7 +19,3 @@
|
||||
:background-color colors/danger-50
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def empty-state
|
||||
{:width 375
|
||||
:height 116})
|
||||
|
||||
@@ -2,12 +2,11 @@
|
||||
(:require
|
||||
[quo.components.graph.utils :as utils]
|
||||
[quo.components.graph.wallet-graph.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.charts :as charts]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.linear-gradient :as linear-gradient]))
|
||||
|
||||
(defn- time-frame->max-data-points
|
||||
@@ -43,10 +42,11 @@
|
||||
gradient-colors [(colors/alpha line-color 0.1) (colors/alpha line-color 0)]
|
||||
fill-color (colors/theme-colors colors/white colors/neutral-95)]
|
||||
(if (= time-frame :empty)
|
||||
[fast-image/fast-image
|
||||
{:style style/empty-state
|
||||
:source (resources/get-themed-image :no-funds theme)
|
||||
:accessibility-label :illustration}]
|
||||
[rn/view
|
||||
{:accessibility-label :illustration
|
||||
:style style/illustration}
|
||||
[text/text {:style {:color colors/white}}
|
||||
"Illustration here"]]
|
||||
[rn/view
|
||||
[linear-gradient/linear-gradient
|
||||
{:colors gradient-colors
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
:blur? false
|
||||
:type :digit} 1])
|
||||
(h/is-truthy (h/query-by-label-text :text-label))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "Is not pressable when disabled is true"
|
||||
@@ -47,5 +47,5 @@
|
||||
:blur? false
|
||||
:type :digit} 1])
|
||||
(h/is-truthy (h/query-by-label-text :text-label))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key))
|
||||
(h/was-not-called on-press))))
|
||||
|
||||
@@ -7,11 +7,6 @@
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- label->accessibility-label
|
||||
[label]
|
||||
(let [label-name (if (keyword? label) (name label) label)]
|
||||
(keyword (str "keyboard-key-" label-name))))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
@@ -19,11 +14,9 @@
|
||||
(let [label-color (style/get-label-color disabled? theme blur?)
|
||||
background-color (style/toggle-background-color @pressed? blur? theme)]
|
||||
[rn/pressable
|
||||
{:accessibility-label (label->accessibility-label label)
|
||||
{:accessibility-label :keyboard-key
|
||||
:disabled (or disabled? (not label))
|
||||
:on-press (fn []
|
||||
(when on-press
|
||||
(on-press label)))
|
||||
:on-press (fn [] (on-press label))
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? false)
|
||||
:style (style/container background-color)}
|
||||
|
||||
@@ -17,15 +17,13 @@
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press on-delete]
|
||||
:or {left-action :none}}]
|
||||
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press]}]
|
||||
[rn/view
|
||||
{:style style/container}
|
||||
(for [row-index (range 1 4)]
|
||||
^{:key row-index}
|
||||
[rn/view {:style style/row-container}
|
||||
(for [column-index (range 1 4)]
|
||||
^{:key (str row-index column-index)}
|
||||
[keyboard-item
|
||||
{:item (+ (* (dec row-index) 3) column-index)
|
||||
:type :digit
|
||||
@@ -60,10 +58,10 @@
|
||||
:theme theme}]
|
||||
(if delete-key?
|
||||
[keyboard-item
|
||||
{:item :i/travel
|
||||
{:item :i/delete
|
||||
:type :key
|
||||
:disabled? disabled?
|
||||
:on-press on-delete
|
||||
:on-press on-press
|
||||
:blur? blur?
|
||||
:theme theme}]
|
||||
[keyboard-item])]]))
|
||||
|
||||
@@ -14,10 +14,7 @@
|
||||
:padding-bottom 4
|
||||
:height 36
|
||||
:flex-direction :row
|
||||
:justify-content :space-between
|
||||
;;
|
||||
:background-color :pink
|
||||
})
|
||||
:justify-content :space-between})
|
||||
|
||||
(def token
|
||||
{:width 32
|
||||
@@ -25,12 +22,14 @@
|
||||
|
||||
(defn text-input
|
||||
[theme]
|
||||
(assoc typography/heading-1
|
||||
:font-weight "600"
|
||||
:color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:padding 0
|
||||
;; TODO: fix the padding
|
||||
:height "100%"))
|
||||
(merge typography/heading-1
|
||||
{:font-weight "600"
|
||||
:margin-left 8
|
||||
:margin-right (if platform/ios? 6 4)
|
||||
:color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:padding 0
|
||||
:text-align :center
|
||||
:height "100%"}))
|
||||
|
||||
(defn divider
|
||||
[width theme]
|
||||
|
||||
@@ -1,107 +1,73 @@
|
||||
(ns quo.components.wallet.token-input.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.wallet.token-input.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.common :as common]
|
||||
[oops.core :as oops]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]))
|
||||
[clojure.string :as string]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.wallet.token-input.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.common :as common]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn calc-value
|
||||
[crypto? currency token value conversion]
|
||||
(let [num-value (if (string? value) (parse-double (or value "0")) value)]
|
||||
(if crypto?
|
||||
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2))
|
||||
(str (.toFixed (/ num-value conversion) 2) " " (string/upper-case (or (clj->js token) ""))))))
|
||||
(if crypto?
|
||||
(str (get common/currency-label currency) (.toFixed (* value conversion) 2))
|
||||
(str (.toFixed (/ value conversion) 2) " " (string/upper-case (clj->js token)))))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [width (:width (rn/get-window))
|
||||
value (reagent/atom nil)
|
||||
value (reagent/atom 0)
|
||||
crypto? (reagent/atom true)
|
||||
input-ref (atom nil)]
|
||||
(fn [{:keys [theme token currency conversion networks title customization-color
|
||||
on-swap container-style show-keyboard?]
|
||||
:or {show-keyboard? true}
|
||||
external-value :value}]
|
||||
(let [number-of-chars (count (or external-value @value))
|
||||
text-unit-position (+ 23
|
||||
(* (if (<= number-of-chars 1)
|
||||
0
|
||||
(- number-of-chars 1))
|
||||
15.333))]
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/main-container width)
|
||||
container-style)}
|
||||
[rn/view {:style style/amount-container}
|
||||
[rn/pressable
|
||||
{:on-press #(when @input-ref (.focus ^js @input-ref))
|
||||
:style {:flex 1
|
||||
:background-color :orange
|
||||
}}
|
||||
[rn/image
|
||||
{:style style/token
|
||||
:source (resources/get-token token)}]
|
||||
|
||||
|
||||
[rn/view {:style {:background-color :lightblue
|
||||
;;
|
||||
:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 40
|
||||
:right 0
|
||||
}}
|
||||
[rn/text-input
|
||||
{:ref #(reset! input-ref %)
|
||||
:auto-focus true
|
||||
:placeholder "0"
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40
|
||||
colors/neutral-50
|
||||
theme)
|
||||
:default-value (or external-value @value)
|
||||
:keyboard-type :numeric
|
||||
:max-length 12
|
||||
:on-change-text #(reset! value %)
|
||||
:style (style/text-input theme)
|
||||
:selection-color customization-color
|
||||
:show-soft-input-on-focus show-keyboard?}]
|
||||
;;
|
||||
[rn/view {:style {:position :absolute
|
||||
:bottom 1
|
||||
:left text-unit-position}}
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
(string/upper-case (or (clj->js (if @crypto? token currency)) ""))]]]]
|
||||
[button/button
|
||||
{:icon true
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press (fn []
|
||||
(swap! crypto? not)
|
||||
(when on-swap
|
||||
(on-swap @crypto?)))
|
||||
:type :outline
|
||||
:accessibility-label :reorder}
|
||||
:i/reorder]]
|
||||
[divider-line/view {:container-style {:margin-vertical 8}}]
|
||||
[rn/view {:style style/data-container}
|
||||
[network-tag/view {:networks networks :title title}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
(calc-value @crypto? currency token (or external-value @value) conversion)]]]))))
|
||||
(fn [{:keys [theme token currency conversion networks title customization-color]}]
|
||||
[rn/view {:style (style/main-container width)}
|
||||
[rn/view {:style style/amount-container}
|
||||
[rn/pressable
|
||||
{:on-press #(when @input-ref (.focus ^js @input-ref))
|
||||
:style {:flex-direction :row
|
||||
:flex-grow 1
|
||||
:align-items :flex-end}}
|
||||
[rn/image
|
||||
{:style style/token
|
||||
:source (resources/get-token token)}]
|
||||
[rn/text-input
|
||||
{:ref #(reset! input-ref %)
|
||||
:placeholder "0"
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)
|
||||
:keyboard-type :numeric
|
||||
:max-length 12
|
||||
:default-value @value
|
||||
:on-change-text #(reset! value %)
|
||||
:style (style/text-input theme)
|
||||
:selection-color customization-color}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:margin-right 8
|
||||
:padding-bottom 2}}
|
||||
(string/upper-case (clj->js (if @crypto? token currency)))]]
|
||||
[button/button
|
||||
{:icon true
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press #(swap! crypto? not)
|
||||
:type :outline
|
||||
:accessibility-label :reorder}
|
||||
:i/reorder]]
|
||||
[divider-line/view {:container-style {:margin-vertical 8}}]
|
||||
[rn/view {:style style/data-container}
|
||||
[network-tag/view {:networks networks :title title}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
(calc-value @crypto? currency token @value conversion)]]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -7,15 +7,6 @@
|
||||
:keycard-watermark (js/require "../resources/images/ui2/keycard-watermark.png")
|
||||
:bored-ape (js/require "../resources/images/mock2/bored-ape.png")})
|
||||
|
||||
(def ui-themed
|
||||
{:no-funds
|
||||
{:light (js/require "../resources/images/ui2/no-funds-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-funds-dark.png")}})
|
||||
|
||||
(defn get-themed-image
|
||||
[k theme]
|
||||
(get-in ui-themed [k theme]))
|
||||
|
||||
(defn get-image
|
||||
[k]
|
||||
(get ui k))
|
||||
|
||||
@@ -78,13 +78,16 @@
|
||||
(fn [can-save?]
|
||||
(if can-save?
|
||||
(keychain/get-credentials
|
||||
(str key-uid "-auth")
|
||||
(str key-uid "-hashed" "-auth")
|
||||
#(callback (if % (oops/oget % "password") auth-method-none)))
|
||||
(callback nil))))))
|
||||
|
||||
(defn save-user-password!
|
||||
[key-uid password]
|
||||
(keychain/save-credentials key-uid key-uid (security/safe-unmask-data password) #()))
|
||||
(keychain/save-credentials key-uid
|
||||
key-uid
|
||||
(security/safe-unmask-data password)
|
||||
#()))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keychain/get-user-password
|
||||
|
||||
@@ -79,19 +79,7 @@
|
||||
:dark (js/require "../resources/images/ui2/no-contacts-to-invite-dark.png")}
|
||||
:no-notifications
|
||||
{:light (js/require "../resources/images/ui2/no-notifications-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-notifications-dark.png")}
|
||||
:no-activity
|
||||
{:light (js/require "../resources/images/ui2/no-activity-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-activity-dark.png")}
|
||||
:no-collectibles
|
||||
{:light (js/require "../resources/images/ui2/no-collectibles-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-collectibles-dark.png")}
|
||||
:no-dapps
|
||||
{:light (js/require "../resources/images/ui2/no-dapps-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-dapps-dark.png")}
|
||||
:no-permissions
|
||||
{:light (js/require "../resources/images/ui2/no-permissions-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-permissions-dark.png")}})
|
||||
:dark (js/require "../resources/images/ui2/no-notifications-dark.png")}})
|
||||
|
||||
(def mock-images
|
||||
{:bored-ape (js/require "../resources/images/mock2/bored-ape.png")
|
||||
|
||||
@@ -33,24 +33,14 @@
|
||||
(rf/sub [:profile/customization-color]))
|
||||
syncing-results? (= :syncing-results @state/root-id)]
|
||||
[rn/view {:style (style/buttons insets)}
|
||||
[standard-auth/button
|
||||
[quo/button
|
||||
(merge
|
||||
{:size 40
|
||||
:accessibility-label :enable-biometrics-button
|
||||
:icon-left :i/face-id
|
||||
:customization-color profile-color
|
||||
:button-label (i18n/label :t/biometric-enable-button {:bio-type-label bio-type-label})}
|
||||
(if syncing-results?
|
||||
{:theme theme
|
||||
:blur? true
|
||||
:on-enter-password (fn [entered-password]
|
||||
(rf/dispatch
|
||||
[:onboarding-2/authenticate-enable-biometrics
|
||||
(security/safe-unmask-data
|
||||
entered-password)])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
:auth-button-label (i18n/label :t/confirm)}
|
||||
{:on-press #(rf/dispatch [:onboarding-2/enable-biometrics])}))]
|
||||
{:on-press #(rf/dispatch [:onboarding-2/sync-enable-biometrics])})]
|
||||
[quo/button
|
||||
{:accessibility-label :maybe-later-button
|
||||
:background :blur
|
||||
|
||||
@@ -35,11 +35,10 @@
|
||||
{:biometric/authenticate {:on-success #(rf/dispatch [:onboarding-2/biometrics-done])
|
||||
:on-fail #(rf/dispatch [:onboarding-2/biometrics-fail %])}})
|
||||
|
||||
(rf/defn authenticate-enable-biometrics
|
||||
{:events [:onboarding-2/authenticate-enable-biometrics]}
|
||||
(rf/defn sync-enable-biometrics
|
||||
{:events [:onboarding-2/sync-enable-biometrics]}
|
||||
[{:keys [db]} password]
|
||||
{:db (-> db
|
||||
(assoc-in [:onboarding-2/profile :password] password)
|
||||
(assoc-in [:onboarding-2/profile :syncing?] true))
|
||||
:biometric/authenticate {:on-success #(rf/dispatch [:onboarding-2/biometrics-done])
|
||||
:on-fail #(rf/dispatch [:onboarding-2/biometrics-fail %])}})
|
||||
@@ -145,15 +144,15 @@
|
||||
(rf/defn onboarding-new-account-finalize-setup
|
||||
{:events [:onboarding-2/finalize-setup]}
|
||||
[{:keys [db]}]
|
||||
(let [masked-password (get-in db [:onboarding-2/profile :password])
|
||||
(let [syncing? (get-in db [:onboarding-2/profile :syncing?])
|
||||
masked-password (get-in db [:onboarding-2/profile :password])
|
||||
key-uid (get-in db [:profile/profile :key-uid])
|
||||
syncing? (get-in db [:onboarding-2/profile :syncing?])
|
||||
biometric-enabled? (= (get-in db [:onboarding-2/profile :auth-method])
|
||||
constants/auth-method-biometric)]
|
||||
(cond-> {:db (assoc db :onboarding-2/generated-keys? true)}
|
||||
biometric-enabled?
|
||||
(assoc :keychain/save-password-and-auth-method
|
||||
{:key-uid key-uid
|
||||
{:key-uid (if syncing? (str key-uid "-hashed") key-uid)
|
||||
:masked-password masked-password
|
||||
:on-success (fn []
|
||||
(if syncing?
|
||||
|
||||
@@ -42,11 +42,19 @@
|
||||
{:db (assoc-in db [:profile/login :processing] true)
|
||||
::login [key-uid (native-module/sha3 (security/safe-unmask-data password))]}))
|
||||
|
||||
(rf/defn biometry-login
|
||||
{:events [:profile.login/biometry-login]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (:profile/login db)]
|
||||
{:db (assoc-in db [:profile/login :processing] true)
|
||||
::login [key-uid (security/safe-unmask-data password)]}))
|
||||
|
||||
(rf/defn login-local-paired-user
|
||||
{:events [:profile.login/local-paired-user]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password]} (get-in db [:syncing :profile])]
|
||||
{::login [key-uid password]}))
|
||||
{:db (assoc-in db [:onboarding-2/profile :password] (security/mask-data password))
|
||||
::login [key-uid password]}))
|
||||
|
||||
(rf/defn redirect-to-root
|
||||
[{:keys [db] :as cofx}]
|
||||
@@ -158,14 +166,25 @@
|
||||
{:on-success #(rf/dispatch [:profile.login/biometric-success])
|
||||
:on-faile #(rf/dispatch [:profile.login/biometric-auth-fail])}})))
|
||||
|
||||
(rf/defn biometric-auth-success
|
||||
{:events [:profile.login/biometric-success]}
|
||||
;; TODO store the password in the hash keychain
|
||||
(rf/defn backwards-compatible-biometric-auth-success
|
||||
{:events [:profile.login/backwards-compatible-biometric-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [key-uid (get-in db [:profile/login :key-uid])]
|
||||
(keychain/get-user-password cofx
|
||||
key-uid
|
||||
#(rf/dispatch [:profile.login/get-user-password-success %]))))
|
||||
|
||||
(rf/defn biometric-auth-success
|
||||
{:events [:profile.login/biometric-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(let [key-uid (get-in db [:profile/login :key-uid])]
|
||||
(keychain/get-user-password cofx
|
||||
(str key-uid "-hashed")
|
||||
#(if (nil? %)
|
||||
(rf/dispatch [:profile.login/backwards-compatible-biometric-success])
|
||||
(rf/dispatch [:profile.login/get-user-password-success %])))))
|
||||
|
||||
;; result of :keychain/get-auth-method above
|
||||
(rf/defn get-user-password-success
|
||||
{:events [:profile.login/get-user-password-success]}
|
||||
@@ -175,7 +194,7 @@
|
||||
cofx
|
||||
{:db (assoc-in db [:profile/login :password] password)}
|
||||
(navigation/init-root :progress)
|
||||
(login))))
|
||||
(biometry-login))))
|
||||
|
||||
(rf/defn biometric-auth-fail
|
||||
{:events [:profile.login/biometric-auth-fail]}
|
||||
|
||||
@@ -3,10 +3,11 @@
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.wallet.account.tabs.dapps.style :as style]
|
||||
[status-im2.contexts.wallet.common.empty-tab.view :as empty-tab]
|
||||
[utils.i18n :as i18n]))
|
||||
[status-im2.contexts.wallet.common.temp :as temp]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn dapp-options
|
||||
[]
|
||||
@@ -22,12 +23,13 @@
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [theme]}]
|
||||
(let [dapps-list []]
|
||||
(let [dapps-list (temp/dapps-list {:on-press-icon #(rf/dispatch [:show-bottom-sheet
|
||||
{:content dapp-options}])})]
|
||||
(if (empty? dapps-list)
|
||||
[empty-tab/view
|
||||
{:title (i18n/label :t/no-dapps)
|
||||
:description (i18n/label :t/no-dapps-description)
|
||||
:image (resources/get-themed-image :no-dapps theme)}]
|
||||
{:title (i18n/label :t/no-dapps)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:placeholder? true}]
|
||||
[rn/view {:style style/dapps-container}
|
||||
[rn/flat-list
|
||||
{:data dapps-list
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
(ns status-im2.contexts.wallet.account.tabs.view
|
||||
(:require
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.wallet.account.tabs.about.view :as about]
|
||||
[status-im2.contexts.wallet.account.tabs.dapps.view :as dapps]
|
||||
[status-im2.contexts.wallet.common.activity-tab.view :as activity]
|
||||
@@ -12,8 +10,8 @@
|
||||
[status-im2.contexts.wallet.common.token-value.view :as token-value]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [selected-tab theme]}]
|
||||
(defn view
|
||||
[{:keys [selected-tab]}]
|
||||
(case selected-tab
|
||||
:assets [rn/flat-list
|
||||
{:render-fn token-value/view
|
||||
@@ -22,13 +20,8 @@
|
||||
:collectibles [collectibles/view]
|
||||
:activity [activity/view]
|
||||
:permissions [empty-tab/view
|
||||
{:title (i18n/label :t/no-permissions)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:image (resources/get-image
|
||||
(quo.theme/theme-value :no-permissions-light
|
||||
:no-permissions-dark
|
||||
theme))}]
|
||||
{:title (i18n/label :t/no-permissions)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:placeholder? true}]
|
||||
:dapps [dapps/view]
|
||||
[about/view]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
[{:id :assets :label (i18n/label :t/assets) :accessibility-label :assets-tab}
|
||||
{:id :collectibles :label (i18n/label :t/collectibles) :accessibility-label :collectibles-tab}
|
||||
{:id :activity :label (i18n/label :t/activity) :accessibility-label :activity-tab}
|
||||
{:id :permissions :label (i18n/label :t/permissions) :accessibility-label :permissions}
|
||||
{:id :dapps :label (i18n/label :t/dapps) :accessibility-label :dapps}
|
||||
{:id :about :label (i18n/label :t/about) :accessibility-label :about}])
|
||||
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
(ns status-im2.contexts.wallet.common.activity-tab.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.wallet.common.empty-tab.view :as empty-tab]
|
||||
[status-im2.contexts.wallet.common.temp :as temp]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn activity-item
|
||||
@@ -15,17 +14,15 @@
|
||||
(merge {:on-press #(js/alert "Item pressed")}
|
||||
item)]])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [theme]}]
|
||||
(let [activity-list []]
|
||||
(defn view
|
||||
[]
|
||||
(let [activity-list temp/activity-list]
|
||||
(if (empty? activity-list)
|
||||
[empty-tab/view
|
||||
{:title (i18n/label :t/no-activity)
|
||||
:description (i18n/label :t/empty-tab-description)
|
||||
:image (resources/get-themed-image :no-activity theme)}]
|
||||
{:title (i18n/label :t/no-activity)
|
||||
:description (i18n/label :t/empty-tab-description)
|
||||
:placeholder? true}]
|
||||
[rn/flat-list
|
||||
{:data activity-list
|
||||
:style {:flex 1}
|
||||
:render-fn activity-item}])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -1,21 +1,19 @@
|
||||
(ns status-im2.contexts.wallet.common.collectibles-tab.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.wallet.common.empty-tab.view :as empty-tab]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [theme]}]
|
||||
(defn view
|
||||
[]
|
||||
(let [collectible-list (rf/sub [:wallet/collectibles])]
|
||||
(if (empty? collectible-list)
|
||||
[empty-tab/view
|
||||
{:title (i18n/label :t/no-collectibles)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:image (resources/get-themed-image :no-collectibles theme)}]
|
||||
{:title (i18n/label :t/no-collectibles)
|
||||
:description (i18n/label :t/no-collectibles-description)
|
||||
:placeholder? true}]
|
||||
[rn/flat-list
|
||||
{:data collectible-list
|
||||
:style {:flex 1}
|
||||
@@ -27,5 +25,3 @@
|
||||
:on-press #(rf/dispatch
|
||||
[:navigate-to
|
||||
:wallet-collectible])}])}])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -22,9 +22,7 @@
|
||||
[quo/button {:on-press #(rf/dispatch [:navigate-to :wallet-create-account])}
|
||||
"Create Account"]
|
||||
[quo/button {:on-press #(rf/dispatch [:navigate-to :wallet-saved-addresses])}
|
||||
"Saved Addresses"]
|
||||
[quo/button {:on-press #(rf/dispatch [:navigate-to :wallet-send-input-amount])}
|
||||
"Send: input amount"]])
|
||||
"Saved Addresses"]])
|
||||
|
||||
(defn wallet-overview-state
|
||||
[networks]
|
||||
|
||||
@@ -30,9 +30,7 @@
|
||||
(defn- new-account-card-data
|
||||
[]
|
||||
{:customization-color (rf/sub [:profile/customization-color])
|
||||
:on-press #(rf/dispatch [:navigate-to :wallet-send-input-amount
|
||||
] ;[:show-bottom-sheet {:content new-account}]
|
||||
)
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet {:content new-account}])
|
||||
:type :add-account})
|
||||
|
||||
(def tabs-data
|
||||
@@ -55,7 +53,10 @@
|
||||
[common.top-nav/view]
|
||||
[rn/view {:style style/overview-container}
|
||||
[quo/wallet-overview (temp/wallet-overview-state networks)]]
|
||||
[quo/wallet-graph {:time-frame :empty}]
|
||||
[rn/pressable
|
||||
{:on-long-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content temp/wallet-temporary-navigation}])}
|
||||
[quo/wallet-graph {:time-frame :empty}]]
|
||||
[rn/flat-list
|
||||
{:style style/accounts-list
|
||||
:content-container-style style/accounts-list-container
|
||||
|
||||
@@ -1,80 +0,0 @@
|
||||
(ns status-im2.contexts.wallet.send.input-amount.component-spec
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im2.contexts.wallet.send.input-amount.view :as input-amount]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn setup-subs
|
||||
[subscriptions]
|
||||
(doseq [keyval subscriptions]
|
||||
(re-frame/reg-sub
|
||||
(key keyval)
|
||||
(fn [_] (val keyval)))))
|
||||
|
||||
(def sub-mocks
|
||||
{:profile/profile {:currency :usd}
|
||||
:wallet/network-details [{:source 525
|
||||
:short-name "eth"
|
||||
:network-name :ethereum
|
||||
:chain-id 1
|
||||
:related-chain-id 5}]})
|
||||
|
||||
(h/describe "Send > input amount screen"
|
||||
(h/test "Default render"
|
||||
(setup-subs sub-mocks)
|
||||
(h/render [input-amount/view {}])
|
||||
(h/is-truthy (h/get-by-text "0"))
|
||||
(h/is-truthy (h/get-by-text "ETH"))
|
||||
(h/is-truthy (h/get-by-text "$0.00"))
|
||||
(h/is-disabled (h/get-by-label-text :button-one)))
|
||||
|
||||
(h/test "Fill token input and confirm"
|
||||
(setup-subs sub-mocks)
|
||||
(let [on-confirm (h/mock-fn)]
|
||||
(h/render [input-amount/view {:on-confirm on-confirm}])
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-3))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-.))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-4))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||
|
||||
(h/wait-for #(h/is-truthy (h/get-by-text "$1234.50")))
|
||||
|
||||
(h/is-truthy (h/get-by-label-text :button-one))
|
||||
|
||||
(h/fire-event :press (h/get-by-label-text :button-one))
|
||||
(h/was-called on-confirm)))
|
||||
|
||||
(h/test "Try to fill more than limit"
|
||||
(setup-subs sub-mocks)
|
||||
(h/render [input-amount/view {}])
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-9))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||
|
||||
(h/wait-for #(h/is-truthy (h/get-by-text "$290.00")))
|
||||
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-backspace))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-8))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||
(h/wait-for #(h/is-truthy (h/get-by-text "$2850.00"))))
|
||||
|
||||
(h/test "Switch from crypto to fiat and check limit"
|
||||
(setup-subs sub-mocks)
|
||||
(h/render [input-amount/view {}])
|
||||
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-2))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-0))
|
||||
(h/wait-for #(h/is-truthy (h/get-by-text "$200.00")))
|
||||
|
||||
(h/fire-event :press (h/query-by-label-text :reorder))
|
||||
|
||||
(h/wait-for #(h/is-truthy (h/get-by-text "2.00 ETH")))
|
||||
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||
|
||||
(h/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH")))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-5))
|
||||
(h/wait-for #(h/is-truthy (h/get-by-text "205.50 ETH")))))
|
||||
@@ -1,8 +0,0 @@
|
||||
(ns status-im2.contexts.wallet.send.input-amount.style)
|
||||
|
||||
(def screen
|
||||
{:flex 1})
|
||||
|
||||
(def input-container
|
||||
{:padding-top 12
|
||||
:padding-bottom 0})
|
||||
@@ -1,93 +0,0 @@
|
||||
(ns status-im2.contexts.wallet.send.input-amount.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.wallet.send.input-amount.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- make-limit-label
|
||||
[{:keys [amount currency]}]
|
||||
(str amount " " (string/upper-case (name currency))))
|
||||
|
||||
(defn- make-new-input
|
||||
[current v]
|
||||
(let [dot "."
|
||||
max-length 12
|
||||
length-owerflow? (>= (count current) max-length)
|
||||
ignore-extra-dot? (and (= v dot) (string/includes? current dot))
|
||||
ignore-value? (or
|
||||
ignore-extra-dot?
|
||||
length-owerflow?)]
|
||||
(if ignore-value?
|
||||
current
|
||||
(str current v))))
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(let [token :eth
|
||||
{:keys [currency]} (rf/sub [:profile/profile])
|
||||
networks (rf/sub [:wallet/network-details])
|
||||
conversion-rate 10
|
||||
limit-crypto 100000000
|
||||
limit-fiat (* limit-crypto conversion-rate)
|
||||
input-value (reagent/atom "")
|
||||
current-limit (reagent/atom {:amount limit-crypto
|
||||
:currency token})
|
||||
handle-swap (fn [crypto?]
|
||||
(let [num-value (parse-double @input-value)]
|
||||
(reset! current-limit (if crypto?
|
||||
{:amount limit-crypto
|
||||
:currency token}
|
||||
{:amount limit-fiat
|
||||
:currency currency}))
|
||||
(when (> num-value (:amount @current-limit))
|
||||
(reset! input-value ""))))
|
||||
handle-keyboard-press (fn [v]
|
||||
(let [current-value @input-value
|
||||
new-value (make-new-input current-value v)
|
||||
num-value (parse-double new-value)]
|
||||
(when (<= num-value (:amount @current-limit))
|
||||
(reset! input-value new-value))))
|
||||
handle-delete (fn [_]
|
||||
(swap! input-value #(subs % 0 (dec (count %)))))]
|
||||
(fn [{:keys [on-confirm]
|
||||
:or {on-confirm #(js/alert "Confirmed")}}]
|
||||
(let [limit-label (make-limit-label @current-limit)]
|
||||
[rn/view
|
||||
{:style style/screen}
|
||||
[quo/page-nav
|
||||
{:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side :account-switcher
|
||||
:account-switcher {:customization-color :yellow
|
||||
:emoji "🎮"
|
||||
:on-press #(js/alert "Switch account")}}]
|
||||
[quo/token-input
|
||||
{:container-style style/input-container
|
||||
:token token
|
||||
:currency currency
|
||||
:networks networks
|
||||
:title (i18n/label :t/send-limit {:limit limit-label})
|
||||
:conversion conversion-rate
|
||||
:show-keyboard? false
|
||||
:value @input-value
|
||||
:on-swap handle-swap}]
|
||||
;; Network routing content to be added
|
||||
[rn/scroll-view]
|
||||
[quo/bottom-actions
|
||||
{:actions :1-action
|
||||
:button-one-label (i18n/label :t/confirm)
|
||||
:button-one-props {:disabled? (empty? @input-value)
|
||||
:on-press on-confirm}}]
|
||||
[quo/numbered-keyboard
|
||||
{:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press handle-keyboard-press
|
||||
:on-delete handle-delete}]]))))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -4,5 +4,4 @@
|
||||
[status-im2.contexts.chat.messages.content.audio.component-spec]
|
||||
[status-im2.contexts.communities.actions.community-options.component-spec]
|
||||
[status-im2.contexts.wallet.add-address-to-watch.component-spec]
|
||||
[status-im2.contexts.wallet.create-account.edit-derivation-path.component-spec]
|
||||
[status-im2.contexts.wallet.send.input-amount.component-spec]))
|
||||
[status-im2.contexts.wallet.create-account.edit-derivation-path.component-spec]))
|
||||
|
||||
@@ -49,7 +49,6 @@
|
||||
[status-im2.contexts.wallet.edit-account.view :as wallet-edit-account]
|
||||
[status-im2.contexts.wallet.saved-addresses.view :as wallet-saved-addresses]
|
||||
[status-im2.contexts.wallet.scan-account.view :as scan-address]
|
||||
[status-im2.contexts.wallet.send.input-amount.view :as wallet-send-input-amount]
|
||||
[status-im2.contexts.wallet.send.select-address.view :as wallet-select-address]
|
||||
[status-im2.navigation.options :as options]
|
||||
[status-im2.navigation.transitions :as transitions]))
|
||||
@@ -288,11 +287,6 @@
|
||||
{:name :wallet-saved-addresses
|
||||
:component wallet-saved-addresses/view}
|
||||
|
||||
{:name :wallet-send-input-amount
|
||||
:options {:modalPresentationStyle :overCurrentContext
|
||||
:insets {:top? true}}
|
||||
:component wallet-send-input-amount/view}
|
||||
|
||||
{:name :wallet-select-address
|
||||
:options {:modalPresentationStyle :overCurrentContext}
|
||||
:component wallet-select-address/view}
|
||||
|
||||
@@ -2389,8 +2389,5 @@
|
||||
"address-placeholder": "0x123abc... or bob.eth",
|
||||
"invalid-address": "It’s not Ethereum address or ENS name",
|
||||
"address-already-in-use": "Address already being used",
|
||||
"address-copied": "Address copied",
|
||||
"no-dapps-description": "We want dApps!",
|
||||
"send-limit": "Max: {{limit}}"
|
||||
"address-copied": "Address copied"
|
||||
}
|
||||
|
||||
|
||||