chore: merge branch 'develop' into status-go/filter-improvements
This commit is contained in:
commit
59896858d0
|
@ -10,7 +10,7 @@
|
||||||
(reagent/as-element
|
(reagent/as-element
|
||||||
(into [react/keyboard-avoiding-view
|
(into [react/keyboard-avoiding-view
|
||||||
(update props
|
(update props
|
||||||
:keyboardVerticalOffset
|
:keyboard-vertical-offset
|
||||||
+
|
+
|
||||||
20
|
20
|
||||||
(if (:ignore-offset props) 44 0))]
|
(if (:ignore-offset props) 44 0))]
|
||||||
|
|
|
@ -275,7 +275,7 @@
|
||||||
(merge (when platform/ios? {:behavior :padding})
|
(merge (when platform/ios? {:behavior :padding})
|
||||||
(if (:ignore-offset props)
|
(if (:ignore-offset props)
|
||||||
props
|
props
|
||||||
(update props :keyboardVerticalOffset + 44 (:status-bar-height @navigation-const))))]
|
(update props :keyboard-vertical-offset + 44 (:status-bar-height @navigation-const))))]
|
||||||
children))
|
children))
|
||||||
|
|
||||||
(defn keyboard-avoiding-view-new
|
(defn keyboard-avoiding-view-new
|
||||||
|
@ -284,7 +284,7 @@
|
||||||
(merge (when platform/ios? {:behavior :padding})
|
(merge (when platform/ios? {:behavior :padding})
|
||||||
(if (:ignore-offset props)
|
(if (:ignore-offset props)
|
||||||
props
|
props
|
||||||
(update props :keyboardVerticalOffset + 44)))]
|
(update props :keyboard-vertical-offset + 44)))]
|
||||||
children))
|
children))
|
||||||
|
|
||||||
(defn scroll-view
|
(defn scroll-view
|
||||||
|
|
|
@ -30,10 +30,7 @@
|
||||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))
|
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))
|
||||||
:container-style style/title-icon-container
|
:container-style style/title-icon-container
|
||||||
:accessibility-label :title-icon}])]
|
:accessibility-label :title-icon}])]
|
||||||
[address-text/view
|
[address-text/view (assoc account-props :format :short)]]])
|
||||||
{:networks (:networks account-props)
|
|
||||||
:address (:address account-props)
|
|
||||||
:format :short}]]])
|
|
||||||
|
|
||||||
(defn- balance-view
|
(defn- balance-view
|
||||||
[{:keys [balance-props type theme]}]
|
[{:keys [balance-props type theme]}]
|
||||||
|
|
|
@ -25,12 +25,12 @@
|
||||||
:blur :grey})
|
:blur :grey})
|
||||||
|
|
||||||
(defn- page-nav-base
|
(defn- page-nav-base
|
||||||
[{:keys [margin-top background on-press accessibility-label icon-name behind-overlay?]
|
[{:keys [margin-top background on-press accessibility-label icon-name behind-overlay? align-center?]
|
||||||
:or {background :white}}
|
:or {background :white}}
|
||||||
& children]
|
& children]
|
||||||
(into [rn/view {:style (style/container margin-top)}
|
(into [rn/view {:style (style/container margin-top)}
|
||||||
(when icon-name
|
(when icon-name
|
||||||
[rn/view {:style style/icon-container}
|
[rn/view (when align-center? {:style style/icon-container})
|
||||||
[button/button
|
[button/button
|
||||||
{:type (button-type background)
|
{:type (button-type background)
|
||||||
:icon-only? true
|
:icon-only? true
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
(ns quo.components.tabs.tabs.schema)
|
||||||
|
|
||||||
|
(def ^:private ?data
|
||||||
|
[:sequential
|
||||||
|
[:maybe
|
||||||
|
[:map
|
||||||
|
[:id [:or :int :keyword [:set :int]]]
|
||||||
|
[:label [:maybe :string]]
|
||||||
|
[:accessibility-label {:optional true} [:maybe [:or :keyword :string]]]
|
||||||
|
[:notification-dot? {:optional true} [:maybe :boolean]]]]])
|
||||||
|
|
||||||
|
(def ?schema
|
||||||
|
[:=>
|
||||||
|
[:catn
|
||||||
|
[:props
|
||||||
|
[:map
|
||||||
|
[:default-active {:optional true} [:maybe [:or :int :keyword]]]
|
||||||
|
[:active-tab-id {:optional true} [:maybe [:or :int :keyword]]]
|
||||||
|
[:data ?data]
|
||||||
|
[:fade-end-percentage {:optional true} [:or :double :string]]
|
||||||
|
[:fade-end? {:optional true} [:maybe :boolean]]
|
||||||
|
[:blur? {:optional true} [:maybe :boolean]]
|
||||||
|
[:on-change {:optional true} [:maybe fn?]]
|
||||||
|
[:on-scroll {:optional true} [:maybe fn?]]
|
||||||
|
[:scroll-on-press? {:optional true} [:maybe :boolean]]
|
||||||
|
[:scrollable? {:optional true} [:maybe :boolean]]
|
||||||
|
[:style {:optional true} [:maybe :map]]
|
||||||
|
[:container-style {:optional true} [:maybe :map]]
|
||||||
|
[:size {:optional true} [:maybe [:or :keyword :int]]]
|
||||||
|
[:in-scroll-view? {:optional true} [:maybe :boolean]]
|
||||||
|
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]]
|
||||||
|
:any])
|
|
@ -2,12 +2,14 @@
|
||||||
(:require
|
(:require
|
||||||
[oops.core :refer [oget]]
|
[oops.core :refer [oget]]
|
||||||
[quo.components.tabs.tab.view :as tab]
|
[quo.components.tabs.tab.view :as tab]
|
||||||
|
[quo.components.tabs.tabs.schema :as component-schema]
|
||||||
[quo.components.tabs.tabs.style :as style]
|
[quo.components.tabs.tabs.style :as style]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.gesture :as gesture]
|
[react-native.gesture :as gesture]
|
||||||
[react-native.linear-gradient :as linear-gradient]
|
[react-native.linear-gradient :as linear-gradient]
|
||||||
[react-native.masked-view :as masked-view]
|
[react-native.masked-view :as masked-view]
|
||||||
[reagent.core :as reagent]
|
[reagent.core :as reagent]
|
||||||
|
[schema.core :as schema]
|
||||||
[utils.collection :as utils.collection]
|
[utils.collection :as utils.collection]
|
||||||
[utils.number]))
|
[utils.number]))
|
||||||
|
|
||||||
|
@ -84,36 +86,20 @@
|
||||||
:on-press #(on-press % index)}
|
:on-press #(on-press % index)}
|
||||||
label]])
|
label]])
|
||||||
|
|
||||||
(defn view
|
(defn- view-internal
|
||||||
" Common options (for scrollable and non-scrollable tabs):
|
|
||||||
|
|
||||||
- `blur?` Boolean passed down to `quo.components.tabs.tab/tab`.
|
|
||||||
- `data` Vector of tab items.
|
|
||||||
- `on-change` Callback called after a tab is selected.
|
|
||||||
- `size` 32/24
|
|
||||||
- `style` Style map passed to View wrapping tabs or to the FlatList when tabs
|
|
||||||
are scrollable.
|
|
||||||
|
|
||||||
Options for scrollable tabs:
|
|
||||||
- `fade-end-percentage` Percentage where fading starts relative to the total
|
|
||||||
layout width of the `flat-list` data.
|
|
||||||
- `fade-end?` When non-nil, causes the end of the scrollable view to fade out.
|
|
||||||
- `on-scroll` Callback called on the on-scroll event of the FlatList. Only
|
|
||||||
used when `scrollable?` is non-nil.
|
|
||||||
- `scrollable?` When non-nil, use a scrollable flat-list to render tabs.
|
|
||||||
- `scroll-on-press?` When non-nil, clicking on a tag centers it the middle
|
|
||||||
(with animation enabled).
|
|
||||||
"
|
|
||||||
[{:keys [default-active data fade-end-percentage fade-end? on-change on-scroll scroll-on-press?
|
[{:keys [default-active data fade-end-percentage fade-end? on-change on-scroll scroll-on-press?
|
||||||
scrollable? style container-style size blur? in-scroll-view? customization-color]
|
scrollable? style container-style size blur? in-scroll-view? customization-color
|
||||||
|
active-tab-id]
|
||||||
:or {fade-end-percentage 0.8
|
:or {fade-end-percentage 0.8
|
||||||
fade-end? false
|
fade-end? false
|
||||||
scrollable? false
|
scrollable? false
|
||||||
scroll-on-press? false
|
scroll-on-press? false
|
||||||
size default-tab-size}
|
size default-tab-size}
|
||||||
:as props}]
|
:as props}]
|
||||||
(let [[active-tab-id
|
(let [[active-tab-internal-id
|
||||||
set-active-tab-id] (rn/use-state default-active)
|
set-active-tab-internal-id] (rn/use-state default-active)
|
||||||
|
tab-id (or active-tab-id active-tab-internal-id)
|
||||||
|
|
||||||
[fading set-fading] (rn/use-state fade-end-percentage)
|
[fading set-fading] (rn/use-state fade-end-percentage)
|
||||||
flat-list-ref (rn/use-ref-atom nil)
|
flat-list-ref (rn/use-ref-atom nil)
|
||||||
tabs-data (rn/use-memo (fn [] (filterv some? data))
|
tabs-data (rn/use-memo (fn [] (filterv some? data))
|
||||||
|
@ -143,11 +129,11 @@
|
||||||
{:animated false
|
{:animated false
|
||||||
:index
|
:index
|
||||||
(utils.collection/first-index
|
(utils.collection/first-index
|
||||||
#(= active-tab-id (:id %))
|
#(= tab-id (:id %))
|
||||||
tabs-data)}))))
|
tabs-data)}))))
|
||||||
[active-tab-id tabs-data])
|
[tab-id tabs-data])
|
||||||
on-tab-press (rn/use-callback (fn [id index]
|
on-tab-press (rn/use-callback (fn [id index]
|
||||||
(set-active-tab-id id)
|
(set-active-tab-internal-id id)
|
||||||
(when (and scroll-on-press? @flat-list-ref)
|
(when (and scroll-on-press? @flat-list-ref)
|
||||||
(.scrollToIndex ^js @flat-list-ref
|
(.scrollToIndex ^js @flat-list-ref
|
||||||
#js
|
#js
|
||||||
|
@ -156,7 +142,8 @@
|
||||||
:viewPosition 0.5}))
|
:viewPosition 0.5}))
|
||||||
(when on-change
|
(when on-change
|
||||||
(on-change id)))
|
(on-change id)))
|
||||||
[set-active-tab-id scroll-on-press? on-change])]
|
[set-active-tab-internal-id scroll-on-press?
|
||||||
|
on-change])]
|
||||||
(if scrollable?
|
(if scrollable?
|
||||||
[rn/view {:style {:margin-top (- (dec unread-count-offset))}}
|
[rn/view {:style {:margin-top (- (dec unread-count-offset))}}
|
||||||
[masked-view-wrapper
|
[masked-view-wrapper
|
||||||
|
@ -183,7 +170,7 @@
|
||||||
:on-scroll on-scroll
|
:on-scroll on-scroll
|
||||||
:on-layout set-initial-scroll-poisition
|
:on-layout set-initial-scroll-poisition
|
||||||
:render-fn tab-view
|
:render-fn tab-view
|
||||||
:render-data {:active-tab-id active-tab-id
|
:render-data {:active-tab-id tab-id
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:number-of-items (count tabs-data)
|
:number-of-items (count tabs-data)
|
||||||
|
@ -194,7 +181,7 @@
|
||||||
(map-indexed (fn [index item]
|
(map-indexed (fn [index item]
|
||||||
^{:key (:id item)}
|
^{:key (:id item)}
|
||||||
[tab-view item index nil
|
[tab-view item index nil
|
||||||
{:active-tab-id active-tab-id
|
{:active-tab-id tab-id
|
||||||
:blur? blur?
|
:blur? blur?
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:number-of-items (count tabs-data)
|
:number-of-items (count tabs-data)
|
||||||
|
@ -202,3 +189,5 @@
|
||||||
:on-press on-tab-press
|
:on-press on-tab-press
|
||||||
:style style}])
|
:style style}])
|
||||||
tabs-data)])))
|
tabs-data)])))
|
||||||
|
|
||||||
|
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||||
|
|
|
@ -59,26 +59,36 @@
|
||||||
:height 32
|
:height 32
|
||||||
:margin-top 8})
|
:margin-top 8})
|
||||||
|
|
||||||
(def content-container
|
(def container
|
||||||
{:margin-left 8})
|
{:flex-direction :row
|
||||||
|
:column-gap 8})
|
||||||
|
|
||||||
(def content-line
|
(def content-line
|
||||||
{:flex-direction :row
|
{:flex-direction :row
|
||||||
:margin-top 2
|
:margin-top 2
|
||||||
:align-items :center})
|
:align-items :center})
|
||||||
|
|
||||||
(defn icon-hole-view
|
(def icon-hole-view
|
||||||
[theme blur?]
|
|
||||||
{:width 32
|
{:width 32
|
||||||
:height 32
|
:height 32
|
||||||
:border-width 1
|
|
||||||
:border-color (if-not blur?
|
|
||||||
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
|
||||||
colors/white-opa-5)
|
|
||||||
:border-radius 16
|
|
||||||
:align-items :center
|
:align-items :center
|
||||||
:justify-content :center})
|
:justify-content :center})
|
||||||
|
|
||||||
|
(defn icon-circle-border
|
||||||
|
[theme blur?]
|
||||||
|
{:position :absolute
|
||||||
|
:top 0
|
||||||
|
:left 0
|
||||||
|
:right 0
|
||||||
|
:bottom 0
|
||||||
|
:width 32
|
||||||
|
:height 32
|
||||||
|
:border-width 1
|
||||||
|
:border-radius 16
|
||||||
|
:border-color (if-not blur?
|
||||||
|
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||||
|
colors/white-opa-5)})
|
||||||
|
|
||||||
(defn icon-color
|
(defn icon-color
|
||||||
[theme]
|
[theme]
|
||||||
(colors/theme-colors colors/neutral-100 colors/white theme))
|
(colors/theme-colors colors/neutral-100 colors/white theme))
|
||||||
|
|
|
@ -70,20 +70,21 @@
|
||||||
status :pending}}
|
status :pending}}
|
||||||
theme]
|
theme]
|
||||||
[rn/view {:style style/icon-container}
|
[rn/view {:style style/icon-container}
|
||||||
|
[rn/view {:style style/icon-status-container}
|
||||||
|
[icon/icon (status-icon status)
|
||||||
|
{:size 12
|
||||||
|
:no-color :true}]]
|
||||||
[hole-view/hole-view
|
[hole-view/hole-view
|
||||||
{:style (style/icon-hole-view theme blur?)
|
{:style style/icon-hole-view
|
||||||
:holes [{:x 20
|
:holes [{:x 20
|
||||||
:y 20
|
:y 20
|
||||||
:right 0
|
:right 0
|
||||||
:width 12
|
:width 12
|
||||||
:height 12
|
:height 12
|
||||||
:borderRadius 6}]}
|
:borderRadius 6}]}
|
||||||
[icon/icon (transaction-icon transaction)
|
[icon/icon (transaction-icon transaction :i/placeholder)
|
||||||
{:color (style/icon-color theme)}]]
|
{:color (style/icon-color theme)}]
|
||||||
[rn/view {:style style/icon-status-container}
|
[rn/view {:style (style/icon-circle-border theme blur?)}]]])
|
||||||
[icon/icon (status-icon status)
|
|
||||||
{:size 12
|
|
||||||
:no-color :true}]]])
|
|
||||||
|
|
||||||
(defn prop-text
|
(defn prop-text
|
||||||
[label theme]
|
[label theme]
|
||||||
|
@ -116,11 +117,9 @@
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:on-press-in on-press-in
|
:on-press-in on-press-in
|
||||||
:on-press-out on-press-out}
|
:on-press-out on-press-out}
|
||||||
[rn/view
|
[rn/view {:style style/container}
|
||||||
{:style {:flex-direction :row}}
|
|
||||||
[transaction-icon-view props theme]
|
[transaction-icon-view props theme]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/content-container}
|
|
||||||
[transaction-header props theme]
|
[transaction-header props theme]
|
||||||
[rn/view {:style style/content-line}
|
[rn/view {:style style/content-line}
|
||||||
(when first-tag [prop-tag first-tag blur?])
|
(when first-tag [prop-tag first-tag blur?])
|
||||||
|
|
|
@ -41,13 +41,13 @@
|
||||||
[message]
|
[message]
|
||||||
(let [cause (if platform/android?
|
(let [cause (if platform/android?
|
||||||
(condp = message
|
(condp = message
|
||||||
android-not-enrolled-error-message :biometrics/not-enrolled-error
|
android-not-enrolled-error-message :biometrics/fingerprints-not-enrolled-error
|
||||||
android-not-available-error-message :biometrics/not-available-error
|
android-not-available-error-message :biometrics/not-available-error
|
||||||
android-too-many-attempts-error-message :biometric/too-many-attempts
|
android-too-many-attempts-error-message :biometric/too-many-attempts
|
||||||
:biometrics/unknown-error)
|
:biometrics/unknown-error)
|
||||||
|
|
||||||
(condp #(string/includes? %2 %1) message
|
(condp #(string/includes? %2 %1) message
|
||||||
ios-not-enrolled-error-message :biometrics/not-enrolled-error
|
ios-not-enrolled-error-message :biometrics/ios-not-enrolled-error
|
||||||
:biometrics/unknown-error))]
|
:biometrics/unknown-error))]
|
||||||
(ex-info "Failed to authenticate with biometrics"
|
(ex-info "Failed to authenticate with biometrics"
|
||||||
{:orig-error-message message}
|
{:orig-error-message message}
|
||||||
|
|
|
@ -14,8 +14,11 @@
|
||||||
(defn show-message
|
(defn show-message
|
||||||
[_ [code]]
|
[_ [code]]
|
||||||
(let [content (case code
|
(let [content (case code
|
||||||
(:biometrics/not-enrolled-error
|
(:biometrics/fingerprints-not-enrolled-error
|
||||||
:biometrics/not-available-error)
|
:biometrics/not-available-error)
|
||||||
|
(i18n/label :t/grant-fingerprints-permissions)
|
||||||
|
|
||||||
|
:biometrics/ios-not-enrolled-error
|
||||||
(i18n/label :t/grant-face-id-permissions)
|
(i18n/label :t/grant-face-id-permissions)
|
||||||
|
|
||||||
:biometric/too-many-attempts
|
:biometric/too-many-attempts
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
(let [cofx {:db {}}
|
(let [cofx {:db {}}
|
||||||
expected {:fx [[:effects.utils/show-popup
|
expected {:fx [[:effects.utils/show-popup
|
||||||
{:title (i18n/label :t/biometric-auth-login-error-title)
|
{:title (i18n/label :t/biometric-auth-login-error-title)
|
||||||
:content (i18n/label :t/grant-face-id-permissions)}]]}]
|
:content (i18n/label :t/grant-fingerprints-permissions)}]]}]
|
||||||
(is (match? expected
|
(is (match? expected
|
||||||
(sut/show-message cofx
|
(sut/show-message cofx
|
||||||
[:biometrics/not-available-error])))))
|
[:biometrics/not-available-error])))))
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[legacy.status-im.ethereum.mnemonic :as mnemonic]
|
[legacy.status-im.ethereum.mnemonic :as mnemonic]
|
||||||
|
[oops.core :as oops]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
@ -104,16 +105,17 @@
|
||||||
"keyboardDidHide"
|
"keyboardDidHide"
|
||||||
#(reset! keyboard-shown? false))
|
#(reset! keyboard-shown? false))
|
||||||
invalid-seed-phrase? (reagent/atom false)
|
invalid-seed-phrase? (reagent/atom false)
|
||||||
|
incorrect-seed-phrase? (reagent/atom false)
|
||||||
input-ref (reagent/atom nil)
|
input-ref (reagent/atom nil)
|
||||||
focus-input (fn []
|
focus-input #(some-> @input-ref
|
||||||
(let [ref @input-ref]
|
(oops/ocall "focus"))
|
||||||
(when ref
|
set-incorrect-seed-phrase #(reset! incorrect-seed-phrase? true)
|
||||||
(.focus ref))))
|
|
||||||
set-invalid-seed-phrase #(reset! invalid-seed-phrase? true)
|
set-invalid-seed-phrase #(reset! invalid-seed-phrase? true)
|
||||||
seed-phrase (reagent/atom "")
|
seed-phrase (reagent/atom "")
|
||||||
on-change-seed-phrase (fn [new-phrase]
|
on-change-seed-phrase (fn [new-phrase]
|
||||||
(when @invalid-seed-phrase?
|
(when @invalid-seed-phrase?
|
||||||
(reset! invalid-seed-phrase? false))
|
(reset! invalid-seed-phrase? false)
|
||||||
|
(reset! incorrect-seed-phrase? false))
|
||||||
(reset! seed-phrase new-phrase))
|
(reset! seed-phrase new-phrase))
|
||||||
on-submit (fn []
|
on-submit (fn []
|
||||||
(swap! seed-phrase clean-seed-phrase)
|
(swap! seed-phrase clean-seed-phrase)
|
||||||
|
@ -143,7 +145,8 @@
|
||||||
suggestions-state (cond
|
suggestions-state (cond
|
||||||
(or error-in-words?
|
(or error-in-words?
|
||||||
words-exceeded?
|
words-exceeded?
|
||||||
@invalid-seed-phrase?) :error
|
@invalid-seed-phrase?
|
||||||
|
@incorrect-seed-phrase?) :error
|
||||||
(string/blank? @seed-phrase) :info
|
(string/blank? @seed-phrase) :info
|
||||||
(string/ends-with? @seed-phrase " ") :empty
|
(string/ends-with? @seed-phrase " ") :empty
|
||||||
:else :words)
|
:else :words)
|
||||||
|
@ -152,6 +155,7 @@
|
||||||
words-exceeded? (i18n/label :t/seed-phrase-words-exceeded)
|
words-exceeded? (i18n/label :t/seed-phrase-words-exceeded)
|
||||||
error-in-words? (i18n/label :t/seed-phrase-error)
|
error-in-words? (i18n/label :t/seed-phrase-error)
|
||||||
@invalid-seed-phrase? (i18n/label :t/seed-phrase-invalid)
|
@invalid-seed-phrase? (i18n/label :t/seed-phrase-invalid)
|
||||||
|
@incorrect-seed-phrase? (i18n/label :t/seed-phrase-incorrect)
|
||||||
:else (i18n/label :t/seed-phrase-info))
|
:else (i18n/label :t/seed-phrase-info))
|
||||||
error-state? (= suggestions-state :error)
|
error-state? (= suggestions-state :error)
|
||||||
button-disabled? (or error-state?
|
button-disabled? (or error-state?
|
||||||
|
@ -172,7 +176,7 @@
|
||||||
:prepare-seed-phrase secure-clean-seed-phrase
|
:prepare-seed-phrase secure-clean-seed-phrase
|
||||||
:focus-input focus-input
|
:focus-input focus-input
|
||||||
:seed-phrase (security/mask-data @seed-phrase)
|
:seed-phrase (security/mask-data @seed-phrase)
|
||||||
:set-invalid-seed-phrase set-invalid-seed-phrase})
|
:set-incorrect-seed-phrase set-incorrect-seed-phrase})
|
||||||
[quo/button
|
[quo/button
|
||||||
{:container-style (style/continue-button @keyboard-shown?)
|
{:container-style (style/continue-button @keyboard-shown?)
|
||||||
:type :primary
|
:type :primary
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn edit-message
|
(defn edit-message
|
||||||
[{:keys [text-value input-ref]}]
|
[{:keys [text-value input-ref input-height]}]
|
||||||
(let [theme (quo.theme/use-theme)]
|
(let [theme (quo.theme/use-theme)]
|
||||||
[rn/view
|
[rn/view
|
||||||
{:style style/container
|
{:style style/container
|
||||||
|
@ -32,7 +32,7 @@
|
||||||
{:size 24
|
{:size 24
|
||||||
:icon-only? true
|
:icon-only? true
|
||||||
:accessibility-label :edit-cancel-button
|
:accessibility-label :edit-cancel-button
|
||||||
:on-press #(utils/cancel-edit-message text-value input-ref)
|
:on-press #(utils/cancel-edit-message text-value input-ref input-height)
|
||||||
:type :outline}
|
:type :outline}
|
||||||
:i/close]]))
|
:i/close]]))
|
||||||
|
|
||||||
|
|
|
@ -101,12 +101,16 @@
|
||||||
(rf/dispatch [:chat.ui/cancel-message-reply]))
|
(rf/dispatch [:chat.ui/cancel-message-reply]))
|
||||||
|
|
||||||
(defn cancel-edit-message
|
(defn cancel-edit-message
|
||||||
[text-value input-ref]
|
[text-value input-ref input-height]
|
||||||
(reset! text-value "")
|
(reset! text-value "")
|
||||||
;; NOTE: adding a timeout to assure the input is blurred on the next tick
|
;; NOTE: adding a timeout to assure the input is blurred on the next tick
|
||||||
;; after the `text-value` was cleared. Otherwise the height will be calculated
|
;; after the `text-value` was cleared. Otherwise the height will be calculated
|
||||||
;; with the old `text-value`, leading to wrong composer height after blur.
|
;; with the old `text-value`, leading to wrong composer height after blur.
|
||||||
(js/setTimeout #(blur-input input-ref) 100)
|
(js/setTimeout
|
||||||
|
(fn []
|
||||||
|
(blur-input input-ref)
|
||||||
|
(reanimated/set-shared-value input-height constants/input-height))
|
||||||
|
100)
|
||||||
(.setNativeProps ^js @input-ref (clj->js {:text ""}))
|
(.setNativeProps ^js @input-ref (clj->js {:text ""}))
|
||||||
(rf/dispatch [:chat.ui/set-input-content-height constants/input-height])
|
(rf/dispatch [:chat.ui/set-input-content-height constants/input-height])
|
||||||
(rf/dispatch [:chat.ui/cancel-message-edit]))
|
(rf/dispatch [:chat.ui/cancel-message-edit]))
|
||||||
|
|
|
@ -106,6 +106,7 @@
|
||||||
[reply/view state (:input-ref props)]
|
[reply/view state (:input-ref props)]
|
||||||
[edit/view
|
[edit/view
|
||||||
{:text-value (:text-value state)
|
{:text-value (:text-value state)
|
||||||
|
:input-height (:height animations)
|
||||||
:input-ref (:input-ref props)}]]
|
:input-ref (:input-ref props)}]]
|
||||||
[reanimated/touchable-opacity
|
[reanimated/touchable-opacity
|
||||||
{:active-opacity 1
|
{:active-opacity 1
|
||||||
|
|
|
@ -102,18 +102,43 @@
|
||||||
;; https://github.com/status-im/status-mobile/issues/17426
|
;; https://github.com/status-im/status-mobile/issues/17426
|
||||||
[quo/skeleton-list (skeleton-list-props :messages parent-height platform/ios?)]]))
|
[quo/skeleton-list (skeleton-list-props :messages parent-height platform/ios?)]]))
|
||||||
|
|
||||||
|
(defn header-height
|
||||||
|
[{:keys [insets able-to-send-message? images reply edit link-previews? input-content-height]}]
|
||||||
|
(if able-to-send-message?
|
||||||
|
(cond-> composer.constants/composer-default-height
|
||||||
|
(ff/enabled? ::ff/shell.jump-to)
|
||||||
|
(+ jump-to.constants/floating-shell-button-height)
|
||||||
|
|
||||||
|
(seq images)
|
||||||
|
(+ composer.constants/images-container-height)
|
||||||
|
|
||||||
|
reply
|
||||||
|
(+ composer.constants/reply-container-height)
|
||||||
|
|
||||||
|
edit
|
||||||
|
(+ composer.constants/edit-container-height)
|
||||||
|
|
||||||
|
link-previews?
|
||||||
|
(+ composer.constants/links-container-height)
|
||||||
|
|
||||||
|
(and input-content-height (not= input-content-height composer.constants/input-height))
|
||||||
|
(+ composer.constants/input-height)
|
||||||
|
|
||||||
|
true
|
||||||
|
(+ (:bottom insets)))
|
||||||
|
(- 70 (:bottom insets))))
|
||||||
|
|
||||||
(defn list-header
|
(defn list-header
|
||||||
[insets able-to-send-message?]
|
[insets able-to-send-message?]
|
||||||
(let [images (rf/sub [:chats/sending-image])
|
(let [header-data {:insets insets
|
||||||
height (if able-to-send-message?
|
:able-to-send-message? able-to-send-message?
|
||||||
(+ composer.constants/composer-default-height
|
:input-content-height (:input-content-height (rf/sub [:chats/current-chat-input]))
|
||||||
(if (ff/enabled? ::ff/shell.jump-to)
|
:images (rf/sub [:chats/sending-image])
|
||||||
jump-to.constants/floating-shell-button-height
|
:reply (rf/sub [:chats/reply-message])
|
||||||
0)
|
:edit (rf/sub [:chats/edit-message])
|
||||||
(if (seq images) composer.constants/images-container-height 0)
|
:link-previews? (or (rf/sub [:chats/link-previews?])
|
||||||
(:bottom insets))
|
(rf/sub [:chats/status-link-previews?]))}]
|
||||||
(- 70 (:bottom insets)))]
|
[rn/view {:style {:height (header-height header-data)}}]))
|
||||||
[rn/view {:style {:height height}}]))
|
|
||||||
|
|
||||||
(defn list-footer-avatar
|
(defn list-footer-avatar
|
||||||
[{:keys [distance-from-list-top display-name online? profile-picture theme group-chat color
|
[{:keys [distance-from-list-top display-name online? profile-picture theme group-chat color
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.platform :as platform]
|
[react-native.platform :as platform]
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.common.validation.profile :as profile-validator]
|
[status-im.common.validation.profile :as profile-validator]
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.profile.edit.bio.style :as style]
|
[status-im.contexts.profile.edit.bio.style :as style]
|
||||||
|
@ -18,20 +17,19 @@
|
||||||
profile (rf/sub [:profile/profile-with-image])
|
profile (rf/sub [:profile/profile-with-image])
|
||||||
customization-color (rf/sub [:profile/customization-color])
|
customization-color (rf/sub [:profile/customization-color])
|
||||||
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
|
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
|
||||||
profile-bio (:bio profile)
|
current-bio (:bio profile)
|
||||||
unsaved-bio (reagent/atom profile-bio)
|
[bio set-bio] (rn/use-state current-bio)
|
||||||
error-msg (reagent/atom nil)
|
[error-msg set-error-msg] (rn/use-state nil)
|
||||||
typing? (reagent/atom false)
|
[typing? set-typing] (rn/use-state false)
|
||||||
validate-bio (debounce/debounce (fn [bio]
|
validate-bio (debounce/debounce (fn [bio]
|
||||||
(reset! error-msg
|
(set-error-msg (profile-validator/validation-bio
|
||||||
(profile-validator/validation-bio bio))
|
bio))
|
||||||
(reset! typing? false))
|
(set-typing false))
|
||||||
300)
|
300)
|
||||||
on-change-text (fn [s]
|
on-change-text (fn [s]
|
||||||
(reset! typing? true)
|
(set-typing true)
|
||||||
(reset! unsaved-bio s)
|
(set-bio s)
|
||||||
(validate-bio s))]
|
(validate-bio s))]
|
||||||
(fn []
|
|
||||||
[quo/overlay
|
[quo/overlay
|
||||||
{:type :shell
|
{:type :shell
|
||||||
:container-style (style/page-wrapper insets)}
|
:container-style (style/page-wrapper insets)}
|
||||||
|
@ -49,28 +47,29 @@
|
||||||
[quo/input
|
[quo/input
|
||||||
{:blur? true
|
{:blur? true
|
||||||
:multiline? true
|
:multiline? true
|
||||||
:error? (not (string/blank? @error-msg))
|
:error? (not (string/blank? error-msg))
|
||||||
:container-style {:margin-bottom -11}
|
:container-style {:margin-bottom -11}
|
||||||
:default-value @unsaved-bio
|
:default-value bio
|
||||||
:auto-focus true
|
:auto-focus true
|
||||||
|
:max-height 200
|
||||||
:char-limit constants/profile-bio-max-length
|
:char-limit constants/profile-bio-max-length
|
||||||
:label (i18n/label :t/profile-bio)
|
:label (i18n/label :t/profile-bio)
|
||||||
:placeholder (i18n/label :t/something-about-you)
|
:placeholder (i18n/label :t/something-about-you)
|
||||||
:on-change-text on-change-text}]
|
:on-change-text on-change-text}]
|
||||||
(when-not (string/blank? @error-msg)
|
(when-not (string/blank? error-msg)
|
||||||
[quo/info-message
|
[quo/info-message
|
||||||
{:type :error
|
{:type :error
|
||||||
:size :default
|
:size :default
|
||||||
:icon :i/info}
|
:icon :i/info}
|
||||||
@error-msg])]
|
error-msg])]
|
||||||
[rn/view {:style style/button-wrapper}
|
[rn/view {:style style/button-wrapper}
|
||||||
[quo/button
|
[quo/button
|
||||||
{:type :primary
|
{:type :primary
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:on-press (fn []
|
:on-press (fn []
|
||||||
(rf/dispatch [:profile/edit-bio @unsaved-bio]))
|
(rf/dispatch [:profile/edit-bio bio]))
|
||||||
:disabled? (boolean (or @typing?
|
:disabled? (boolean (or typing?
|
||||||
(and (string/blank? profile-bio)
|
(and (string/blank? current-bio)
|
||||||
(string/blank? @unsaved-bio))
|
(string/blank? bio))
|
||||||
(not (string/blank? @error-msg))))}
|
(not (string/blank? error-msg))))}
|
||||||
(i18n/label :t/save-bio)]]]])))
|
(i18n/label :t/save-bio)]]]]))
|
||||||
|
|
|
@ -196,7 +196,7 @@
|
||||||
login-multiaccount (rn/use-callback #(rf/dispatch [:profile.login/login]))]
|
login-multiaccount (rn/use-callback #(rf/dispatch [:profile.login/login]))]
|
||||||
[rn/keyboard-avoiding-view
|
[rn/keyboard-avoiding-view
|
||||||
{:style style/login-container
|
{:style style/login-container
|
||||||
:keyboardVerticalOffset (- (safe-area/get-bottom))}
|
:keyboard-vertical-offset (- (safe-area/get-bottom))}
|
||||||
[rn/view {:style style/multi-profile-button-container}
|
[rn/view {:style style/multi-profile-button-container}
|
||||||
(when config/quo-preview-enabled?
|
(when config/quo-preview-enabled?
|
||||||
[quo/button
|
[quo/button
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
:blur? true
|
:blur? true
|
||||||
:action :arrow}
|
:action :arrow}
|
||||||
{:title (i18n/label :t/wallet)
|
{:title (i18n/label :t/wallet)
|
||||||
:on-press #(rf/dispatch [:navigate-to-within-stack [:screen/settings.wallet :settings]])
|
:on-press #(rf/dispatch [:open-modal :screen/settings.wallet])
|
||||||
:image-props :i/wallet
|
:image-props :i/wallet
|
||||||
:image :icon
|
:image :icon
|
||||||
:blur? true
|
:blur? true
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.contexts.profile.settings.screens.password.change-password.style
|
(ns status-im.contexts.profile.settings.screens.password.change-password.style
|
||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
|
[react-native.platform :as platform]
|
||||||
[react-native.safe-area :as safe-area]))
|
[react-native.safe-area :as safe-area]))
|
||||||
|
|
||||||
(def form-container
|
(def form-container
|
||||||
|
@ -48,7 +49,7 @@
|
||||||
:justify-content :space-between})
|
:justify-content :space-between})
|
||||||
|
|
||||||
(def bottom-part
|
(def bottom-part
|
||||||
{:margin-bottom (- (safe-area/get-bottom) 12)
|
{:margin-bottom (if platform/ios? (safe-area/get-bottom) 12)
|
||||||
:justify-content :flex-end})
|
:justify-content :flex-end})
|
||||||
|
|
||||||
(def disclaimer-container
|
(def disclaimer-container
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [{:keys [top]} (safe-area/get-insets)
|
(let [{:keys [top bottom]} (safe-area/get-insets)
|
||||||
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
|
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
|
||||||
current-step (rf/sub [:settings/change-password-current-step])]
|
current-step (rf/sub [:settings/change-password-current-step])]
|
||||||
(rn/use-unmount #(rf/dispatch [:change-password/reset]))
|
(rn/use-unmount #(rf/dispatch [:change-password/reset]))
|
||||||
|
@ -34,7 +34,11 @@
|
||||||
:on-press navigate-back}]
|
:on-press navigate-back}]
|
||||||
[rn/keyboard-avoiding-view
|
[rn/keyboard-avoiding-view
|
||||||
{:style {:flex 1}
|
{:style {:flex 1}
|
||||||
:keyboardVerticalOffset (if platform/ios? alert-banners-top-margin 0)}
|
:keyboard-vertical-offset (if platform/ios?
|
||||||
|
(-> 12
|
||||||
|
(+ alert-banners-top-margin)
|
||||||
|
(- bottom))
|
||||||
|
0)}
|
||||||
(condp = current-step
|
(condp = current-step
|
||||||
:old-password [old-password-form/view]
|
:old-password [old-password-form/view]
|
||||||
:new-password [new-password-form/view])]]]))
|
:new-password [new-password-form/view])]]]))
|
||||||
|
|
|
@ -30,18 +30,18 @@
|
||||||
supported? (boolean biometric-type)
|
supported? (boolean biometric-type)
|
||||||
enabled? (= auth-method constants/auth-method-biometric)
|
enabled? (= auth-method constants/auth-method-biometric)
|
||||||
biometric-on? (and supported? enabled?)
|
biometric-on? (and supported? enabled?)
|
||||||
press-handler (if biometric-on?
|
press-handler (when supported?
|
||||||
|
(if biometric-on?
|
||||||
(fn [] (rf/dispatch [:biometric/disable]))
|
(fn [] (rf/dispatch [:biometric/disable]))
|
||||||
(on-press-biometric-enable label theme))]
|
(on-press-biometric-enable label theme)))]
|
||||||
{:title label
|
{:title label
|
||||||
:image-props icon
|
:image-props icon
|
||||||
:image :icon
|
:image :icon
|
||||||
:blur? true
|
:blur? true
|
||||||
:action :selector
|
:action :selector
|
||||||
:action-props {:disabled? (not supported?)
|
:action-props {:on-change press-handler
|
||||||
:on-change press-handler
|
|
||||||
:checked? biometric-on?}
|
:checked? biometric-on?}
|
||||||
:on-press (when supported? press-handler)}))
|
:on-press press-handler}))
|
||||||
|
|
||||||
(defn- get-change-password-item
|
(defn- get-change-password-item
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -167,9 +167,9 @@
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/verify-private-key-for-keypair verify-private-key-for-keypair)
|
(rf/reg-event-fx :wallet/verify-private-key-for-keypair verify-private-key-for-keypair)
|
||||||
|
|
||||||
(defn import-keypair-by-seed-phrase
|
(defn import-missing-keypair-by-seed-phrase
|
||||||
[_ [{:keys [keypair-key-uid seed-phrase password on-success on-error]}]]
|
[_ [{:keys [keypair-key-uid seed-phrase password on-success on-error]}]]
|
||||||
{:fx [[:import-keypair-by-seed-phrase
|
{:fx [[:effects.wallet/import-missing-keypair-by-seed-phrase
|
||||||
{:keypair-key-uid keypair-key-uid
|
{:keypair-key-uid keypair-key-uid
|
||||||
:seed-phrase seed-phrase
|
:seed-phrase seed-phrase
|
||||||
:password password
|
:password password
|
||||||
|
@ -178,24 +178,26 @@
|
||||||
#{keypair-key-uid}])
|
#{keypair-key-uid}])
|
||||||
(rf/call-continuation on-success))
|
(rf/call-continuation on-success))
|
||||||
:on-error (fn [error]
|
:on-error (fn [error]
|
||||||
(rf/dispatch [:wallet/import-keypair-by-seed-phrase-failed error])
|
(rf/dispatch [:wallet/import-missing-keypair-by-seed-phrase-failed error])
|
||||||
|
(log/error "failed to import missing keypair with seed phrase"
|
||||||
|
{:error error})
|
||||||
(rf/call-continuation on-error error))}]]})
|
(rf/call-continuation on-error error))}]]})
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/import-keypair-by-seed-phrase import-keypair-by-seed-phrase)
|
(rf/reg-event-fx :wallet/import-missing-keypair-by-seed-phrase import-missing-keypair-by-seed-phrase)
|
||||||
|
|
||||||
(defn import-keypair-by-seed-phrase-failed
|
(defn import-missing-keypair-by-seed-phrase-failed
|
||||||
[_ [error]]
|
[_ [error]]
|
||||||
(let [error-type (-> error ex-message keyword)
|
(let [error-type (-> error ex-message keyword)
|
||||||
error-data (ex-data error)]
|
error-data (ex-data error)]
|
||||||
(when-not (and (= error-type :import-keypair-by-seed-phrase/import-error)
|
(when-not (= error-type :import-missing-keypair-by-seed-phrase/import-error)
|
||||||
(= (:hint error-data) :incorrect-seed-phrase-for-keypair))
|
|
||||||
{:fx [[:dispatch
|
{:fx [[:dispatch
|
||||||
[:toasts/upsert
|
[:toasts/upsert
|
||||||
{:type :negative
|
{:type :negative
|
||||||
:theme :dark
|
:theme :dark
|
||||||
:text (:error error-data)}]]]})))
|
:text (:error error-data)}]]]})))
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/import-keypair-by-seed-phrase-failed import-keypair-by-seed-phrase-failed)
|
(rf/reg-event-fx :wallet/import-missing-keypair-by-seed-phrase-failed
|
||||||
|
import-missing-keypair-by-seed-phrase-failed)
|
||||||
|
|
||||||
(defn import-missing-keypair-by-private-key
|
(defn import-missing-keypair-by-private-key
|
||||||
[_ [{:keys [keypair-key-uid private-key password on-success on-error]}]]
|
[_ [{:keys [keypair-key-uid private-key password on-success on-error]}]]
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view
|
||||||
(:require [quo.core :as quo]
|
(:require [quo.core :as quo]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.remove.view :as remove-key-pair]
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.remove.view :as remove-keypair]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -14,20 +14,22 @@
|
||||||
[(:key-uid keypair)]])
|
[(:key-uid keypair)]])
|
||||||
[keypair])
|
[keypair])
|
||||||
on-show-qr (rn/use-callback #(rf/dispatch [:open-modal
|
on-show-qr (rn/use-callback #(rf/dispatch [:open-modal
|
||||||
:screen/settings.encrypted-key-pair-qr
|
:screen/settings.encrypted-keypair-qr
|
||||||
keypair])
|
keypair])
|
||||||
[keypair])
|
[keypair])
|
||||||
on-remove-keypair (rn/use-callback #(rf/dispatch
|
on-remove-keypair (rn/use-callback #(rf/dispatch
|
||||||
[:show-bottom-sheet
|
[:show-bottom-sheet
|
||||||
{:theme :dark
|
{:theme :dark
|
||||||
:content (fn []
|
:content (fn []
|
||||||
[remove-key-pair/view keypair])}])
|
[remove-keypair/view keypair])}])
|
||||||
[keypair])
|
[keypair])
|
||||||
on-rename-keypair (rn/use-callback #(rf/dispatch [:open-modal :screen/settings.rename-keypair
|
on-rename-keypair (rn/use-callback #(rf/dispatch [:open-modal :screen/settings.rename-keypair
|
||||||
keypair])
|
keypair])
|
||||||
[keypair])
|
[keypair])
|
||||||
on-import-seed-phrase (rn/use-callback
|
on-import-seed-phrase (rn/use-callback
|
||||||
#(rf/dispatch [:open-modal :screen/settings.import-seed-phrase keypair])
|
#(rf/dispatch [:open-modal
|
||||||
|
:screen/settings.missing-keypair.import-seed-phrase
|
||||||
|
keypair])
|
||||||
[keypair])
|
[keypair])
|
||||||
on-import-private-key (rn/use-callback
|
on-import-private-key (rn/use-callback
|
||||||
#(rf/dispatch [:open-modal
|
#(rf/dispatch [:open-modal
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.countdown.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
|
@ -1,4 +1,4 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.style
|
||||||
(:require
|
(:require
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
[react-native.safe-area :as safe-area]))
|
[react-native.safe-area :as safe-area]))
|
|
@ -1,4 +1,4 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.colors :as colors]
|
[quo.foundations.colors :as colors]
|
||||||
|
@ -7,8 +7,10 @@
|
||||||
[status-im.common.qr-codes.view :as qr-codes]
|
[status-im.common.qr-codes.view :as qr-codes]
|
||||||
[status-im.common.resources :as resources]
|
[status-im.common.resources :as resources]
|
||||||
[status-im.common.standard-authentication.core :as standard-auth]
|
[status-im.common.standard-authentication.core :as standard-auth]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.countdown.view :as countdown]
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.countdown.view
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.style :as style]
|
:as countdown]
|
||||||
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.style
|
||||||
|
:as style]
|
||||||
[status-im.contexts.syncing.utils :as sync-utils]
|
[status-im.contexts.syncing.utils :as sync-utils]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
|
@ -1,4 +1,4 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.style)
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-private-key.style)
|
||||||
|
|
||||||
(def form-container
|
(def form-container
|
||||||
{:row-gap 8
|
{:row-gap 8
|
|
@ -1,4 +1,4 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.view
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-private-key.view
|
||||||
(:require
|
(:require
|
||||||
[clojure.string :as string]
|
[clojure.string :as string]
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
|
@ -7,7 +7,8 @@
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||||
[status-im.common.standard-authentication.core :as standard-auth]
|
[status-im.common.standard-authentication.core :as standard-auth]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.style :as style]
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-private-key.style
|
||||||
|
:as style]
|
||||||
[status-im.contexts.wallet.common.validation :as validation]
|
[status-im.contexts.wallet.common.validation :as validation]
|
||||||
[utils.debounce :as debounce]
|
[utils.debounce :as debounce]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
|
@ -68,8 +69,7 @@
|
||||||
[on-change])
|
[on-change])
|
||||||
on-import-error (rn/use-callback
|
on-import-error (rn/use-callback
|
||||||
(fn [_error]
|
(fn [_error]
|
||||||
(rf/dispatch [:hide-bottom-sheet])
|
(rf/dispatch [:hide-bottom-sheet])))
|
||||||
(show-invalid)))
|
|
||||||
on-import-success (rn/use-callback
|
on-import-success (rn/use-callback
|
||||||
(fn []
|
(fn []
|
||||||
(rf/dispatch [:hide-bottom-sheet])
|
(rf/dispatch [:hide-bottom-sheet])
|
||||||
|
@ -134,5 +134,5 @@
|
||||||
(case flow-state
|
(case flow-state
|
||||||
:correct-private-key (i18n/label :t/correct-private-key)
|
:correct-private-key (i18n/label :t/correct-private-key)
|
||||||
:invalid-private-key (i18n/label :t/invalid-private-key)
|
:invalid-private-key (i18n/label :t/invalid-private-key)
|
||||||
:incorrect-private-key (i18n/label :t/incorrect-private-key {:name (:name keypair)})
|
:incorrect-private-key (i18n/label :t/incorrect-private-key)
|
||||||
nil)])]]]))
|
nil)])]]]))
|
|
@ -1,4 +1,4 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.import-seed-phrase.view
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-seed-phrase.view
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
|
@ -14,16 +14,17 @@
|
||||||
container-style
|
container-style
|
||||||
prepare-seed-phrase
|
prepare-seed-phrase
|
||||||
seed-phrase
|
seed-phrase
|
||||||
set-invalid-seed-phrase
|
set-incorrect-seed-phrase
|
||||||
focus-input]}]
|
focus-input]}]
|
||||||
(let [keypair (rf/sub [:get-screen-params])
|
(let [keypair (rf/sub [:get-screen-params])
|
||||||
customization-color (rf/sub [:profile/customization-color])
|
customization-color (rf/sub [:profile/customization-color])
|
||||||
show-errors (rn/use-callback
|
show-errors (rn/use-callback
|
||||||
#(js/setTimeout
|
(fn [_error]
|
||||||
|
(js/setTimeout
|
||||||
(fn []
|
(fn []
|
||||||
(focus-input)
|
(focus-input)
|
||||||
(reagent/next-tick set-invalid-seed-phrase))
|
(reagent/next-tick set-incorrect-seed-phrase))
|
||||||
600))
|
600)))
|
||||||
on-import-error (rn/use-callback
|
on-import-error (rn/use-callback
|
||||||
(fn [_error]
|
(fn [_error]
|
||||||
(rf/dispatch [:hide-bottom-sheet])
|
(rf/dispatch [:hide-bottom-sheet])
|
||||||
|
@ -34,7 +35,7 @@
|
||||||
(rf/dispatch [:navigate-back])))
|
(rf/dispatch [:navigate-back])))
|
||||||
on-auth-success (rn/use-callback
|
on-auth-success (rn/use-callback
|
||||||
(fn [password]
|
(fn [password]
|
||||||
(rf/dispatch [:wallet/import-keypair-by-seed-phrase
|
(rf/dispatch [:wallet/import-missing-keypair-by-seed-phrase
|
||||||
{:keypair-key-uid (:key-uid keypair)
|
{:keypair-key-uid (:key-uid keypair)
|
||||||
:seed-phrase (prepare-seed-phrase seed-phrase)
|
:seed-phrase (prepare-seed-phrase seed-phrase)
|
||||||
:password password
|
:password password
|
|
@ -1,4 +1,4 @@
|
||||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.scan-qr.view
|
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.scan-qr.view
|
||||||
(:require
|
(:require
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im.common.scan-qr-code.view :as scan-qr-code]
|
[status-im.common.scan-qr-code.view :as scan-qr-code]
|
|
@ -159,9 +159,7 @@
|
||||||
:ens address-or-ens
|
:ens address-or-ens
|
||||||
:ens? ens-name?}])
|
:ens? ens-name?}])
|
||||||
(rf/dispatch
|
(rf/dispatch
|
||||||
[:navigate-to-within-stack
|
[:open-modal :screen/settings.save-address]))
|
||||||
[:screen/settings.save-address
|
|
||||||
:screen/settings.add-address-to-save]]))
|
|
||||||
[address ens-name? address-or-ens])]
|
[address ens-name? address-or-ens])]
|
||||||
(rn/use-unmount #(rf/dispatch [:wallet/clear-address-to-save]))
|
(rn/use-unmount #(rf/dispatch [:wallet/clear-address-to-save]))
|
||||||
[quo/overlay {:type :shell}
|
[quo/overlay {:type :shell}
|
||||||
|
|
|
@ -66,8 +66,7 @@
|
||||||
|
|
||||||
(defn- add-address-to-save
|
(defn- add-address-to-save
|
||||||
[]
|
[]
|
||||||
(rf/dispatch [:navigate-to-within-stack
|
(rf/dispatch [:open-modal :screen/settings.add-address-to-save]))
|
||||||
[:screen/settings.add-address-to-save :screen/settings.saved-addresses]]))
|
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -8,11 +8,11 @@
|
||||||
|
|
||||||
(defn open-saved-addresses-settings-modal
|
(defn open-saved-addresses-settings-modal
|
||||||
[]
|
[]
|
||||||
(rf/dispatch [:navigate-to-within-stack [:screen/settings.saved-addresses :settings]]))
|
(rf/dispatch [:open-modal :screen/settings.saved-addresses]))
|
||||||
|
|
||||||
(defn open-keypairs-and-accounts-settings-modal
|
(defn open-keypairs-and-accounts-settings-modal
|
||||||
[]
|
[]
|
||||||
(rf/dispatch [:navigate-to-within-stack [:screen/settings.keypairs-and-accounts :settings]]))
|
(rf/dispatch [:open-modal :screen/settings.keypairs-and-accounts]))
|
||||||
|
|
||||||
(defn basic-settings-options
|
(defn basic-settings-options
|
||||||
[]
|
[]
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
|
|
||||||
(defn open-network-settings-modal
|
(defn open-network-settings-modal
|
||||||
[]
|
[]
|
||||||
(rf/dispatch [:navigate-to-within-stack [:screen/settings.network-settings :settings]]))
|
(rf/dispatch [:open-modal :screen/settings.network-settings]))
|
||||||
|
|
||||||
(defn advanced-settings-options
|
(defn advanced-settings-options
|
||||||
[]
|
[]
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
(:require
|
(:require
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[reagent.core :as reagent]
|
|
||||||
[status-im.contexts.wallet.account.style :as style]
|
[status-im.contexts.wallet.account.style :as style]
|
||||||
[status-im.contexts.wallet.account.tabs.view :as tabs]
|
[status-im.contexts.wallet.account.tabs.view :as tabs]
|
||||||
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
||||||
|
@ -21,14 +20,16 @@
|
||||||
(not watch-only?) (conj {:id :dapps :label (i18n/label :t/dapps) :accessibility-label :dapps})
|
(not watch-only?) (conj {:id :dapps :label (i18n/label :t/dapps) :accessibility-label :dapps})
|
||||||
true (conj {:id :about :label (i18n/label :t/about) :accessibility-label :about})))
|
true (conj {:id :about :label (i18n/label :t/about) :accessibility-label :about})))
|
||||||
|
|
||||||
|
(defn- change-tab [id] (rf/dispatch [:wallet/select-account-tab id]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [selected-tab (reagent/atom first-tab-id)]
|
(let [selected-tab (or (rf/sub [:wallet/account-tab]) first-tab-id)
|
||||||
(fn []
|
{:keys [name color formatted-balance watch-only?
|
||||||
(let [{:keys [name color formatted-balance
|
address]} (rf/sub [:wallet/current-viewing-account])
|
||||||
watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
|
||||||
customization-color (rf/sub [:profile/customization-color])]
|
customization-color (rf/sub [:profile/customization-color])]
|
||||||
(rn/use-unmount #(rf/dispatch [:wallet/close-account-page]))
|
(rn/use-mount
|
||||||
|
#(rf/dispatch [:wallet/fetch-activities-for-current-account address]))
|
||||||
[rn/view {:style {:flex 1}}
|
[rn/view {:style {:flex 1}}
|
||||||
[account-switcher/view
|
[account-switcher/view
|
||||||
{:type :wallet-networks
|
{:type :wallet-networks
|
||||||
|
@ -62,16 +63,16 @@
|
||||||
[quo/tabs
|
[quo/tabs
|
||||||
{:style style/tabs
|
{:style style/tabs
|
||||||
:size 32
|
:size 32
|
||||||
:default-active @selected-tab
|
:active-tab-id selected-tab
|
||||||
:data (tabs-data watch-only?)
|
:data (tabs-data watch-only?)
|
||||||
:on-change (rn/use-callback (fn [tab] (reset! selected-tab tab)))
|
:on-change change-tab
|
||||||
:scrollable? true
|
:scrollable? true
|
||||||
:scroll-on-press? true}]
|
:scroll-on-press? true}]
|
||||||
[tabs/view {:selected-tab @selected-tab}]
|
[tabs/view {:selected-tab selected-tab}]
|
||||||
(when (ff/enabled? ::ff/shell.jump-to)
|
(when (ff/enabled? ::ff/shell.jump-to)
|
||||||
[quo/floating-shell-button
|
[quo/floating-shell-button
|
||||||
{:jump-to
|
{:jump-to
|
||||||
{:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
|
{:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
|
||||||
:customization-color customization-color
|
:customization-color customization-color
|
||||||
:label (i18n/label :t/jump-to)}}
|
:label (i18n/label :t/jump-to)}}
|
||||||
style/shell-button])]))))
|
style/shell-button])]))
|
||||||
|
|
|
@ -7,5 +7,4 @@
|
||||||
:skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :bridge-to-chain-id])))}
|
:skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :bridge-to-chain-id])))}
|
||||||
{:screen-id :screen/wallet.bridge-input-amount
|
{:screen-id :screen/wallet.bridge-input-amount
|
||||||
:skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :amount])))}
|
:skip-step? (fn [db] (some? (get-in db [:wallet :ui :send :amount])))}
|
||||||
{:screen-id :screen/wallet.transaction-confirmation}
|
{:screen-id :screen/wallet.transaction-confirmation}])
|
||||||
{:screen-id :screen/wallet.transaction-progress}])
|
|
||||||
|
|
|
@ -49,6 +49,7 @@
|
||||||
:on-press #(rf/dispatch
|
:on-press #(rf/dispatch
|
||||||
[:wallet/set-collectible-to-send
|
[:wallet/set-collectible-to-send
|
||||||
{:collectible collectible
|
{:collectible collectible
|
||||||
|
:start-flow? true
|
||||||
:current-screen :screen/wallet.collectible}])}
|
:current-screen :screen/wallet.collectible}])}
|
||||||
(i18n/label :t/send)])
|
(i18n/label :t/send)])
|
||||||
[quo/button
|
[quo/button
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
:on-press on-press
|
:on-press on-press
|
||||||
:accessibility-label accessibility-label
|
:accessibility-label accessibility-label
|
||||||
:networks networks
|
:networks networks
|
||||||
|
:align-center? true
|
||||||
:networks-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}])
|
:networks-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}])
|
||||||
:right-side [(when (and (ff/enabled? ::ff/wallet.wallet-connect)
|
:right-side [(when (and (ff/enabled? ::ff/wallet.wallet-connect)
|
||||||
(not watch-only?))
|
(not watch-only?))
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
(ns status-im.contexts.wallet.common.activity-tab.events
|
||||||
|
(:require [camel-snake-kebab.extras :as cske]
|
||||||
|
[utils.ethereum.chain :as chain]
|
||||||
|
[utils.re-frame :as rf]
|
||||||
|
[utils.transforms :as transforms]))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:wallet/fetch-activities-for-current-account
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
(let [address (-> db :wallet :current-viewing-account-address)
|
||||||
|
chain-ids (chain/chain-ids db)
|
||||||
|
request-id 0
|
||||||
|
filters {:period {:startTimestamp 0
|
||||||
|
:endTimestamp 0}
|
||||||
|
:types []
|
||||||
|
:statuses []
|
||||||
|
:counterpartyAddresses []
|
||||||
|
:assets []
|
||||||
|
:collectibles []
|
||||||
|
:filterOutAssets false
|
||||||
|
:filterOutCollectibles false}
|
||||||
|
offset 0
|
||||||
|
limit 35
|
||||||
|
request-params [request-id [address] chain-ids filters offset limit]]
|
||||||
|
{:fx [[:json-rpc/call
|
||||||
|
[{;; This method is deprecated and will be replaced by
|
||||||
|
;; "wallet_startActivityFilterSession"
|
||||||
|
;; https://github.com/status-im/status-mobile/issues/19864
|
||||||
|
:method "wallet_filterActivityAsync"
|
||||||
|
:params request-params
|
||||||
|
:on-error [:wallet/log-rpc-error
|
||||||
|
{:event :wallet/fetch-activities-for-current-account
|
||||||
|
:params request-params}]}]]]})))
|
||||||
|
|
||||||
|
(rf/reg-event-fx
|
||||||
|
:wallet/activity-filtering-for-current-account-done
|
||||||
|
(fn [{:keys [db]} [{:keys [message]}]]
|
||||||
|
(let [address (-> db :wallet :current-viewing-account-address)
|
||||||
|
activities (->> message
|
||||||
|
(transforms/json->clj)
|
||||||
|
(:activities)
|
||||||
|
(cske/transform-keys transforms/->kebab-case-keyword))
|
||||||
|
sorted-activities (sort :timestamp activities)]
|
||||||
|
{:db (assoc-in db [:wallet :activities address] sorted-activities)})))
|
|
@ -1,61 +1,42 @@
|
||||||
(ns status-im.contexts.wallet.common.activity-tab.view
|
(ns status-im.contexts.wallet.common.activity-tab.view
|
||||||
(:require
|
(:require
|
||||||
[legacy.status-im.utils.hex :as utils.hex]
|
|
||||||
[native-module.core :as native-module]
|
|
||||||
[quo.core :as quo]
|
[quo.core :as quo]
|
||||||
[quo.foundations.resources :as quo.resources]
|
|
||||||
[quo.theme]
|
[quo.theme]
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[status-im.common.resources :as resources]
|
[status-im.common.resources :as resources]
|
||||||
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
|
[status-im.contexts.shell.jump-to.constants :as jump-to.constants]
|
||||||
[status-im.contexts.wallet.common.activity-tab.constants :as constants]
|
|
||||||
[status-im.contexts.wallet.common.empty-tab.view :as empty-tab]
|
[status-im.contexts.wallet.common.empty-tab.view :as empty-tab]
|
||||||
[utils.datetime :as datetime]
|
|
||||||
[utils.ethereum.chain :as chain]
|
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.money :as money]
|
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(def precision 6)
|
(defn send-and-receive-activity
|
||||||
|
[{:keys [transaction relative-date status sender recipient token amount network-name
|
||||||
(defn activity-item
|
network-logo]}]
|
||||||
[{:keys [activity-type activity-status timestamp symbol-out symbol-in token-in token-out amount-in
|
|
||||||
amount-out sender recipient]}]
|
|
||||||
(let [chain-id (or (:chain-id token-in) (:chain-id token-out))
|
|
||||||
amount-in-units (native-module/hex-to-number
|
|
||||||
(utils.hex/normalize-hex amount-in))
|
|
||||||
amount-in-value (str (money/with-precision
|
|
||||||
(money/wei->ether amount-in-units)
|
|
||||||
precision))
|
|
||||||
amount-out-units (native-module/hex-to-number
|
|
||||||
(utils.hex/normalize-hex amount-out))
|
|
||||||
amount-out-value (str (money/with-precision
|
|
||||||
(money/wei->ether amount-out-units)
|
|
||||||
precision))
|
|
||||||
relative-date (datetime/timestamp->relative (* timestamp 1000))
|
|
||||||
receiving-activity? (= activity-type constants/wallet-activity-type-receive)]
|
|
||||||
[quo/wallet-activity
|
[quo/wallet-activity
|
||||||
{:transaction (constants/wallet-activity-id->name activity-type)
|
{:transaction transaction
|
||||||
:timestamp relative-date
|
:timestamp relative-date
|
||||||
:status (constants/wallet-activity-status->name activity-status)
|
:status status
|
||||||
:counter 1
|
:counter 1
|
||||||
:first-tag {:size 24
|
:first-tag {:size 24
|
||||||
:type :token
|
:type :token
|
||||||
:token (or symbol-out symbol-in)
|
:token token
|
||||||
:amount (if receiving-activity? amount-in-value amount-out-value)}
|
:amount amount}
|
||||||
:second-tag-prefix (constants/second-tag-prefix activity-type)
|
:second-tag-prefix :t/from
|
||||||
:second-tag {:type :address
|
:second-tag {:type :address :address sender}
|
||||||
:address (if receiving-activity? recipient sender)}
|
:third-tag-prefix :t/to
|
||||||
:third-tag-prefix (constants/third-tag-prefix activity-type)
|
:third-tag {:type :address :address recipient}
|
||||||
:third-tag {:type :address
|
:fourth-tag-prefix :t/via
|
||||||
:address (if receiving-activity? sender recipient)}
|
|
||||||
:fourth-tag-prefix (constants/fourth-tag-prefix activity-type)
|
|
||||||
:fourth-tag {:size 24
|
:fourth-tag {:size 24
|
||||||
:type :network
|
:type :network
|
||||||
:network-logo (quo.resources/get-network (chain/chain-id->chain-keyword
|
:network-name network-name
|
||||||
chain-id))
|
:network-logo network-logo}
|
||||||
:network-name (chain/chain-id->chain-name chain-id)}
|
:blur? false}])
|
||||||
:blur? false}]))
|
|
||||||
|
(defn activity-item
|
||||||
|
[{:keys [transaction] :as activity}]
|
||||||
|
(case transaction
|
||||||
|
(:send :receive) [send-and-receive-activity activity]
|
||||||
|
nil))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
|
@ -69,7 +50,8 @@
|
||||||
[rn/section-list
|
[rn/section-list
|
||||||
{:sections activity-list
|
{:sections activity-list
|
||||||
:sticky-section-headers-enabled false
|
:sticky-section-headers-enabled false
|
||||||
:style {:flex 1}
|
:style {:flex 1
|
||||||
|
:padding-horizontal 8}
|
||||||
:content-container-style {:padding-bottom jump-to.constants/floating-shell-button-height}
|
:content-container-style {:padding-bottom jump-to.constants/floating-shell-button-height}
|
||||||
:render-fn activity-item
|
:render-fn activity-item
|
||||||
:render-section-header-fn (fn [{:keys [title]}] [quo/divider-date title])}])))
|
:render-section-header-fn (fn [{:keys [title]}] [quo/divider-date title])}])))
|
||||||
|
|
|
@ -72,8 +72,10 @@
|
||||||
selected-account? (rf/sub [:wallet/current-viewing-account-address])
|
selected-account? (rf/sub [:wallet/current-viewing-account-address])
|
||||||
send-params (if selected-account?
|
send-params (if selected-account?
|
||||||
{:token token-data
|
{:token token-data
|
||||||
|
:stack-id :screen/wallet.accounts
|
||||||
:start-flow? true}
|
:start-flow? true}
|
||||||
{:token-symbol token-symbol
|
{:token-symbol token-symbol
|
||||||
|
:stack-id :wallet-stack
|
||||||
:start-flow? true})]
|
:start-flow? true})]
|
||||||
[quo/action-drawer
|
[quo/action-drawer
|
||||||
[(cond->> [(when (ff/enabled? ::ff/wallet.assets-modal-manage-tokens)
|
[(cond->> [(when (ff/enabled? ::ff/wallet.assets-modal-manage-tokens)
|
||||||
|
|
|
@ -79,7 +79,7 @@
|
||||||
:on-success (fn [value]
|
:on-success (fn [value]
|
||||||
(resolver {:value value}))}))))
|
(resolver {:value value}))}))))
|
||||||
|
|
||||||
(defn import-keypair-by-seed-phrase
|
(defn import-missing-keypair-by-seed-phrase
|
||||||
[keypair-key-uid seed-phrase password]
|
[keypair-key-uid seed-phrase password]
|
||||||
(-> (validate-mnemonic seed-phrase)
|
(-> (validate-mnemonic seed-phrase)
|
||||||
(promesa/then
|
(promesa/then
|
||||||
|
@ -87,20 +87,20 @@
|
||||||
(if (not= keypair-key-uid key-uid)
|
(if (not= keypair-key-uid key-uid)
|
||||||
(promesa/rejected
|
(promesa/rejected
|
||||||
(ex-info
|
(ex-info
|
||||||
(error-message :import-keypair-by-seed-phrase/import-error)
|
(error-message :import-missing-keypair-by-seed-phrase/import-error)
|
||||||
{:hint :incorrect-seed-phrase-for-keypair}))
|
{:hint :incorrect-seed-phrase-for-keypair}))
|
||||||
(make-seed-phrase-fully-operable seed-phrase password))))
|
(make-seed-phrase-fully-operable seed-phrase password))))
|
||||||
(promesa/catch
|
(promesa/catch
|
||||||
(fn [error]
|
(fn [error]
|
||||||
(promesa/rejected
|
(promesa/rejected
|
||||||
(ex-info
|
(ex-info
|
||||||
(error-message :import-keypair-by-seed-phrase/import-error)
|
(error-message :import-missing-keypair-by-seed-phrase/import-error)
|
||||||
(ex-data error)))))))
|
(ex-data error)))))))
|
||||||
|
|
||||||
(rf/reg-fx
|
(rf/reg-fx
|
||||||
:import-keypair-by-seed-phrase
|
:effects.wallet/import-missing-keypair-by-seed-phrase
|
||||||
(fn [{:keys [keypair-key-uid seed-phrase password on-success on-error]}]
|
(fn [{:keys [keypair-key-uid seed-phrase password on-success on-error]}]
|
||||||
(-> (import-keypair-by-seed-phrase keypair-key-uid seed-phrase password)
|
(-> (import-missing-keypair-by-seed-phrase keypair-key-uid seed-phrase password)
|
||||||
(promesa/then (partial rf/call-continuation on-success))
|
(promesa/then (partial rf/call-continuation on-success))
|
||||||
(promesa/catch (partial rf/call-continuation on-error)))))
|
(promesa/catch (partial rf/call-continuation on-error)))))
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
[status-im.constants :as constants]
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.settings.wallet.effects]
|
[status-im.contexts.settings.wallet.effects]
|
||||||
[status-im.contexts.settings.wallet.events]
|
[status-im.contexts.settings.wallet.events]
|
||||||
|
[status-im.contexts.wallet.common.activity-tab.events]
|
||||||
[status-im.contexts.wallet.common.utils.external-links :as external-links]
|
[status-im.contexts.wallet.common.utils.external-links :as external-links]
|
||||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||||
[status-im.contexts.wallet.data-store :as data-store]
|
[status-im.contexts.wallet.data-store :as data-store]
|
||||||
|
@ -35,6 +36,12 @@
|
||||||
(fn [{:keys [db]} [address]]
|
(fn [{:keys [db]} [address]]
|
||||||
{:db (assoc-in db [:wallet :current-viewing-account-address] address)
|
{:db (assoc-in db [:wallet :current-viewing-account-address] address)
|
||||||
:fx [[:dispatch [:navigate-to :screen/wallet.accounts address]]
|
:fx [[:dispatch [:navigate-to :screen/wallet.accounts address]]
|
||||||
|
[:dispatch [:wallet/fetch-activities-for-current-account]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/navigate-to-account-within-stack
|
||||||
|
(fn [{:keys [db]} [address]]
|
||||||
|
{:db (assoc-in db [:wallet :current-viewing-account-address] address)
|
||||||
|
:fx [[:dispatch [:navigate-to-within-stack [:screen/wallet.accounts :shell-stack] address]]
|
||||||
[:dispatch [:wallet/fetch-activities]]]}))
|
[:dispatch [:wallet/fetch-activities]]]}))
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/navigate-to-new-account
|
(rf/reg-event-fx :wallet/navigate-to-new-account
|
||||||
|
@ -44,6 +51,14 @@
|
||||||
[:dispatch [:navigate-to :screen/wallet.accounts address]]
|
[:dispatch [:navigate-to :screen/wallet.accounts address]]
|
||||||
[:dispatch [:wallet/show-account-created-toast address]]]}))
|
[:dispatch [:wallet/show-account-created-toast address]]]}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/select-account-tab
|
||||||
|
(fn [{:keys [db]} [tab]]
|
||||||
|
{:db (assoc-in db [:wallet :ui :account-page :active-tab] tab)}))
|
||||||
|
|
||||||
|
(rf/reg-event-fx :wallet/clear-account-tab
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
{:db (assoc-in db [:wallet :ui :account-page :active-tab] nil)}))
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/switch-current-viewing-account
|
(rf/reg-event-fx :wallet/switch-current-viewing-account
|
||||||
(fn [{:keys [db]} [address]]
|
(fn [{:keys [db]} [address]]
|
||||||
{:db (assoc-in db [:wallet :current-viewing-account-address] address)}))
|
{:db (assoc-in db [:wallet :current-viewing-account-address] address)}))
|
||||||
|
@ -55,6 +70,7 @@
|
||||||
(rf/reg-event-fx :wallet/close-account-page
|
(rf/reg-event-fx :wallet/close-account-page
|
||||||
(fn [_]
|
(fn [_]
|
||||||
{:fx [[:dispatch [:wallet/clean-current-viewing-account]]
|
{:fx [[:dispatch [:wallet/clean-current-viewing-account]]
|
||||||
|
[:dispatch [:wallet/clear-account-tab]]
|
||||||
[:dispatch [:pop-to-root :shell-stack]]]}))
|
[:dispatch [:pop-to-root :shell-stack]]]}))
|
||||||
|
|
||||||
(defn log-rpc-error
|
(defn log-rpc-error
|
||||||
|
@ -491,49 +507,6 @@
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/update-selected-networks update-selected-networks)
|
(rf/reg-event-fx :wallet/update-selected-networks update-selected-networks)
|
||||||
|
|
||||||
(rf/reg-event-fx
|
|
||||||
:wallet/fetch-activities
|
|
||||||
(fn [{:keys [db]}]
|
|
||||||
(let [addresses (->> (get-in db [:wallet :accounts])
|
|
||||||
vals
|
|
||||||
(map :address))
|
|
||||||
chain-ids (chain/chain-ids db)
|
|
||||||
request-id 0
|
|
||||||
filters {:period {:startTimestamp 0
|
|
||||||
:endTimestamp 0}
|
|
||||||
:types []
|
|
||||||
:statuses []
|
|
||||||
:counterpartyAddresses []
|
|
||||||
:assets []
|
|
||||||
:collectibles []
|
|
||||||
:filterOutAssets false
|
|
||||||
:filterOutCollectibles false}
|
|
||||||
offset 0
|
|
||||||
limit 20
|
|
||||||
request-params [request-id
|
|
||||||
addresses
|
|
||||||
chain-ids
|
|
||||||
filters
|
|
||||||
offset
|
|
||||||
limit]]
|
|
||||||
{:fx [[:json-rpc/call
|
|
||||||
[{;; This method is deprecated and will be replaced by
|
|
||||||
;; "wallet_startActivityFilterSession"
|
|
||||||
;; https://github.com/status-im/status-mobile/issues/19864
|
|
||||||
:method "wallet_filterActivityAsync"
|
|
||||||
:params request-params
|
|
||||||
:on-error [:wallet/log-rpc-error
|
|
||||||
{:event :wallet/fetch-activities
|
|
||||||
:params request-params}]}]]]})))
|
|
||||||
|
|
||||||
(rf/reg-event-fx
|
|
||||||
:wallet/activity-filtering-done
|
|
||||||
(fn [{:keys [db]} [{:keys [message]}]]
|
|
||||||
(let [{:keys [activities]} (transforms/json->clj message)
|
|
||||||
activities (cske/transform-keys transforms/->kebab-case-keyword activities)
|
|
||||||
sorted-activities (sort :timestamp activities)]
|
|
||||||
{:db (assoc-in db [:wallet :activities] sorted-activities)})))
|
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:wallet/get-crypto-on-ramps-success
|
:wallet/get-crypto-on-ramps-success
|
||||||
(fn [{:keys [db]} [data]]
|
(fn [{:keys [db]} [data]]
|
||||||
|
|
|
@ -253,7 +253,7 @@
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
:wallet/set-collectible-to-send
|
:wallet/set-collectible-to-send
|
||||||
(fn [{db :db} [{:keys [collectible current-screen]}]]
|
(fn [{db :db} [{:keys [collectible current-screen start-flow?]}]]
|
||||||
(let [collection-data (:collection-data collectible)
|
(let [collection-data (:collection-data collectible)
|
||||||
collectible-data (:collectible-data collectible)
|
collectible-data (:collectible-data collectible)
|
||||||
contract-type (:contract-type collectible)
|
contract-type (:contract-type collectible)
|
||||||
|
@ -282,6 +282,7 @@
|
||||||
[:dispatch
|
[:dispatch
|
||||||
[:wallet/wizard-navigate-forward
|
[:wallet/wizard-navigate-forward
|
||||||
{:current-screen current-screen
|
{:current-screen current-screen
|
||||||
|
:start-flow? start-flow?
|
||||||
:flow-id :wallet-send-flow}]]]})))
|
:flow-id :wallet-send-flow}]]]})))
|
||||||
|
|
||||||
(rf/reg-event-fx
|
(rf/reg-event-fx
|
||||||
|
@ -447,18 +448,26 @@
|
||||||
(assoc-in [:wallet :transactions] transaction-details)
|
(assoc-in [:wallet :transactions] transaction-details)
|
||||||
(assoc-in [:wallet :ui :send :transaction-ids] transaction-ids))
|
(assoc-in [:wallet :ui :send :transaction-ids] transaction-ids))
|
||||||
:fx [[:dispatch
|
:fx [[:dispatch
|
||||||
[:wallet/wizard-navigate-forward
|
[:wallet/end-transaction-flow]]]})))
|
||||||
{:current-screen :screen/wallet.transaction-confirmation
|
|
||||||
:flow-id :wallet-send-flow}]]]})))
|
|
||||||
|
|
||||||
(rf/reg-event-fx :wallet/close-transaction-progress-page
|
(rf/reg-event-fx :wallet/clean-up-transaction-flow
|
||||||
(fn [_]
|
(fn [_]
|
||||||
{:fx [[:dispatch [:wallet/clean-scanned-address]]
|
{:fx [[:dispatch [:dismiss-modal :screen/wallet.transaction-confirmation]]
|
||||||
|
[:dispatch [:wallet/clean-scanned-address]]
|
||||||
[:dispatch [:wallet/clean-local-suggestions]]
|
[:dispatch [:wallet/clean-local-suggestions]]
|
||||||
[:dispatch [:wallet/clean-send-address]]
|
[:dispatch [:wallet/clean-send-address]]
|
||||||
[:dispatch [:wallet/clean-disabled-from-networks]]
|
[:dispatch [:wallet/clean-disabled-from-networks]]
|
||||||
[:dispatch [:wallet/select-address-tab nil]]
|
[:dispatch [:wallet/select-address-tab nil]]]}))
|
||||||
[:dispatch [:dismiss-modal :screen/wallet.transaction-progress]]]}))
|
|
||||||
|
(rf/reg-event-fx :wallet/end-transaction-flow
|
||||||
|
(fn [{:keys [db]}]
|
||||||
|
(let [address (get-in db [:wallet :current-viewing-account-address])]
|
||||||
|
{:fx [[:dispatch [:wallet/navigate-to-account-within-stack address]]
|
||||||
|
[:dispatch [:wallet/fetch-activities]]
|
||||||
|
[:dispatch [:wallet/select-account-tab :activity]]
|
||||||
|
[:dispatch-later
|
||||||
|
[{:ms 20
|
||||||
|
:dispatch [:wallet/clean-up-transaction-flow]}]]]})))
|
||||||
|
|
||||||
(defn- transaction-data
|
(defn- transaction-data
|
||||||
[{:keys [from-address to-address token-address route data eth-transfer?]}]
|
[{:keys [from-address to-address token-address route data eth-transfer?]}]
|
||||||
|
|
|
@ -27,5 +27,4 @@
|
||||||
:skip-step? (fn [db]
|
:skip-step? (fn [db]
|
||||||
(or (not (collectible-selected? db))
|
(or (not (collectible-selected? db))
|
||||||
(some? (get-in db [:wallet :ui :send :amount]))))}
|
(some? (get-in db [:wallet :ui :send :amount]))))}
|
||||||
{:screen-id :screen/wallet.transaction-confirmation}
|
{:screen-id :screen/wallet.transaction-confirmation}])
|
||||||
{:screen-id :screen/wallet.transaction-progress}])
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
(defn- on-press
|
(defn- on-account-press
|
||||||
[address network-details]
|
[address network-details]
|
||||||
(rf/dispatch [:wallet/select-from-account
|
(rf/dispatch [:wallet/select-from-account
|
||||||
{:address address
|
{:address address
|
||||||
|
@ -22,15 +22,19 @@
|
||||||
(rf/dispatch [:navigate-back]))
|
(rf/dispatch [:navigate-back]))
|
||||||
|
|
||||||
(defn- render-fn
|
(defn- render-fn
|
||||||
[item]
|
[item _ _ {:keys [network-details]}]
|
||||||
(let [network-details (rf/sub [:wallet/network-details])]
|
(let [transformed-address (rf/sub [:wallet/account-address (:address item)
|
||||||
|
(:network-preferences-names item)])]
|
||||||
[quo/account-item
|
[quo/account-item
|
||||||
{:on-press #(on-press (:address item) network-details)
|
{:on-press #(on-account-press (:address item) network-details)
|
||||||
:account-props item}]))
|
:account-props (assoc item
|
||||||
|
:address transformed-address
|
||||||
|
:full-address? true)}]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [accounts (rf/sub [:wallet/accounts-with-current-asset])]
|
(let [accounts (rf/sub [:wallet/accounts-with-current-asset])
|
||||||
|
network-details (rf/sub [:wallet/network-details])]
|
||||||
[floating-button-page/view
|
[floating-button-page/view
|
||||||
{:footer-container-padding 0
|
{:footer-container-padding 0
|
||||||
:header [account-switcher/view
|
:header [account-switcher/view
|
||||||
|
@ -45,5 +49,6 @@
|
||||||
{:style style/accounts-list
|
{:style style/accounts-list
|
||||||
:content-container-style style/accounts-list-container
|
:content-container-style style/accounts-list-container
|
||||||
:data accounts
|
:data accounts
|
||||||
|
:render-data {:network-details network-details}
|
||||||
:render-fn render-fn
|
:render-fn render-fn
|
||||||
:shows-horizontal-scroll-indicator false}]]))
|
:shows-horizontal-scroll-indicator false}]]))
|
||||||
|
|
|
@ -7,11 +7,13 @@
|
||||||
[react-native.core :as rn]
|
[react-native.core :as rn]
|
||||||
[react-native.safe-area :as safe-area]
|
[react-native.safe-area :as safe-area]
|
||||||
[status-im.common.controlled-input.utils :as controlled-input]
|
[status-im.common.controlled-input.utils :as controlled-input]
|
||||||
|
[status-im.constants :as constants]
|
||||||
[status-im.contexts.wallet.common.account-switcher.view :as account-switcher]
|
[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.asset-list.view :as asset-list]
|
||||||
[status-im.contexts.wallet.common.utils :as utils]
|
[status-im.contexts.wallet.common.utils :as utils]
|
||||||
[status-im.contexts.wallet.send.input-amount.style :as style]
|
[status-im.contexts.wallet.send.input-amount.style :as style]
|
||||||
[status-im.contexts.wallet.send.routes.view :as routes]
|
[status-im.contexts.wallet.send.routes.view :as routes]
|
||||||
|
[status-im.contexts.wallet.sheets.buy-token.view :as buy-token]
|
||||||
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
|
[status-im.contexts.wallet.sheets.unpreferred-networks-alert.view :as unpreferred-networks-alert]
|
||||||
[utils.debounce :as debounce]
|
[utils.debounce :as debounce]
|
||||||
[utils.i18n :as i18n]
|
[utils.i18n :as i18n]
|
||||||
|
@ -125,6 +127,15 @@
|
||||||
:style {:margin-top 15}}
|
:style {:margin-top 15}}
|
||||||
(i18n/label :t/no-routes-found)]])
|
(i18n/label :t/no-routes-found)]])
|
||||||
|
|
||||||
|
(defn- not-enough-asset
|
||||||
|
[]
|
||||||
|
[quo/alert-banner
|
||||||
|
{:action? true
|
||||||
|
:text (i18n/label :t/not-enough-assets)
|
||||||
|
:button-text (i18n/label :t/buy-eth)
|
||||||
|
:on-button-press #(rf/dispatch [:show-bottom-sheet
|
||||||
|
{:content buy-token/view}])}])
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed
|
;; crypto-decimals, limit-crypto and initial-crypto-currency? args are needed
|
||||||
;; for component tests only
|
;; for component tests only
|
||||||
|
@ -264,7 +275,25 @@
|
||||||
limit-insufficient? (> (controlled-input/numeric-value input-state)
|
limit-insufficient? (> (controlled-input/numeric-value input-state)
|
||||||
current-limit)
|
current-limit)
|
||||||
should-try-again? (and (not limit-insufficient?) no-routes-found?)
|
should-try-again? (and (not limit-insufficient?) no-routes-found?)
|
||||||
current-address (rf/sub [:wallet/current-viewing-account-address])]
|
current-address (rf/sub [:wallet/current-viewing-account-address])
|
||||||
|
owned-eth-token (rf/sub [:wallet/token-by-symbol
|
||||||
|
(string/upper-case
|
||||||
|
constants/mainnet-short-name)
|
||||||
|
enabled-from-chain-ids])
|
||||||
|
not-enough-asset? (and
|
||||||
|
(or no-routes-found? limit-insufficient?)
|
||||||
|
(not-empty sender-network-values)
|
||||||
|
(if (= token-symbol
|
||||||
|
(string/upper-case
|
||||||
|
constants/mainnet-short-name))
|
||||||
|
(= current-limit input-amount)
|
||||||
|
(money/equal-to (:total-balance
|
||||||
|
owned-eth-token)
|
||||||
|
0)))
|
||||||
|
show-no-routes? (and
|
||||||
|
(or no-routes-found? limit-insufficient?)
|
||||||
|
(not-empty sender-network-values)
|
||||||
|
(not not-enough-asset?))]
|
||||||
(rn/use-mount
|
(rn/use-mount
|
||||||
(fn []
|
(fn []
|
||||||
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
(let [dismiss-keyboard-fn #(when (= % "active") (rn/dismiss-keyboard!))
|
||||||
|
@ -339,8 +368,9 @@
|
||||||
{:loading-routes? loading-routes?
|
{:loading-routes? loading-routes?
|
||||||
:fees fee-formatted
|
:fees fee-formatted
|
||||||
:amount amount-text}])
|
:amount amount-text}])
|
||||||
(when (and (or no-routes-found? limit-insufficient?) (not-empty sender-network-values))
|
(cond
|
||||||
[no-routes-found])
|
show-no-routes? [no-routes-found]
|
||||||
|
not-enough-asset? [not-enough-asset])
|
||||||
[quo/bottom-actions
|
[quo/bottom-actions
|
||||||
{:actions :one-action
|
{:actions :one-action
|
||||||
:button-one-label (if should-try-again?
|
:button-one-label (if should-try-again?
|
||||||
|
|
|
@ -17,15 +17,21 @@
|
||||||
:description (i18n/label :t/here-is-a-cat-in-a-box-instead)
|
:description (i18n/label :t/here-is-a-cat-in-a-box-instead)
|
||||||
:image (resources/get-themed-image :cat-in-box theme)
|
:image (resources/get-themed-image :cat-in-box theme)
|
||||||
:container-style style/empty-container-style}]
|
:container-style style/empty-container-style}]
|
||||||
(into [rn/view {:style style/my-accounts-container}]
|
[rn/view {:style style/my-accounts-container}
|
||||||
(map (fn [{:keys [color address] :as account}]
|
(doall
|
||||||
|
(for [{:keys [color address] :as account} other-accounts]
|
||||||
|
^{:key (str address)}
|
||||||
|
(let [transformed-address (rf/sub [:wallet/account-address address
|
||||||
|
(:network-preferences-names account)])]
|
||||||
[quo/account-item
|
[quo/account-item
|
||||||
{:account-props (assoc account :customization-color color)
|
{:account-props (assoc account
|
||||||
|
:customization-color color
|
||||||
|
:address transformed-address
|
||||||
|
:full-address? true)
|
||||||
:on-press #(rf/dispatch [:wallet/select-send-address
|
:on-press #(rf/dispatch [:wallet/select-send-address
|
||||||
{:address address
|
{:address address
|
||||||
:recipient account
|
:recipient account
|
||||||
:stack-id :screen/wallet.select-address}])}]))
|
:stack-id :screen/wallet.select-address}])}])))])))
|
||||||
other-accounts))))
|
|
||||||
|
|
||||||
(defn- recent-transactions
|
(defn- recent-transactions
|
||||||
[theme]
|
[theme]
|
||||||
|
@ -46,16 +52,56 @@
|
||||||
:stack-id :screen/wallet.select-address}])}]))
|
:stack-id :screen/wallet.select-address}])}]))
|
||||||
recent-recipients))))
|
recent-recipients))))
|
||||||
|
|
||||||
|
(defn- saved-address
|
||||||
|
[{:keys [name address chain-short-names customization-color ens? ens]}]
|
||||||
|
(let [full-address (str chain-short-names address)
|
||||||
|
on-press-saved-address (rn/use-callback
|
||||||
|
#(rf/dispatch
|
||||||
|
[:wallet/select-send-address
|
||||||
|
{:address full-address
|
||||||
|
:recipient full-address
|
||||||
|
:stack-id :screen/wallet.select-address}])
|
||||||
|
[full-address])]
|
||||||
|
[quo/saved-address
|
||||||
|
{:user-props {:name name
|
||||||
|
:address full-address
|
||||||
|
:ens (when ens? ens)
|
||||||
|
:customization-color customization-color}
|
||||||
|
:container-style {:margin-horizontal 8}
|
||||||
|
:on-press on-press-saved-address}]))
|
||||||
|
|
||||||
|
(defn- saved-addresses
|
||||||
|
[theme]
|
||||||
|
(let [group-saved-addresses (rf/sub [:wallet/grouped-saved-addresses])
|
||||||
|
section-header (rn/use-callback
|
||||||
|
(fn [{:keys [title index]}]
|
||||||
|
[quo/divider-label
|
||||||
|
{:tight? true
|
||||||
|
:container-style (when (pos? index) {:margin-top 8})}
|
||||||
|
title]))
|
||||||
|
empty-state-component (rn/use-memo
|
||||||
|
(fn []
|
||||||
|
[quo/empty-state
|
||||||
|
{:title (i18n/label :t/no-saved-addresses)
|
||||||
|
:description (i18n/label
|
||||||
|
:t/you-like-to-type-43-characters)
|
||||||
|
:image (resources/get-themed-image :sweating-man
|
||||||
|
theme)}])
|
||||||
|
[theme])]
|
||||||
|
[rn/section-list
|
||||||
|
{:key-fn :title
|
||||||
|
:shows-vertical-scroll-indicator false
|
||||||
|
:render-section-header-fn section-header
|
||||||
|
:sections group-saved-addresses
|
||||||
|
:render-fn saved-address
|
||||||
|
:empty-component empty-state-component}]))
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[{:keys [selected-tab]}]
|
[{:keys [selected-tab]}]
|
||||||
(let [theme (quo.theme/use-theme)]
|
(let [theme (quo.theme/use-theme)]
|
||||||
(case selected-tab
|
(case selected-tab
|
||||||
:tab/recent [recent-transactions theme]
|
:tab/recent [recent-transactions theme]
|
||||||
:tab/saved [quo/empty-state
|
:tab/saved [saved-addresses theme]
|
||||||
{:title (i18n/label :t/no-saved-addresses)
|
|
||||||
:description (i18n/label :t/you-like-to-type-43-characters)
|
|
||||||
:image (resources/get-themed-image :sweating-man theme)
|
|
||||||
:container-style style/empty-container-style}]
|
|
||||||
:tab/contacts [quo/empty-state
|
:tab/contacts [quo/empty-state
|
||||||
{:title (i18n/label :t/no-contacts)
|
{:title (i18n/label :t/no-contacts)
|
||||||
:description (i18n/label :t/no-contacts-description)
|
:description (i18n/label :t/no-contacts-description)
|
||||||
|
|
|
@ -47,7 +47,7 @@
|
||||||
|
|
||||||
(defn view
|
(defn view
|
||||||
[]
|
[]
|
||||||
(let [leave-page #(rf/dispatch [:wallet/close-transaction-progress-page])
|
(let [leave-page #(rf/dispatch [:wallet/end-transaction-flow])
|
||||||
{:keys [color]} (rf/sub [:wallet/current-viewing-account])]
|
{:keys [color]} (rf/sub [:wallet/current-viewing-account])]
|
||||||
(fn []
|
(fn []
|
||||||
(rn/use-effect
|
(rn/use-effect
|
||||||
|
|
|
@ -37,7 +37,8 @@
|
||||||
"wallet-blockchain-status-changed" {:fx [[:dispatch
|
"wallet-blockchain-status-changed" {:fx [[:dispatch
|
||||||
[:wallet/blockchain-status-changed
|
[:wallet/blockchain-status-changed
|
||||||
(transforms/js->clj event-js)]]]}
|
(transforms/js->clj event-js)]]]}
|
||||||
"wallet-activity-filtering-done" {:fx [[:dispatch
|
"wallet-activity-filtering-done" {:fx
|
||||||
[:wallet/activity-filtering-done
|
[[:dispatch
|
||||||
|
[:wallet/activity-filtering-for-current-account-done
|
||||||
(transforms/js->clj event-js)]]]}
|
(transforms/js->clj event-js)]]]}
|
||||||
(log/debug ::unknown-wallet-event :type event-type)))))
|
(log/debug ::unknown-wallet-event :type event-type)))))
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
|
|
||||||
(rf/defn navigate-to-within-stack
|
(rf/defn navigate-to-within-stack
|
||||||
{:events [:navigate-to-within-stack]}
|
{:events [:navigate-to-within-stack]}
|
||||||
[{:keys [db]} comp-id]
|
[{:keys [db]} comp-id screen-params]
|
||||||
{:db (assoc db :view-id (first comp-id))
|
{:db (all-screens-params db (first comp-id) screen-params)
|
||||||
:fx [[:navigate-to-within-stack comp-id]]})
|
:fx [[:navigate-to-within-stack comp-id]]})
|
||||||
|
|
||||||
(re-frame/reg-event-fx :open-modal
|
(re-frame/reg-event-fx :open-modal
|
||||||
|
|
|
@ -57,14 +57,15 @@
|
||||||
[status-im.contexts.profile.settings.screens.password.change-password.view :as change-password]
|
[status-im.contexts.profile.settings.screens.password.change-password.view :as change-password]
|
||||||
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
|
[status-im.contexts.profile.settings.screens.password.view :as settings-password]
|
||||||
[status-im.contexts.profile.settings.view :as settings]
|
[status-im.contexts.profile.settings.view :as settings]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.encrypted-qr.view :as
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.encrypted-qr.view
|
||||||
encrypted-key-pair-qr]
|
:as encrypted-keypair-qr]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.import-private-key.view :as
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-private-key.view
|
||||||
import-private-key]
|
:as missing-keypairs.import-private-key]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.import-seed-phrase.view :as
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.import-seed-phrase.view
|
||||||
import-seed-phrase]
|
:as missing-keypairs.import-seed-phrase]
|
||||||
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.missing-keypairs.scan-qr.view
|
||||||
|
:as scan-keypair-qr]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.rename.view :as keypair-rename]
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.rename.view :as keypair-rename]
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.scan-qr.view :as scan-keypair-qr]
|
|
||||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
|
[status-im.contexts.settings.wallet.keypairs-and-accounts.view :as keypairs-and-accounts]
|
||||||
[status-im.contexts.settings.wallet.network-settings.view :as network-settings]
|
[status-im.contexts.settings.wallet.network-settings.view :as network-settings]
|
||||||
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.view :as
|
[status-im.contexts.settings.wallet.saved-addresses.add-address-to-save.view :as
|
||||||
|
@ -535,9 +536,9 @@
|
||||||
:options (assoc options/dark-screen :sheet? true)
|
:options (assoc options/dark-screen :sheet? true)
|
||||||
:component keypair-rename/view}
|
:component keypair-rename/view}
|
||||||
|
|
||||||
{:name :screen/settings.encrypted-key-pair-qr
|
{:name :screen/settings.encrypted-keypair-qr
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component encrypted-key-pair-qr/view}
|
:component encrypted-keypair-qr/view}
|
||||||
|
|
||||||
{:name :screen/settings.saved-addresses
|
{:name :screen/settings.saved-addresses
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
|
@ -551,13 +552,13 @@
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
:component scan-keypair-qr/view}
|
:component scan-keypair-qr/view}
|
||||||
|
|
||||||
{:name :screen/settings.import-seed-phrase
|
{:name :screen/settings.missing-keypair.import-seed-phrase
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component import-seed-phrase/view}
|
:component missing-keypairs.import-seed-phrase/view}
|
||||||
|
|
||||||
{:name :screen/settings.missing-keypair-import-private-key
|
{:name :screen/settings.missing-keypair-import-private-key
|
||||||
:options options/transparent-screen-options
|
:options options/transparent-screen-options
|
||||||
:component import-private-key/view}
|
:component missing-keypairs.import-private-key/view}
|
||||||
|
|
||||||
{:name :screen/settings.network-settings
|
{:name :screen/settings.network-settings
|
||||||
:options options/transparent-modal-screen-options
|
:options options/transparent-modal-screen-options
|
||||||
|
|
|
@ -1,26 +1,82 @@
|
||||||
(ns status-im.subs.wallet.activities
|
(ns status-im.subs.wallet.activities
|
||||||
(:require
|
(:require
|
||||||
|
[legacy.status-im.utils.hex :as utils.hex]
|
||||||
|
[native-module.core :as native-module]
|
||||||
|
[quo.foundations.resources :as quo.resources]
|
||||||
|
[quo.foundations.resources]
|
||||||
[re-frame.core :as rf]
|
[re-frame.core :as rf]
|
||||||
[status-im.contexts.wallet.common.activity-tab.constants :as constants]
|
[status-im.contexts.wallet.common.activity-tab.constants :as constants]
|
||||||
[utils.datetime :as datetime]))
|
[utils.datetime :as datetime]
|
||||||
|
[utils.money :as money]))
|
||||||
|
|
||||||
|
(def precision 6)
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/all-activities
|
:wallet/all-activities
|
||||||
:<- [:wallet]
|
:<- [:wallet]
|
||||||
:-> :activities)
|
:-> :activities)
|
||||||
|
|
||||||
(rf/reg-sub :wallet/activities-for-current-viewing-account
|
(defn- activity-amount
|
||||||
|
[amount]
|
||||||
|
(-> amount
|
||||||
|
(utils.hex/normalize-hex)
|
||||||
|
(native-module/hex-to-number)
|
||||||
|
(money/wei->ether)
|
||||||
|
(money/with-precision precision)
|
||||||
|
(str)))
|
||||||
|
|
||||||
|
(defn- process-send-activity
|
||||||
|
[{:keys [symbol-out chain-id-out amount-out]} activity chain-id->network-name]
|
||||||
|
(let [network-name (chain-id->network-name chain-id-out)]
|
||||||
|
(assoc activity
|
||||||
|
:transaction :send
|
||||||
|
:token symbol-out
|
||||||
|
:amount (activity-amount amount-out)
|
||||||
|
:network-name network-name
|
||||||
|
:network-logo (quo.resources/get-network network-name))))
|
||||||
|
|
||||||
|
(defn- process-receive-activity
|
||||||
|
[{:keys [symbol-in amount-in chain-id-in]} activity chain-id->network-name]
|
||||||
|
(let [network-name (chain-id->network-name chain-id-in)]
|
||||||
|
(assoc activity
|
||||||
|
:transaction :receive
|
||||||
|
:token symbol-in
|
||||||
|
:amount (activity-amount amount-in)
|
||||||
|
:network-name network-name
|
||||||
|
:network-logo (quo.resources/get-network network-name))))
|
||||||
|
|
||||||
|
(defn- process-activity-by-type
|
||||||
|
[chain-id->network-name
|
||||||
|
{:keys [activity-type activity-status timestamp sender recipient] :as data}]
|
||||||
|
(let [activity {:relative-date (datetime/timestamp->relative (* timestamp 1000))
|
||||||
|
:timestamp timestamp
|
||||||
|
:status (constants/wallet-activity-status->name activity-status)
|
||||||
|
:sender sender
|
||||||
|
:recipient recipient}]
|
||||||
|
(condp = activity-type
|
||||||
|
constants/wallet-activity-type-send
|
||||||
|
(process-send-activity data activity chain-id->network-name)
|
||||||
|
|
||||||
|
constants/wallet-activity-type-receive
|
||||||
|
(process-receive-activity data activity chain-id->network-name)
|
||||||
|
|
||||||
|
nil)))
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/activities-for-current-viewing-account
|
||||||
:<- [:wallet/all-activities]
|
:<- [:wallet/all-activities]
|
||||||
:<- [:wallet/current-viewing-account-address]
|
:<- [:wallet/current-viewing-account-address]
|
||||||
(fn [[activities current-viewing-account-address]]
|
:<- [:wallet/network-details]
|
||||||
(->> activities
|
(fn [[activities current-viewing-account-address network-details]]
|
||||||
(filter (fn [{:keys [sender recipient activity-type]}]
|
(let [chain-id->network-name (update-vals (group-by :chain-id network-details)
|
||||||
(let [receiving-activity? (= activity-type constants/wallet-activity-type-receive)
|
(comp :network-name first))]
|
||||||
relevant-address (if receiving-activity? recipient sender)]
|
(->> current-viewing-account-address
|
||||||
(= relevant-address current-viewing-account-address))))
|
(get activities)
|
||||||
(distinct)
|
(keep #(process-activity-by-type chain-id->network-name %))
|
||||||
(group-by (fn [{:keys [timestamp]}]
|
(group-by (fn [{:keys [timestamp]}]
|
||||||
(datetime/timestamp->relative-short-date (* timestamp 1000))))
|
(datetime/timestamp->relative-short-date (* timestamp 1000))))
|
||||||
(map (fn [[date activities]]
|
(map (fn [[date activities]]
|
||||||
{:title date :data activities :timestamp (:timestamp (first activities))}))
|
{:title date
|
||||||
(sort-by (fn [{:keys [timestamp]}] (- timestamp))))))
|
:data activities
|
||||||
|
:timestamp (:timestamp (first activities))}))
|
||||||
|
(sort-by (fn [{:keys [timestamp]}] (- timestamp)))))))
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
(:require
|
(:require
|
||||||
[cljs.test :refer [is testing]]
|
[cljs.test :refer [is testing]]
|
||||||
[re-frame.db :as rf-db]
|
[re-frame.db :as rf-db]
|
||||||
status-im.subs.root
|
[status-im.contexts.wallet.common.activity-tab.constants :as constants]
|
||||||
status-im.subs.wallet.collectibles
|
[status-im.subs.root]
|
||||||
|
[status-im.subs.wallet.collectibles]
|
||||||
[test-helpers.unit :as h]
|
[test-helpers.unit :as h]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -14,7 +15,7 @@
|
||||||
[:wallet :activities]
|
[:wallet :activities]
|
||||||
[{:id 1 :name "Transaction1"}
|
[{:id 1 :name "Transaction1"}
|
||||||
{:id 2 :name "Transaction2"}])
|
{:id 2 :name "Transaction2"}])
|
||||||
(is (= [{:id 1 :name "Transaction1"} {:id 2 :name "Transaction2"}] (rf/sub [sub-name])))))
|
(is (match? [{:id 1 :name "Transaction1"} {:id 2 :name "Transaction2"}] (rf/sub [sub-name])))))
|
||||||
|
|
||||||
(h/deftest-sub :wallet/activities-for-current-viewing-account
|
(h/deftest-sub :wallet/activities-for-current-viewing-account
|
||||||
[sub-name]
|
[sub-name]
|
||||||
|
@ -23,11 +24,62 @@
|
||||||
(fn [db]
|
(fn [db]
|
||||||
(-> db
|
(-> db
|
||||||
(assoc-in [:wallet :activities]
|
(assoc-in [:wallet :activities]
|
||||||
[{:sender "acc1" :recipient "acc2" :timestamp 1588291200}
|
{"acc1" [{:activity-type constants/wallet-activity-type-send
|
||||||
{:sender "acc2" :recipient "acc1" :timestamp 1588377600}
|
:amount-out "0x1"
|
||||||
{:sender "acc3" :recipient "acc4" :timestamp 1588464000}])
|
:sender "acc1"
|
||||||
|
:recipient "acc2"
|
||||||
|
:timestamp 1588291200}
|
||||||
|
{:activity-type constants/wallet-activity-type-receive
|
||||||
|
:amount-in "0x1"
|
||||||
|
:sender "acc2"
|
||||||
|
:recipient "acc1"
|
||||||
|
:timestamp 1588377600}
|
||||||
|
{:activity-type constants/wallet-activity-type-send
|
||||||
|
:amount-out "0x1"
|
||||||
|
:sender "acc1"
|
||||||
|
:recipient "acc4"
|
||||||
|
:timestamp 1588464000}]
|
||||||
|
"acc3" [{:activity-type constants/wallet-activity-type-receive
|
||||||
|
:amount-in "0x1"
|
||||||
|
:sender "acc4"
|
||||||
|
:recipient "acc3"
|
||||||
|
:timestamp 1588464000}]})
|
||||||
(assoc-in [:wallet :current-viewing-account-address] "acc1"))))
|
(assoc-in [:wallet :current-viewing-account-address] "acc1"))))
|
||||||
(is (= [{:title "May 1, 2020"
|
(is
|
||||||
:data [{:sender "acc1" :recipient "acc2" :timestamp 1588291200}]
|
(match? [{:title "May 3, 2020"
|
||||||
:timestamp 1588291200}]
|
:timestamp 1588464000
|
||||||
|
:data [{:relative-date "May 3, 2020"
|
||||||
|
:amount "0"
|
||||||
|
:network-logo nil
|
||||||
|
:recipient "acc4"
|
||||||
|
:transaction :send
|
||||||
|
:token nil
|
||||||
|
:network-name nil
|
||||||
|
:status nil
|
||||||
|
:sender "acc1"
|
||||||
|
:timestamp 1588464000}]}
|
||||||
|
{:title "May 2, 2020"
|
||||||
|
:timestamp 1588377600
|
||||||
|
:data [{:relative-date "May 2, 2020"
|
||||||
|
:amount "0"
|
||||||
|
:network-logo nil
|
||||||
|
:recipient "acc1"
|
||||||
|
:transaction :receive
|
||||||
|
:token nil
|
||||||
|
:network-name nil
|
||||||
|
:status nil
|
||||||
|
:sender "acc2"
|
||||||
|
:timestamp 1588377600}]}
|
||||||
|
{:title "May 1, 2020"
|
||||||
|
:timestamp 1588291200
|
||||||
|
:data [{:relative-date "May 1, 2020"
|
||||||
|
:amount "0"
|
||||||
|
:network-logo nil
|
||||||
|
:recipient "acc2"
|
||||||
|
:transaction :send
|
||||||
|
:token nil
|
||||||
|
:network-name nil
|
||||||
|
:status nil
|
||||||
|
:sender "acc1"
|
||||||
|
:timestamp 1588291200}]}]
|
||||||
(rf/sub [sub-name])))))
|
(rf/sub [sub-name])))))
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
(ns status-im.subs.wallet.networks
|
(ns status-im.subs.wallet.networks
|
||||||
(:require [quo.foundations.resources :as resources]
|
(:require [quo.foundations.resources :as resources]
|
||||||
[re-frame.core :as re-frame]
|
[re-frame.core :as re-frame]
|
||||||
[status-im.constants :as constants]))
|
[status-im.constants :as constants]
|
||||||
|
[status-im.contexts.wallet.common.utils.networks :as network-utils]))
|
||||||
|
|
||||||
|
(def max-network-prefixes 2)
|
||||||
|
|
||||||
(re-frame/reg-sub
|
(re-frame/reg-sub
|
||||||
:wallet/networks
|
:wallet/networks
|
||||||
|
@ -88,3 +91,13 @@
|
||||||
(filter
|
(filter
|
||||||
#(contains? selected-networks (:network-name %))
|
#(contains? selected-networks (:network-name %))
|
||||||
network-details)))
|
network-details)))
|
||||||
|
|
||||||
|
(re-frame/reg-sub
|
||||||
|
:wallet/account-address
|
||||||
|
(fn [_ [_ address network-preferences]]
|
||||||
|
(let [short-names (map network-utils/network->short-name network-preferences)
|
||||||
|
prefix (when (<= (count short-names) max-network-prefixes)
|
||||||
|
(network-utils/short-names->network-preference-prefix
|
||||||
|
short-names))
|
||||||
|
transformed-address (str prefix address)]
|
||||||
|
transformed-address)))
|
||||||
|
|
|
@ -82,3 +82,14 @@
|
||||||
:chain-id 10
|
:chain-id 10
|
||||||
:layer 2}}
|
:layer 2}}
|
||||||
(rf/sub [sub-name])))))
|
(rf/sub [sub-name])))))
|
||||||
|
|
||||||
|
(h/deftest-sub :wallet/account-address
|
||||||
|
[sub-name]
|
||||||
|
(testing
|
||||||
|
"returns the address with prefixes when an address and less than 3 network preferences are passed"
|
||||||
|
(is
|
||||||
|
(match? "eth:0x01" (rf/sub [sub-name "0x01" [:ethereum]]))))
|
||||||
|
(testing
|
||||||
|
"returns the address without the prefixes when an address and equal or more than 3 network preferences are passed"
|
||||||
|
(is
|
||||||
|
(match? "0x01" (rf/sub [sub-name "0x01" [:ethereum :optimism :arbitrum]])))))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
(ns status-im.subs.wallet.send
|
(ns status-im.subs.wallet.send
|
||||||
(:require
|
(:require
|
||||||
[re-frame.core :as rf]
|
[re-frame.core :as rf]
|
||||||
|
[status-im.contexts.wallet.common.activity-tab.constants :as constants]
|
||||||
[utils.number]))
|
[utils.number]))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
|
@ -40,14 +41,15 @@
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/recent-recipients
|
:wallet/recent-recipients
|
||||||
:<- [:wallet/activities-for-current-viewing-account]
|
:<- [:wallet/all-activities]
|
||||||
:<- [:wallet/current-viewing-account-address]
|
:<- [:wallet/current-viewing-account-address]
|
||||||
(fn [[sections current-viewing-account-address]]
|
(fn [[all-activities current-viewing-account-address]]
|
||||||
(let [all-transactions (mapcat :data sections)
|
(let [address-activity (get all-activities current-viewing-account-address)]
|
||||||
users-sent-transactions (filter (fn [{:keys [sender]}]
|
(->> address-activity
|
||||||
(= sender current-viewing-account-address))
|
(keep (fn [{:keys [activity-type recipient]}]
|
||||||
all-transactions)]
|
(when (= constants/wallet-activity-type-send activity-type)
|
||||||
(set (map :recipient users-sent-transactions)))))
|
recipient)))
|
||||||
|
(distinct)))))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/send-token-not-supported-in-receiver-networks?
|
:wallet/send-token-not-supported-in-receiver-networks?
|
||||||
|
|
|
@ -2,8 +2,9 @@
|
||||||
(:require
|
(:require
|
||||||
[cljs.test :refer [is testing]]
|
[cljs.test :refer [is testing]]
|
||||||
[re-frame.db :as rf-db]
|
[re-frame.db :as rf-db]
|
||||||
status-im.subs.root
|
[status-im.contexts.wallet.common.activity-tab.constants :as constants]
|
||||||
status-im.subs.wallet.send
|
[status-im.subs.root]
|
||||||
|
[status-im.subs.wallet.send]
|
||||||
[test-helpers.unit :as h]
|
[test-helpers.unit :as h]
|
||||||
[utils.re-frame :as rf]))
|
[utils.re-frame :as rf]))
|
||||||
|
|
||||||
|
@ -61,8 +62,25 @@
|
||||||
(fn [db]
|
(fn [db]
|
||||||
(-> db
|
(-> db
|
||||||
(assoc-in [:wallet :activities]
|
(assoc-in [:wallet :activities]
|
||||||
[{:sender "acc1" :recipient "acc2" :timestamp 1588291200}
|
{"acc1" [{:activity-type constants/wallet-activity-type-send
|
||||||
{:sender "acc2" :recipient "acc1" :timestamp 1588377600}
|
:amount-out "0x1"
|
||||||
{:sender "acc3" :recipient "acc4" :timestamp 1588464000}])
|
:sender "acc1"
|
||||||
|
:recipient "acc2"
|
||||||
|
:timestamp 1588291200}
|
||||||
|
{:activity-type constants/wallet-activity-type-receive
|
||||||
|
:amount-in "0x1"
|
||||||
|
:sender "acc2"
|
||||||
|
:recipient "acc1"
|
||||||
|
:timestamp 1588377600}
|
||||||
|
{:activity-type constants/wallet-activity-type-send
|
||||||
|
:amount-out "0x1"
|
||||||
|
:sender "acc1"
|
||||||
|
:recipient "acc4"
|
||||||
|
:timestamp 1588464000}]
|
||||||
|
"acc3" [{:activity-type constants/wallet-activity-type-receive
|
||||||
|
:amount-in "0x1"
|
||||||
|
:sender "acc4"
|
||||||
|
:recipient "acc3"
|
||||||
|
:timestamp 1588464000}]})
|
||||||
(assoc-in [:wallet :current-viewing-account-address] "acc1"))))
|
(assoc-in [:wallet :current-viewing-account-address] "acc1"))))
|
||||||
(is (= #{"acc2"} (rf/sub [sub-name])))))
|
(is (match? ["acc2" "acc4"] (rf/sub [sub-name])))))
|
||||||
|
|
|
@ -260,21 +260,21 @@
|
||||||
:<- [:wallet/keypairs]
|
:<- [:wallet/keypairs]
|
||||||
(fn [keypairs [_ format-options]]
|
(fn [keypairs [_ format-options]]
|
||||||
(let [grouped-keypairs (group-by :lowest-operability keypairs)
|
(let [grouped-keypairs (group-by :lowest-operability keypairs)
|
||||||
operable-key-pair-ids (->> (concat (:fully grouped-keypairs)
|
operable-keypair-ids (->> (concat (:fully grouped-keypairs)
|
||||||
(:partially grouped-keypairs))
|
(:partially grouped-keypairs))
|
||||||
(map :key-uid)
|
(map :key-uid)
|
||||||
(into #{}))
|
(into #{}))
|
||||||
missing-key-pair-ids (->> (map :key-uid (:no grouped-keypairs))
|
missing-keypair-ids (->> (map :key-uid (:no grouped-keypairs))
|
||||||
(into #{}))]
|
(into #{}))]
|
||||||
{:operable (->> keypairs
|
{:operable (->> keypairs
|
||||||
(filter #(contains? operable-key-pair-ids (:key-uid %)))
|
(filter #(contains? operable-keypair-ids (:key-uid %)))
|
||||||
(map (fn [{:keys [accounts name type key-uid]}]
|
(map (fn [{:keys [accounts name type key-uid]}]
|
||||||
{:type (keyword type)
|
{:type (keyword type)
|
||||||
:name name
|
:name name
|
||||||
:key-uid key-uid
|
:key-uid key-uid
|
||||||
:accounts (format-settings-keypair-accounts accounts format-options)})))
|
:accounts (format-settings-keypair-accounts accounts format-options)})))
|
||||||
:missing (->> keypairs
|
:missing (->> keypairs
|
||||||
(filter #(contains? missing-key-pair-ids (:key-uid %)))
|
(filter #(contains? missing-keypair-ids (:key-uid %)))
|
||||||
(map (fn [{:keys [accounts name type key-uid]}]
|
(map (fn [{:keys [accounts name type key-uid]}]
|
||||||
{:type (keyword type)
|
{:type (keyword type)
|
||||||
:name name
|
:name name
|
||||||
|
@ -435,6 +435,12 @@
|
||||||
accounts)
|
accounts)
|
||||||
accounts))))
|
accounts))))
|
||||||
|
|
||||||
|
(rf/reg-sub
|
||||||
|
:wallet/account-tab
|
||||||
|
:<- [:wallet/ui]
|
||||||
|
(fn [ui]
|
||||||
|
(get-in ui [:account-page :active-tab])))
|
||||||
|
|
||||||
(rf/reg-sub
|
(rf/reg-sub
|
||||||
:wallet/current-viewing-account-token-values
|
:wallet/current-viewing-account-token-values
|
||||||
:<- [:wallet/current-viewing-account]
|
:<- [:wallet/current-viewing-account]
|
||||||
|
|
|
@ -1587,6 +1587,7 @@
|
||||||
"seed-phrase-words-uppercase": "Recovery phrase cannot contain uppercase characters",
|
"seed-phrase-words-uppercase": "Recovery phrase cannot contain uppercase characters",
|
||||||
"seed-phrase-error": "Recovery phrase contains invalid words",
|
"seed-phrase-error": "Recovery phrase contains invalid words",
|
||||||
"seed-phrase-invalid": "Invalid recovery phrase",
|
"seed-phrase-invalid": "Invalid recovery phrase",
|
||||||
|
"seed-phrase-incorrect": "Recovery phrase does not match key pair",
|
||||||
"seed-phrase-info": "Enter 12, 18 or 24 words separated by spaces",
|
"seed-phrase-info": "Enter 12, 18 or 24 words separated by spaces",
|
||||||
"word-count": "Word count",
|
"word-count": "Word count",
|
||||||
"word-n": "Word #{{number}}",
|
"word-n": "Word #{{number}}",
|
||||||
|
@ -1629,6 +1630,7 @@
|
||||||
"ok-save-pass": "OK, save password",
|
"ok-save-pass": "OK, save password",
|
||||||
"lock-app-with": "Lock app with",
|
"lock-app-with": "Lock app with",
|
||||||
"grant-face-id-permissions": "To grant the required Face ID permission, please go to your system settings and make sure that Status > Face ID is selected",
|
"grant-face-id-permissions": "To grant the required Face ID permission, please go to your system settings and make sure that Status > Face ID is selected",
|
||||||
|
"grant-fingerprints-permissions": "To grant the required fingerprints permission, please go to your system settings and make sure that Status > Fingerprints is selected",
|
||||||
"request-feature": "Request a feature",
|
"request-feature": "Request a feature",
|
||||||
"select-account-dapp": "Select the account you wish to use with Dapps",
|
"select-account-dapp": "Select the account you wish to use with Dapps",
|
||||||
"apply": "Apply",
|
"apply": "Apply",
|
||||||
|
@ -2658,7 +2660,7 @@
|
||||||
"import-private-key-info": "New addresses cannot be derived from an account imported from a private key. Import using a seed phrase if you wish to derive addresses.",
|
"import-private-key-info": "New addresses cannot be derived from an account imported from a private key. Import using a seed phrase if you wish to derive addresses.",
|
||||||
"invalid-private-key": "It’s not a valid private key",
|
"invalid-private-key": "It’s not a valid private key",
|
||||||
"correct-private-key": "Correct private key",
|
"correct-private-key": "Correct private key",
|
||||||
"incorrect-private-key": "This is not the private key for {{name}}",
|
"incorrect-private-key": "This is not the private key for this key pair",
|
||||||
"private-key-public-address": "Public address of private key",
|
"private-key-public-address": "Public address of private key",
|
||||||
"this-account-has-no-activity": "This account has no activity",
|
"this-account-has-no-activity": "This account has no activity",
|
||||||
"this-address-has-activity": "This address has activity",
|
"this-address-has-activity": "This address has activity",
|
||||||
|
@ -2699,5 +2701,7 @@
|
||||||
"wallet-connect-version-not-supported": "WalletConnect version {{version}} is not supported",
|
"wallet-connect-version-not-supported": "WalletConnect version {{version}} is not supported",
|
||||||
"add-network-preferences": "Add network preferences",
|
"add-network-preferences": "Add network preferences",
|
||||||
"saved-address-network-preference-selection-description": "Only change if you know which networks the address owner is happy to to receive funds on",
|
"saved-address-network-preference-selection-description": "Only change if you know which networks the address owner is happy to to receive funds on",
|
||||||
"add-preferences": "Add preferences"
|
"add-preferences": "Add preferences",
|
||||||
|
"buy-eth": "Buy ETH",
|
||||||
|
"not-enough-assets": "Not enough assets to pay gas fees"
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue