Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0d9bedf11c | ||
|
|
3e268936f6 | ||
|
|
e92da6d24b | ||
|
|
34c95c42d1 | ||
|
|
1ee44259c4 | ||
|
|
112b69c1d6 | ||
|
|
3ce6a86e9b | ||
|
|
b005eb8181 | ||
|
|
4bd7abaace | ||
|
|
e2e8afb7b1 | ||
|
|
256f3f8f24 | ||
|
|
6931fd0052 | ||
|
|
136c3c0032 | ||
|
|
a92b50afea | ||
|
|
fd3a21a320 | ||
|
|
f93e372d18 | ||
|
|
0ed39a42ef | ||
|
|
ead51b7e7c | ||
|
|
9481890624 | ||
|
|
419e84db08 | ||
|
|
66785d01ec | ||
|
|
1cc4807336 | ||
|
|
141252e5a0 | ||
|
|
9d825ee04e | ||
|
|
fb84f105db | ||
|
|
f509d132f3 | ||
|
|
5ee5d70567 | ||
|
|
b5a09a334a |
@@ -2,7 +2,7 @@
|
||||
name: MVPBug Report
|
||||
about: MVPBug Report
|
||||
title: ''
|
||||
labels: 'E:Mobile Bug MVP'
|
||||
labels: ['E:Mobile Bug MVP', ':1234: low prio']
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
@@ -70,3 +70,19 @@ Documentation change PR (review please): https://github.com/status-im/status.im/
|
||||
| Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. | Please embed Image/Video here of the before and after. |
|
||||
|
||||
status: ready <!-- Can be ready or wip -->
|
||||
|
||||
<!-- Uncomment this section for status-go upgrade/dogfooding pull requests
|
||||
|
||||
- Specify potentially impacted user flows in _Areas that maybe impacted*.
|
||||
- Ensure that _Steps to test_ is filled in.
|
||||
|
||||
### Risk
|
||||
|
||||
Described potential risks and worst case scenarios.
|
||||
|
||||
Tick **one**:
|
||||
- [ ] Low risk: 2 devs MUST perform testing as specified above and attach their results as comments to this PR **before** merging.
|
||||
- [ ] High risk: QA team MUST perform additional testing in the specified affected areas **before** merging.
|
||||
|
||||
|
||||
-->
|
||||
|
||||
@@ -447,6 +447,16 @@ android-devices: export TARGET := android-sdk
|
||||
android-devices: ##@other Invoke adb devices
|
||||
adb devices
|
||||
|
||||
android-pull-geth: export TARGET := android-sdk
|
||||
android-pull-geth: export VERSION ?= debug
|
||||
android-pull-geth:
|
||||
adb pull "/storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log"
|
||||
|
||||
android-tail-geth: export TARGET := android-sdk
|
||||
android-tail-geth: export VERSION ?= debug
|
||||
android-tail-geth:
|
||||
adb shell 'while true; do cat; sleep 1; done < /storage/emulated/0/Android/data/im.status.ethereum$$( [ "$(VERSION)" = "release" ] || echo ".$(VERSION)" )/files/Download/geth.log'
|
||||
|
||||
android-logcat: export TARGET := android-sdk
|
||||
android-logcat: ##@other Read status-mobile logs from Android phone using adb
|
||||
adb logcat | grep -e RNBootstrap -e ReactNativeJS -e ReactNative -e StatusModule -e StatusNativeLogs -e 'F DEBUG :' -e 'Go :' -e 'GoLog :' -e 'libc :'
|
||||
|
||||
@@ -119,8 +119,6 @@
|
||||
<array>
|
||||
<string>armv7</string>
|
||||
</array>
|
||||
<key>UIStatusBarStyle</key>
|
||||
<string>UIStatusBarStyleLightContent</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
@@ -133,7 +131,7 @@
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<true/>
|
||||
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
|
||||
<array>
|
||||
<string>A00000080400010101</string>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 MiB After Width: | Height: | Size: 1.4 MiB |
Binary file not shown.
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.8 MiB |
+2
-1
@@ -131,7 +131,8 @@
|
||||
:output-dir "target/test"
|
||||
:optimizations :simple
|
||||
:target :node-test
|
||||
:dev {:devtools {:preloads [status-im.setup.schema-preload]}}
|
||||
:dev {:devtools {:preloads [status-im.setup.schema-preload
|
||||
status-im.setup.test-preload]}}
|
||||
;; Uncomment line below to `make test-watch` a specific file
|
||||
:ns-regexp #shadow/env "SHADOW_NS_REGEXP"
|
||||
:main legacy.status-im.test-runner/main
|
||||
|
||||
@@ -38,10 +38,12 @@
|
||||
:always
|
||||
(update :contacts conj (:id member))))
|
||||
|
||||
(defn community-chat-id->channel-id [chat-id] (subs chat-id constants/community-id-length))
|
||||
|
||||
(defn decode-chat-id
|
||||
[chat-id]
|
||||
(let [community-id (subs chat-id 0 constants/community-id-length)
|
||||
channel-id (subs chat-id constants/community-id-length)]
|
||||
channel-id (community-chat-id->channel-id chat-id)]
|
||||
{:community-id community-id
|
||||
:channel-id channel-id}))
|
||||
|
||||
|
||||
@@ -135,7 +135,8 @@
|
||||
(>= (- now app-in-background-since)
|
||||
constants/ms-in-bg-for-require-bioauth))]
|
||||
(rf/merge cofx
|
||||
{:db (dissoc db :app-in-background-since)}
|
||||
{:db (dissoc db :app-in-background-since)
|
||||
:effects.biometric/get-supported-type nil}
|
||||
(mailserver/process-next-messages-request)
|
||||
(when-not new-account?
|
||||
(universal-links/process-stored-event))
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
[{:keys [db] :as cofx} {:keys [auth-method logout?]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
(rf/merge cofx
|
||||
{:set-root :progress
|
||||
{:dispatch [:init-root :progress]
|
||||
:effects.shell/reset-state nil
|
||||
:hide-popover nil
|
||||
::logout nil
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[quo.core :as quo]
|
||||
[react-native.platform :as platform]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -57,7 +58,15 @@
|
||||
:accessibility-label :local-notifications-settings-button
|
||||
:subtitle (i18n/label :t/local-notifications-subtitle)
|
||||
:active notifications-enabled?
|
||||
:on-press #(rf/dispatch [:push-notifications/switch (not notifications-enabled?)])
|
||||
:on-press (fn []
|
||||
(when-not notifications-enabled?
|
||||
(rf/dispatch
|
||||
[:request-permissions
|
||||
{:permissions [:post-notifications]
|
||||
:on-allowed #(log/info "push notification permissions were allowed")
|
||||
:on-denied #(log/error
|
||||
"user denied push notification permissions")}]))
|
||||
(rf/dispatch [:push-notifications/switch (not notifications-enabled?)]))
|
||||
:accessory :switch}]]))
|
||||
|
||||
(defn notifications-settings
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
[]
|
||||
[;;PROGRESS
|
||||
{:name :progress
|
||||
:options {:insets {:top? true}}
|
||||
:options {:insets {:top? true}
|
||||
:theme :dark}
|
||||
:component progress/progress}
|
||||
|
||||
;;COMMUNITY
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(defn drag-gesture
|
||||
[x-pos disabled? track-width sliding-complete?
|
||||
set-sliding-complete
|
||||
on-complete reset-fn]
|
||||
[x-pos disabled? track-width sliding-complete? set-sliding-complete on-complete reset-fn]
|
||||
(-> (gesture/gesture-pan)
|
||||
(gesture/with-test-ID :slide-button-gestures)
|
||||
(gesture/enabled (not disabled?))
|
||||
@@ -71,14 +69,16 @@
|
||||
(dimensions :thumb))
|
||||
[dimensions])
|
||||
custom-color (if (= type :danger) :danger customization-color)
|
||||
gesture (rn/use-memo #(drag-gesture x-pos
|
||||
disabled?
|
||||
(dimensions :usable-track)
|
||||
sliding-complete?
|
||||
set-sliding-complete
|
||||
on-complete
|
||||
reset-fn)
|
||||
[sliding-complete? disabled?])]
|
||||
gesture (rn/use-memo
|
||||
(fn []
|
||||
(drag-gesture x-pos
|
||||
disabled?
|
||||
(dimensions :usable-track)
|
||||
sliding-complete?
|
||||
set-sliding-complete
|
||||
on-complete
|
||||
reset-fn))
|
||||
[sliding-complete? disabled? on-complete])]
|
||||
[gesture/gesture-detector
|
||||
{:gesture gesture}
|
||||
[reanimated/view
|
||||
|
||||
@@ -8,10 +8,11 @@
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- get-icon-color
|
||||
[danger? theme]
|
||||
(if danger?
|
||||
(colors/theme-colors colors/danger-50 colors/danger-60 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
[blur? danger? theme]
|
||||
(cond
|
||||
danger? (colors/theme-colors colors/danger-50 colors/danger-60 theme)
|
||||
blur? colors/white-opa-70
|
||||
:else (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(defn- divider
|
||||
[theme blur?]
|
||||
@@ -51,7 +52,7 @@
|
||||
:accessible true
|
||||
:style (style/left-icon sub-label)}
|
||||
[icon/icon icon
|
||||
{:color (or icon-color (get-icon-color danger? theme))
|
||||
{:color (or icon-color (get-icon-color blur? danger? theme))
|
||||
:no-color no-icon-color?
|
||||
:size 20}]])
|
||||
[rn/view
|
||||
@@ -84,7 +85,7 @@
|
||||
:accessible true
|
||||
:accessibility-label :right-icon-for-action}
|
||||
[icon/icon right-icon
|
||||
{:color (get-icon-color danger? theme)
|
||||
{:color (get-icon-color blur? danger? theme)
|
||||
:size 20}]])
|
||||
(when (= state :selected)
|
||||
[rn/view {:style style/right-icon}
|
||||
|
||||
@@ -20,8 +20,9 @@
|
||||
{:background-color (when-not (or scroll? blur?)
|
||||
(colors/theme-colors colors/white colors/neutral-95 theme))})
|
||||
|
||||
(def buttons-container
|
||||
{:flex-direction :row
|
||||
(defn buttons-container
|
||||
[actions]
|
||||
{:flex-direction (if (= actions :two-vertical-actions) :column :row)
|
||||
:justify-content :space-around
|
||||
:padding-vertical 12
|
||||
:gap 12
|
||||
|
||||
@@ -17,9 +17,9 @@
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:actions [:maybe [:enum :one-action :two-actions]]]
|
||||
[:actions [:maybe [:enum :one-action :two-actions :two-vertical-actions]]]
|
||||
[:description {:optional true} [:maybe [:enum :top :bottom :top-error]]]
|
||||
[:description-text {:optional true} [:maybe :string]]
|
||||
[:description-text {:optional true} [:maybe [:or :string :schema.common/hiccup]]]
|
||||
[:description-top-text {:optional true} [:maybe :string]]
|
||||
[:error-message {:optional true} [:maybe :string]]
|
||||
[:role {:optional true} [:maybe [:enum :admin :member :token-master :owner]]]
|
||||
@@ -72,8 +72,9 @@
|
||||
:context (i18n/label (keyword "t" role))}
|
||||
context-tag-props)]])
|
||||
|
||||
[rn/view {:style style/buttons-container}
|
||||
(when (= actions :two-actions)
|
||||
[rn/view {:style (style/buttons-container actions)}
|
||||
(when (or (= actions :two-actions)
|
||||
(= actions :two-vertical-actions))
|
||||
[button/button
|
||||
(merge
|
||||
{:size 40
|
||||
@@ -93,8 +94,10 @@
|
||||
button-one-props)
|
||||
button-one-label]]
|
||||
(when (= description :bottom)
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (style/description-bottom scroll? blur? theme)} description-text])]))
|
||||
(if (string? description-text)
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (style/description-bottom scroll? blur? theme)} description-text]
|
||||
description-text))]))
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
(defn- left-image
|
||||
[{:keys [type customization-color account-avatar-emoji account-avatar-type icon-avatar
|
||||
profile-picture]}]
|
||||
profile-picture blur?]}]
|
||||
(case type
|
||||
:account [account-avatar/view
|
||||
{:customization-color customization-color
|
||||
@@ -28,6 +28,7 @@
|
||||
:keypair [icon-avatar/icon-avatar
|
||||
{:icon icon-avatar
|
||||
:border? true
|
||||
:blur? blur?
|
||||
:color :neutral}]
|
||||
|
||||
:default-keypair [user-avatar/user-avatar
|
||||
@@ -213,6 +214,7 @@
|
||||
[rn/view {:style style/left-container}
|
||||
[left-image
|
||||
{:type type
|
||||
:blur? blur?
|
||||
:customization-color customization-color
|
||||
:account-avatar-emoji account-avatar-emoji
|
||||
:account-avatar-type account-avatar-type
|
||||
|
||||
@@ -31,7 +31,8 @@
|
||||
:size :paragraph-2}
|
||||
(:name account-props)]
|
||||
[address-text/view
|
||||
{:networks networks
|
||||
{:blur? blur?
|
||||
:networks networks
|
||||
:address (:address account-props)
|
||||
:format :short}]]]
|
||||
(when (= action :icon)
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
|
||||
(def container-info
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
:align-items :center
|
||||
:flex 1})
|
||||
|
||||
(def user-info
|
||||
{:margin-left 8})
|
||||
|
||||
@@ -25,14 +25,16 @@
|
||||
:style {:width 32 :height 32}}]
|
||||
[rn/view {:style style/user-info}
|
||||
[text/text
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:style (style/style-text-name theme)}
|
||||
{:weight :semi-bold
|
||||
:size :paragraph-1
|
||||
:number-of-lines 1
|
||||
:style (style/style-text-name theme)}
|
||||
(:name dapp)]
|
||||
[text/text
|
||||
{:weight :regular
|
||||
:size :paragraph-2
|
||||
:style (style/style-text-value theme)}
|
||||
{:weight :regular
|
||||
:size :paragraph-2
|
||||
:number-of-lines 1
|
||||
:style (style/style-text-value theme)}
|
||||
(:value dapp)]]]
|
||||
(when right-component
|
||||
[right-component dapp])]))
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
(defn- checkbox-border-unchecked-color
|
||||
[theme]
|
||||
{:normal (colors/theme-colors colors/neutral-30 colors/neutral-70 theme)
|
||||
:blur (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-40 theme)})
|
||||
:blur (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)})
|
||||
|
||||
(defn- filled-checkbox-background-color
|
||||
[theme]
|
||||
|
||||
@@ -51,3 +51,24 @@
|
||||
:right-icon :i/globe
|
||||
:chevron? true}]}])
|
||||
(h/is-truthy (h/get-by-text "subtitle"))))
|
||||
|
||||
(h/describe "Data Item Category tests"
|
||||
(h/test "category renders"
|
||||
(h/render [category/category
|
||||
{:list-type :data-item
|
||||
:label "Label"
|
||||
:data [{:title "Item 1"
|
||||
:subtitle "subtitle"
|
||||
:right-icon :i/globe}]}])
|
||||
(h/is-truthy (h/get-by-text "Label"))
|
||||
(h/is-truthy (h/get-by-text "Item 1"))
|
||||
(h/is-truthy (h/get-by-text "subtitle")))
|
||||
|
||||
(h/test "category renders without label"
|
||||
(h/render [category/category
|
||||
{:list-type :data-item
|
||||
:data [{:title "Item 1"
|
||||
:subtitle "subtitle"
|
||||
:right-icon :i/globe}]}])
|
||||
(h/is-falsy (h/query-by-label-text "Label"))
|
||||
(h/is-truthy (h/get-by-text "Item 1"))))
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
(ns quo.components.settings.category.data-item.view
|
||||
(:require
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.settings.category.style :as style]
|
||||
[quo.components.settings.data-item.view :as data-item]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn view
|
||||
[{:keys [label data container-style blur?]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
last-item (rn/use-memo #(last data) [data])]
|
||||
[rn/view {:style (merge (style/container label) container-style)}
|
||||
(when label
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/label blur? theme)}
|
||||
label])
|
||||
[rn/view {:style (style/settings-items blur? theme)}
|
||||
(for [item data
|
||||
;; NOTE: overwriting the background of the data-item in favor of the category bg
|
||||
:let [data-item-container-style (-> item :container-style (assoc :background-color nil))
|
||||
data-item-props (assoc item
|
||||
:blur? blur?
|
||||
:container-style data-item-container-style)]]
|
||||
^{:key item}
|
||||
[:<>
|
||||
[data-item/view data-item-props]
|
||||
(when-not (= item last-item)
|
||||
[rn/view {:style (style/settings-separator blur? theme)}])])]]))
|
||||
|
||||
@@ -7,20 +7,23 @@
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn settings-category
|
||||
[{:keys [label data container-style] :as props}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
settings-item (filter identity data)]
|
||||
[{:keys [label data blur? container-style]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
settings-items (remove nil? data)
|
||||
last-index (dec (count settings-items))]
|
||||
[rn/view {:style (merge (style/container label) container-style)}
|
||||
(when label
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/label props theme)}
|
||||
:style (style/label blur? theme)}
|
||||
label])
|
||||
[rn/view {:style (style/settings-items props theme)}
|
||||
(for [item settings-item]
|
||||
^{:key item}
|
||||
[:<>
|
||||
[settings-item/view item]
|
||||
(when-not (= item (last settings-item))
|
||||
[rn/view {:style (style/settings-separator props theme)}])])]]))
|
||||
[rn/view {:style (style/settings-items blur? theme)}
|
||||
(map-indexed
|
||||
(fn [index item]
|
||||
^{:key (str label (:title item))}
|
||||
[:<>
|
||||
[settings-item/view item]
|
||||
(when-not (= last-index index)
|
||||
[rn/view {:style (style/settings-separator blur? theme)}])])
|
||||
settings-items)]]))
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
:padding-bottom 8})
|
||||
|
||||
(defn settings-items
|
||||
[{:keys [blur?]} theme]
|
||||
[blur? theme]
|
||||
{:border-radius 16
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
@@ -22,7 +22,7 @@
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
|
||||
|
||||
(defn label
|
||||
[{:keys [blur?]} theme]
|
||||
[blur? theme]
|
||||
{:margin-bottom 12
|
||||
:color (if blur?
|
||||
colors/white-opa-40
|
||||
@@ -32,7 +32,7 @@
|
||||
{:margin-top 12})
|
||||
|
||||
(defn settings-separator
|
||||
[{:keys [blur?]} theme]
|
||||
[blur? theme]
|
||||
{:height 1
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
(ns quo.components.settings.category.view
|
||||
(:require
|
||||
[quo.components.settings.category.data-item.view :as data-item]
|
||||
[quo.components.settings.category.reorder.view :as reorder]
|
||||
[quo.components.settings.category.settings.view :as settings]))
|
||||
|
||||
(defn category
|
||||
[{:keys [list-type] :as props}]
|
||||
(if (= list-type :settings)
|
||||
[settings/settings-category props]
|
||||
[reorder/reorder-category props]))
|
||||
(condp = list-type
|
||||
:settings [settings/settings-category props]
|
||||
:data-item [data-item/view props]
|
||||
:reorder [reorder/reorder-category props]
|
||||
nil))
|
||||
|
||||
@@ -116,7 +116,8 @@
|
||||
[rn/view {:style (style/left-container (:image props))}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:style {:color (when blur? colors/white)}} title]
|
||||
:style {:color (when blur? colors/white)}}
|
||||
title]
|
||||
[description-component props]
|
||||
[tag-component props]]]
|
||||
[rn/view {:style (style/sub-container (:alignment action-props))}
|
||||
|
||||
@@ -39,6 +39,12 @@
|
||||
(def avatar-container-rounded
|
||||
(assoc avatar-container-common :border-radius 16))
|
||||
|
||||
(def big-avatar-container-rounded
|
||||
(assoc avatar-container-common
|
||||
:width 84
|
||||
:height 84
|
||||
:border-radius 42))
|
||||
|
||||
(def community-logo-image
|
||||
{:width 64
|
||||
:height 64
|
||||
|
||||
@@ -13,8 +13,9 @@
|
||||
:as props}]
|
||||
[rn/view {:style style/avatar-overlay}
|
||||
[rn/view
|
||||
{:style (if (= avatar-type :wallet-account)
|
||||
style/avatar-container-rounded
|
||||
{:style (case avatar-type
|
||||
:wallet-account style/avatar-container-rounded
|
||||
:saved-address style/big-avatar-container-rounded
|
||||
style/avatar-container-circular)}
|
||||
(case avatar-type
|
||||
:profile
|
||||
@@ -37,7 +38,7 @@
|
||||
[channel-avatar/view (assoc props :locked? nil :size :size-64)]
|
||||
|
||||
:saved-address
|
||||
[wallet-avatar/wallet-user-avatar (assoc props :size :size-64)]
|
||||
[wallet-avatar/wallet-user-avatar (assoc props :size :size-80)]
|
||||
|
||||
nil)]])
|
||||
|
||||
|
||||
@@ -28,5 +28,10 @@
|
||||
:height 24
|
||||
:border-radius 12})
|
||||
|
||||
(def dapp
|
||||
{:width 24
|
||||
:height 24
|
||||
:border-radius 12})
|
||||
|
||||
(def token-image
|
||||
{:border-radius 12})
|
||||
|
||||
@@ -23,6 +23,10 @@
|
||||
[rn/image
|
||||
{:source image-source
|
||||
:style style/network}]
|
||||
:dapp
|
||||
[rn/image
|
||||
{:source image-source
|
||||
:style style/dapp}]
|
||||
:saved-address
|
||||
[wallet-user-avatar/wallet-user-avatar
|
||||
{:full-name label
|
||||
@@ -50,7 +54,7 @@
|
||||
- :label - string - tag label
|
||||
- :customization-color - color - It will be passed down to components that
|
||||
should vary based on a custom color.
|
||||
- :type - :token / :user / :collectible / :saved-address / :network / :account
|
||||
- :type - :token / :user / :collectible / :saved-address / :network / :account / :dapp
|
||||
- :emoji - string - emoji used for displaying account avatar
|
||||
- :image-source - resource - image to display on :network, :collectible and :user
|
||||
- :theme - :light / :dark"
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
[{:keys [blur? customization-color theme selected? container-style]}]
|
||||
(merge {:border-radius 16
|
||||
:border-width 1
|
||||
:border-color (if selected?
|
||||
(if blur?
|
||||
colors/white
|
||||
(colors/resolve-color customization-color theme))
|
||||
(if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme)))
|
||||
:padding-bottom 8}
|
||||
:padding-bottom 8
|
||||
:border-color (cond
|
||||
(and selected? blur?) colors/white
|
||||
selected? (colors/resolve-color customization-color theme)
|
||||
blur? colors/white-opa-5
|
||||
:else (colors/theme-colors colors/neutral-10
|
||||
colors/neutral-80
|
||||
theme))}
|
||||
container-style))
|
||||
|
||||
(def header-container
|
||||
|
||||
@@ -47,12 +47,13 @@
|
||||
:accessibility-label :title}
|
||||
[text/text {:weight :semi-bold}
|
||||
(if (= type :default-keypair) (keypair-string full-name) full-name)]
|
||||
(if (= action :selector)
|
||||
[selectors/view
|
||||
{:type :radio
|
||||
:checked? selected?
|
||||
:blur? blur?
|
||||
:customization-color customization-color}]
|
||||
(case action
|
||||
:none nil
|
||||
:selector [selectors/view
|
||||
{:type :radio
|
||||
:checked? selected?
|
||||
:blur? blur?
|
||||
:customization-color customization-color}]
|
||||
[rn/pressable {:on-press on-options-press}
|
||||
[icon/icon :i/options
|
||||
{:color (if blur?
|
||||
@@ -94,20 +95,23 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [accounts action container-style selected? on-press] :as props}]
|
||||
[rn/pressable
|
||||
{:style (style/container (merge props
|
||||
{:selected? selected?
|
||||
:container-style container-style}))
|
||||
:on-press #(when (= action :selector) (on-press))}
|
||||
[rn/view {:style style/header-container}
|
||||
[avatar props]
|
||||
[rn/view
|
||||
{:style {:margin-left 8
|
||||
:flex 1}}
|
||||
[title-view (assoc props :selected? selected?)]
|
||||
[details-view props]]]
|
||||
[rn/flat-list
|
||||
{:data accounts
|
||||
:render-fn acc-list-card
|
||||
:separator [rn/view {:style {:height 8}}]
|
||||
:style {:padding-horizontal 8}}]])
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/pressable
|
||||
{:style (style/container (assoc props
|
||||
:selected? selected?
|
||||
:container-style container-style
|
||||
:theme theme))
|
||||
:on-press #(when (= action :selector) (on-press))
|
||||
:pointer-events :box-only}
|
||||
[rn/view {:style style/header-container}
|
||||
[avatar props]
|
||||
[rn/view
|
||||
{:style {:margin-left 8
|
||||
:flex 1}}
|
||||
[title-view (assoc props :selected? selected?)]
|
||||
[details-view props]]]
|
||||
[rn/flat-list
|
||||
{:data accounts
|
||||
:render-fn acc-list-card
|
||||
:separator [rn/view {:style {:height 8}}]
|
||||
:style {:padding-horizontal 8}}]]))
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn title-view
|
||||
[{:keys [keypairs blur? on-import-press]}]
|
||||
[{:keys [keypairs blur? on-import-press show-import-all?]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view
|
||||
{:accessibility-label :title
|
||||
@@ -29,12 +29,13 @@
|
||||
:style {:color colors/warning-60}}
|
||||
(i18n/label :t/amount-missing-keypairs
|
||||
{:amount (str (count keypairs))})]
|
||||
[button/button
|
||||
{:type :outline
|
||||
:background :blur
|
||||
:size 24
|
||||
:on-press on-import-press}
|
||||
(i18n/label :t/import)]]
|
||||
(when show-import-all?
|
||||
[button/button
|
||||
{:type :outline
|
||||
:background :blur
|
||||
:size 24
|
||||
:on-press on-import-press}
|
||||
(i18n/label :t/import)])]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (style/subtitle blur? theme)}
|
||||
|
||||
@@ -81,8 +81,9 @@
|
||||
(js->clj :keywordize-keys true)
|
||||
(on-selection-change))))]
|
||||
(fn [{:keys [token customization-color show-keyboard? crypto? currency value error? selection
|
||||
handle-on-swap]
|
||||
:or {show-keyboard? true}}]
|
||||
handle-on-swap allow-selection?]
|
||||
:or {show-keyboard? true
|
||||
allow-selection? true}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
window-width (:width (rn/get-window))]
|
||||
[rn/pressable
|
||||
@@ -107,7 +108,8 @@
|
||||
:selection-color customization-color
|
||||
:show-soft-input-on-focus show-keyboard?
|
||||
:on-selection-change handle-selection-change
|
||||
:selection (clj->js selection)}
|
||||
:selection (clj->js selection)
|
||||
:editable allow-selection?}
|
||||
controlled-input? (assoc :value value)
|
||||
(not controlled-input?) (assoc :default-value value-internal))]
|
||||
[token-name-text theme (if crypto? token currency)]]]
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
(def black-opa-0 (alpha black 0))
|
||||
(def black-opa-30 (alpha black 0.3))
|
||||
(def black-opa-60 (alpha black 0.6))
|
||||
(def onboarding-header-black "#000716")
|
||||
(def onboarding-header-black neutral-100)
|
||||
(def border-avatar-light
|
||||
"Simulates a blurred, transparent border for avatars in light mode"
|
||||
"#475060")
|
||||
|
||||
@@ -33,6 +33,9 @@
|
||||
[:fn {:error/message "schema.common/exception should be of type ExceptionInfo"}
|
||||
(fn [v] (instance? ExceptionInfo v))])
|
||||
|
||||
(def ^:private ?hiccup
|
||||
vector?)
|
||||
|
||||
(defn register-schemas
|
||||
[]
|
||||
(registry/register ::theme ?theme)
|
||||
@@ -40,4 +43,5 @@
|
||||
(registry/register ::public-key ?public-key)
|
||||
(registry/register ::image-source ?image-source)
|
||||
(registry/register ::rpc-call ?rpc-call)
|
||||
(registry/register ::exception ?exception))
|
||||
(registry/register ::exception ?exception)
|
||||
(registry/register ::hiccup ?hiccup))
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
(defn get-label-by-type
|
||||
[biometric-type]
|
||||
(condp = biometric-type
|
||||
constants/biometrics-type-android (i18n/label :t/biometric-fingerprint)
|
||||
constants/biometrics-type-face-id (i18n/label :t/biometric-faceid)
|
||||
(i18n/label :t/biometric-touchid)))
|
||||
constants/biometrics-type-android (i18n/label :t/biometric-fingerprint)
|
||||
constants/biometrics-type-face-id (i18n/label :t/biometric-faceid)
|
||||
constants/biometrics-type-touch-id (i18n/label :t/biometric-touchid)
|
||||
(i18n/label :t/biometric)))
|
||||
|
||||
(defn get-icon-by-type
|
||||
[biometric-type]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im.common.bottom-sheet.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]))
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def ^:private sheet-border-radius 20)
|
||||
|
||||
@@ -22,11 +21,8 @@
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(defn shell-bg
|
||||
[blur-background]
|
||||
{:background-color (if blur-background
|
||||
blur-background
|
||||
(if platform/ios? colors/white-opa-5 colors/neutral-100-opa-90))
|
||||
(def shell-bg
|
||||
{:background-color colors/bottom-sheet-background-blur
|
||||
:flex 1})
|
||||
|
||||
(def shell-bg-container
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
(defn view
|
||||
[{:keys [hide? insets]}
|
||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||
gradient-cover? customization-color hide-handle? blur-radius blur-background]
|
||||
gradient-cover? customization-color hide-handle? blur-radius]
|
||||
:or {border-radius 12}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
{window-height :height} (rn/get-window)
|
||||
@@ -134,7 +134,7 @@
|
||||
(when shell?
|
||||
[rn/view {:style style/shell-bg-container}
|
||||
[quo/blur
|
||||
{:style (style/shell-bg blur-background)
|
||||
{:style style/shell-bg
|
||||
:blur-radius (or blur-radius 20)
|
||||
:blur-amount 32
|
||||
:blur-type :transparent
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im.common.enter-seed-phrase.style
|
||||
(:require
|
||||
[react-native.safe-area :as safe-area]))
|
||||
(:require [react-native.platform :as platform]))
|
||||
|
||||
(def full-layout {:flex 1})
|
||||
|
||||
@@ -11,6 +10,13 @@
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(defn recovery-phrase-container
|
||||
[{:keys [banner-offset insets keyboard-shown?]}]
|
||||
{:flex 1
|
||||
:padding-bottom (if keyboard-shown?
|
||||
(when platform/ios? banner-offset)
|
||||
(:bottom insets))})
|
||||
|
||||
(def form-container
|
||||
{:flex 1
|
||||
:padding-horizontal 20
|
||||
@@ -29,9 +35,7 @@
|
||||
:margin-top 12
|
||||
:margin-horizontal -20})
|
||||
|
||||
(defn continue-button
|
||||
[keyboard-shown?]
|
||||
{:margin-top :auto
|
||||
:margin-bottom (when-not keyboard-shown? (safe-area/get-bottom))})
|
||||
(def continue-button
|
||||
{:margin-top :auto})
|
||||
|
||||
(def keyboard-container {:margin-top :auto})
|
||||
|
||||
@@ -96,7 +96,7 @@
|
||||
(take 7)))
|
||||
|
||||
(defn recovery-phrase-screen
|
||||
[{:keys [keypair title recovering-keypair? render-controls]}]
|
||||
[{:keys [banner-offset initial-insets keypair title recovering-keypair? render-controls]}]
|
||||
(reagent/with-let [keyboard-shown? (reagent/atom false)
|
||||
keyboard-show-listener (.addListener rn/keyboard
|
||||
"keyboardDidShow"
|
||||
@@ -114,7 +114,8 @@
|
||||
seed-phrase (reagent/atom "")
|
||||
on-change-seed-phrase (fn [new-phrase]
|
||||
(when @invalid-seed-phrase?
|
||||
(reset! invalid-seed-phrase? false)
|
||||
(reset! invalid-seed-phrase? false))
|
||||
(when @incorrect-seed-phrase?
|
||||
(reset! incorrect-seed-phrase? false))
|
||||
(reset! seed-phrase new-phrase))
|
||||
on-submit (fn []
|
||||
@@ -161,7 +162,10 @@
|
||||
button-disabled? (or error-state?
|
||||
(not (constants/seed-phrase-valid-length word-count))
|
||||
(not all-words-valid?))]
|
||||
[:<>
|
||||
[rn/view
|
||||
{:style (style/recovery-phrase-container {:insets initial-insets
|
||||
:banner-offset banner-offset
|
||||
:keyboard-shown? @keyboard-shown?})}
|
||||
[recovery-phrase-form
|
||||
{:title title
|
||||
:keypair keypair
|
||||
@@ -172,18 +176,18 @@
|
||||
(if (fn? render-controls)
|
||||
(render-controls {:submit-disabled? button-disabled?
|
||||
:keyboard-shown? @keyboard-shown?
|
||||
:container-style (style/continue-button @keyboard-shown?)
|
||||
:container-style style/continue-button
|
||||
:prepare-seed-phrase secure-clean-seed-phrase
|
||||
:focus-input focus-input
|
||||
:seed-phrase (security/mask-data @seed-phrase)
|
||||
:set-incorrect-seed-phrase set-incorrect-seed-phrase})
|
||||
[quo/button
|
||||
{:container-style (style/continue-button @keyboard-shown?)
|
||||
{:container-style style/continue-button
|
||||
:type :primary
|
||||
:disabled? button-disabled?
|
||||
:on-press on-submit}
|
||||
(i18n/label :t/continue)])]
|
||||
(when @keyboard-shown?
|
||||
(when (or @keyboard-shown? error-state?)
|
||||
[rn/view {:style style/keyboard-container}
|
||||
[quo/predictive-keyboard
|
||||
{:type suggestions-state
|
||||
@@ -197,7 +201,8 @@
|
||||
|
||||
(defn screen
|
||||
[{:keys [initial-insets title keypair navigation-icon recovering-keypair? render-controls]}]
|
||||
(let [{navigation-bar-top :top} initial-insets]
|
||||
(let [{navigation-bar-top :top} initial-insets
|
||||
banner-offset (rf/sub [:alert-banners/top-margin])]
|
||||
[rn/view {:style style/full-layout}
|
||||
[rn/keyboard-avoiding-view {:style style/page-container}
|
||||
[quo/page-nav
|
||||
@@ -210,6 +215,8 @@
|
||||
{:title title
|
||||
:keypair keypair
|
||||
:render-controls render-controls
|
||||
:banner-offset banner-offset
|
||||
:initial-insets initial-insets
|
||||
:recovering-keypair? recovering-keypair?}]]]))
|
||||
|
||||
(defn view
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||
gradient-cover? keyboard-should-persist-taps]
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps]
|
||||
:or {footer-container-padding (safe-area/get-top)}}
|
||||
& children]
|
||||
(reagent/with-let [scroll-view-ref (atom nil)
|
||||
@@ -110,7 +110,9 @@
|
||||
:always-bounce-vertical @keyboard-did-show?
|
||||
:shows-vertical-scroll-indicator false
|
||||
:keyboard-should-persist-taps keyboard-should-persist-taps}
|
||||
(into [rn/view {:on-layout set-content-container-height}]
|
||||
(into [rn/view
|
||||
{:style content-container-style
|
||||
:on-layout set-content-container-height}]
|
||||
children)]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/keyboard-avoiding-view
|
||||
|
||||
@@ -365,20 +365,10 @@
|
||||
:sub-label nil
|
||||
:chevron? false}))
|
||||
|
||||
(defn add-members-entry
|
||||
[chat-id]
|
||||
(defn add-manage-members-entry
|
||||
[chat-id admin?]
|
||||
(entry {:icon :i/add-user
|
||||
:label (i18n/label :t/add-members)
|
||||
:on-press #(rf/dispatch [:open-modal :group-add-manage-members chat-id])
|
||||
:danger? false
|
||||
:accessibility-label :add-members
|
||||
:sub-label nil
|
||||
:chevron? false}))
|
||||
|
||||
(defn manage-members-entry
|
||||
[chat-id]
|
||||
(entry {:icon :i/add-user
|
||||
:label (i18n/label :t/manage-members)
|
||||
:label (i18n/label (if admin? :t/manage-members :t/add-members))
|
||||
:on-press #(rf/dispatch [:open-modal :group-add-manage-members chat-id])
|
||||
:danger? false
|
||||
:accessibility-label :manage-members
|
||||
@@ -433,8 +423,7 @@
|
||||
admin? (get admins current-pub-key)]
|
||||
[(group-details-entry chat-id)
|
||||
(when inside-chat?
|
||||
(when admin?
|
||||
(manage-members-entry chat-id)))
|
||||
(add-manage-members-entry chat-id admin?))
|
||||
(when (and admin? inside-chat?)
|
||||
(when config/show-not-implemented-features?
|
||||
(edit-group-entry)))
|
||||
@@ -459,7 +448,7 @@
|
||||
(destructive-actions item inside-chat?)])])
|
||||
|
||||
(defn contact-actions
|
||||
[{:keys [public-key] :as contact} {:keys [chat-id admin?] :as extra-data}]
|
||||
[{:keys [public-key added?] :as contact} {:keys [chat-id admin?] :as extra-data}]
|
||||
(let [current-pub-key (rf/sub [:multiaccount/public-key])]
|
||||
[quo/action-drawer
|
||||
[[(view-profile-entry public-key)
|
||||
@@ -470,7 +459,7 @@
|
||||
[(when-not (= current-pub-key public-key)
|
||||
(when config/show-not-implemented-features?
|
||||
(mark-untrustworthy-entry)))
|
||||
(when-not (= current-pub-key public-key) (remove-from-contacts-entry contact))
|
||||
(when added? (remove-from-contacts-entry contact))
|
||||
(when-not (= current-pub-key public-key) (block-user-entry contact))]
|
||||
(when (and admin? chat-id)
|
||||
[(if (= current-pub-key public-key)
|
||||
|
||||
@@ -2,12 +2,13 @@
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:flex 1
|
||||
:padding 10
|
||||
:margin-vertical 10.5
|
||||
:border-width 1
|
||||
:border-color colors/neutral-10
|
||||
:border-radius 16})
|
||||
{:flex 1
|
||||
:padding 10
|
||||
:margin-top 10.5
|
||||
:margin-bottom 0
|
||||
:border-width 1
|
||||
:border-color colors/neutral-10
|
||||
:border-radius 16})
|
||||
|
||||
(def content
|
||||
{:padding-bottom 20})
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[status-im.common.raw-data-block.style :as style]))
|
||||
|
||||
(defn view
|
||||
[{:keys [data]}]
|
||||
[data]
|
||||
[rn/scroll-view
|
||||
{:style style/container
|
||||
:content-container-style style/content}
|
||||
|
||||
@@ -195,7 +195,7 @@
|
||||
true)
|
||||
|
||||
(defn view
|
||||
[{:keys [title subtitle validate-fn on-success-scan error-message share-button?]}]
|
||||
[{:keys [title subtitle validate-fn on-success-scan error-message share-button? import-keypair?]}]
|
||||
(let [insets (safe-area/get-insets)
|
||||
qr-code-succeed? (reagent/atom false)
|
||||
qr-view-finder (reagent/atom {})
|
||||
@@ -233,7 +233,9 @@
|
||||
:set-qr-code-succeeded (fn [value]
|
||||
(when on-success-scan
|
||||
(on-success-scan value))
|
||||
(rf/dispatch [:navigate-back]))
|
||||
(if import-keypair?
|
||||
(set-rescan-timeout)
|
||||
(rf/dispatch [:navigate-back])))
|
||||
:set-rescan-timeout set-rescan-timeout}])
|
||||
[rn/view {:style (style/root-container (:top insets))}
|
||||
[header
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
:size 24}]]
|
||||
[password-input/view
|
||||
{:on-press-biometrics on-press-biometrics
|
||||
:blur? true
|
||||
:processing processing
|
||||
:error error
|
||||
:default-password password
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
(rf/reg-event-fx :standard-auth/authorize authorize)
|
||||
|
||||
(defn authorize-with-biometric
|
||||
[_ [{:keys [on-auth-success on-auth-fail] :as args}]]
|
||||
[_ [{:keys [on-auth-success on-auth-fail on-close] :as args}]]
|
||||
(let [args-with-biometric-btn
|
||||
(assoc args
|
||||
:on-press-biometric
|
||||
@@ -31,7 +31,10 @@
|
||||
{:prompt-message (i18n/label :t/biometric-auth-confirm-message)
|
||||
:on-cancel #(rf/dispatch [:standard-auth/authorize-with-password
|
||||
args-with-biometric-btn])
|
||||
:on-success #(rf/dispatch [:standard-auth/on-biometric-success on-auth-success])
|
||||
:on-success (fn []
|
||||
(when (fn? on-close)
|
||||
(on-close))
|
||||
(rf/dispatch [:standard-auth/on-biometric-success on-auth-success]))
|
||||
:on-fail (fn [err]
|
||||
(rf/dispatch [:standard-auth/authorize-with-password
|
||||
args-with-biometric-btn])
|
||||
|
||||
@@ -14,10 +14,12 @@
|
||||
(> (-> s str string/trim count) constants/key-pair-name-max-length))
|
||||
|
||||
(defn validation-keypair-name
|
||||
[s]
|
||||
[s existing-keypair-names]
|
||||
(cond
|
||||
(string/blank? s) nil
|
||||
(validators/has-emojis? s) (i18n/label :t/key-name-error-emoji)
|
||||
(validators/has-special-characters? s) (i18n/label :t/key-name-error-special-char)
|
||||
(keypair-too-short? s) (i18n/label :t/your-key-pair-name-is-too-short)
|
||||
(keypair-too-long? s) (i18n/label :t/your-key-pair-name-is-too-long)))
|
||||
(keypair-too-short? s) (i18n/label :t/key-name-error-too-short
|
||||
{:count constants/key-pair-name-min-length})
|
||||
(keypair-too-long? s) (i18n/label :t/your-key-pair-name-is-too-long)
|
||||
(contains? existing-keypair-names s) (i18n/label :t/key-name-error-taken)))
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest are]]
|
||||
[status-im.common.validation.keypair :as keypair-validator]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(deftest keypair-name-too-short-test
|
||||
@@ -18,10 +19,12 @@
|
||||
|
||||
(deftest validation-keypair-name-test
|
||||
(are [arg expected]
|
||||
(= (keypair-validator/validation-keypair-name arg) expected)
|
||||
(= (keypair-validator/validation-keypair-name arg #{"Collection"}) expected)
|
||||
nil nil
|
||||
"" nil
|
||||
"name !" (i18n/label :t/key-name-error-special-char)
|
||||
"Hello 😊" (i18n/label :t/key-name-error-emoji)
|
||||
"abc" (i18n/label :t/your-key-pair-name-is-too-short)
|
||||
"abc" (i18n/label :t/key-name-error-too-short
|
||||
{:count constants/key-pair-name-min-length})
|
||||
"Collection" (i18n/label :t/key-name-error-taken)
|
||||
(apply str (repeat 25 "a")) (i18n/label :t/your-key-pair-name-is-too-long)))
|
||||
|
||||
@@ -268,12 +268,14 @@
|
||||
(def ^:const wallet-connect-personal-sign-method "personal_sign")
|
||||
(def ^:const wallet-connect-eth-sign-method "eth_sign")
|
||||
(def ^:const wallet-connect-eth-send-transaction-method "eth_sendTransaction")
|
||||
(def ^:const wallet-connect-eth-sign-transaction-method "eth_signTransaction")
|
||||
(def ^:const wallet-connect-eth-sign-typed-method "eth_signTypedData")
|
||||
(def ^:const wallet-connect-eth-sign-typed-v4-method "eth_signTypedData_v4")
|
||||
(def ^:const wallet-connect-supported-methods
|
||||
#{wallet-connect-personal-sign-method
|
||||
wallet-connect-eth-sign-method
|
||||
wallet-connect-eth-send-transaction-method
|
||||
wallet-connect-eth-sign-transaction-method
|
||||
wallet-connect-eth-sign-typed-method
|
||||
wallet-connect-eth-sign-typed-v4-method})
|
||||
(def ^:const wallet-connect-supported-events #{"accountsChanged" "chainChanged"})
|
||||
@@ -492,6 +494,10 @@
|
||||
(def ^:const optimism-abbreviated-name "Oeth.")
|
||||
(def ^:const arbitrum-abbreviated-name "Arb1.")
|
||||
|
||||
(def ^:const mainnet-full-name "Mainnet")
|
||||
(def ^:const optimism-full-name "Optimism")
|
||||
(def ^:const arbitrum-full-name "Arbitrum")
|
||||
|
||||
(def ^:const mainnet-network-name :mainnet)
|
||||
(def ^:const ethereum-network-name :ethereum)
|
||||
(def ^:const optimism-network-name :optimism)
|
||||
|
||||
@@ -27,29 +27,37 @@
|
||||
(rf/dispatch [:deselect-member public-key true]))))
|
||||
|
||||
(defn add-member-contact-item-render
|
||||
[{:keys [public-key] :as item} _ _ {:keys [group]}]
|
||||
(let [current-pk (rf/sub [:multiaccount/public-key])
|
||||
{:keys [contacts]} group
|
||||
[{:keys [public-key] :as item} _ _ {:keys [group admin? current-pk]}]
|
||||
(let [{:keys [contacts]} group
|
||||
member? (contains? contacts public-key)
|
||||
checked? (reagent/atom member?)]
|
||||
(fn []
|
||||
(let [on-toggle #(group-chat-member-toggle member? (swap! checked? not) public-key)]
|
||||
(if (or (= current-pk public-key) (and (not admin?) member?))
|
||||
(fn []
|
||||
[contact-list-item/contact-list-item
|
||||
(when (not= current-pk public-key)
|
||||
{:disabled? true
|
||||
:accessory {:disabled? true
|
||||
:type :checkbox
|
||||
:checked? @checked?}}
|
||||
item])
|
||||
(fn []
|
||||
(let [on-toggle #(group-chat-member-toggle member? (swap! checked? not) public-key)]
|
||||
[contact-list-item/contact-list-item
|
||||
{:on-press on-toggle
|
||||
:allow-multiple-presses? true
|
||||
:accessory {:type :checkbox
|
||||
:checked? @checked?
|
||||
:on-check on-toggle}})
|
||||
item]))))
|
||||
:on-check on-toggle}}
|
||||
item])))))
|
||||
|
||||
(defn add-manage-members
|
||||
[{:keys [scroll-enabled? on-scroll]}]
|
||||
(let [selected-participants (rf/sub [:group-chat/selected-participants])
|
||||
deselected-members (rf/sub [:group-chat/deselected-members])
|
||||
chat-id (rf/sub [:get-screen-params :group-add-manage-members])
|
||||
group (rf/sub [:chats/chat-by-id chat-id])
|
||||
theme (quo.theme/use-theme)]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
selected-participants (rf/sub [:group-chat/selected-participants])
|
||||
deselected-members (rf/sub [:group-chat/deselected-members])
|
||||
chat-id (rf/sub [:get-screen-params :group-add-manage-members])
|
||||
{:keys [admins] :as group} (rf/sub [:chats/chat-by-id chat-id])
|
||||
current-pk (rf/sub [:multiaccount/public-key])
|
||||
admin? (get admins current-pk)]
|
||||
[rn/view {:flex 1 :margin-top 20}
|
||||
[rn/touchable-opacity
|
||||
{:on-press #(rf/dispatch [:navigate-back])
|
||||
@@ -60,7 +68,7 @@
|
||||
{:size :heading-1
|
||||
:weight :semi-bold
|
||||
:style {:margin-left 20}}
|
||||
(i18n/label :t/manage-members)]
|
||||
(i18n/label (if admin? :t/manage-members :t/add-members))]
|
||||
[gesture/section-list
|
||||
{:key-fn :title
|
||||
:scroll-enabled @scroll-enabled?
|
||||
@@ -70,7 +78,9 @@
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-section-footer-fn contact-list/contacts-section-footer
|
||||
:content-container-style {:padding-bottom 20}
|
||||
:render-data {:group group}
|
||||
:render-data {:group group
|
||||
:admin? admin?
|
||||
:current-pk current-pk}
|
||||
:render-fn add-member-contact-item-render}]
|
||||
[rn/view {:style (style/bottom-container 30 theme)}
|
||||
[quo/button
|
||||
@@ -159,17 +169,16 @@
|
||||
:on-press #(rf/dispatch [:chat.ui/mute chat-id (not muted)
|
||||
(when-not muted
|
||||
constants/mute-till-unmuted)])}
|
||||
(when admin?
|
||||
{:accessibility-label :manage-members
|
||||
:customization-color color
|
||||
:icon :i/add-user
|
||||
:label (i18n/label :t/manage-members)
|
||||
:counter-value (count contacts)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:group/clear-added-participants])
|
||||
(rf/dispatch [:group/clear-removed-members])
|
||||
(rf/dispatch [:open-modal :group-add-manage-members
|
||||
chat-id]))})]}]
|
||||
{:accessibility-label :manage-members
|
||||
:customization-color color
|
||||
:icon :i/add-user
|
||||
:label (i18n/label (if admin? :t/manage-members :t/add-members))
|
||||
:counter-value (count contacts)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:group/clear-added-participants])
|
||||
(rf/dispatch [:group/clear-removed-members])
|
||||
(rf/dispatch [:open-modal :group-add-manage-members
|
||||
chat-id]))}]}]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:sticky-section-headers-enabled false
|
||||
|
||||
+24
-10
@@ -16,8 +16,13 @@
|
||||
contact-id])
|
||||
{:keys [contact-request-state community-id]} (rf/sub [:chats/current-chat-chat-view])
|
||||
chat-type (rf/sub [:chats/chat-type])
|
||||
joined (rf/sub [:communities/community-joined
|
||||
community-id])
|
||||
community-chat? (= chat-type :community-chat)
|
||||
joined (when community-chat?
|
||||
(rf/sub [:communities/community-joined
|
||||
community-id]))
|
||||
pending? (when community-chat?
|
||||
(rf/sub [:communities/my-pending-request-to-join
|
||||
community-id]))
|
||||
contact-request-send? (or (not contact-request-state)
|
||||
(= contact-request-state
|
||||
constants/contact-request-state-none))
|
||||
@@ -28,19 +33,28 @@
|
||||
[rn/view {:style style/container}
|
||||
[quo/permission-context
|
||||
{:blur? true
|
||||
:on-press (condp = chat-type
|
||||
:community-chat #(rf/dispatch [:open-modal :community-account-selection-sheet
|
||||
{:community-id community-id}])
|
||||
:on-press (cond
|
||||
(and community-chat? (not pending?) (not joined))
|
||||
#(rf/dispatch [:open-modal :community-account-selection-sheet
|
||||
{:community-id community-id}])
|
||||
|
||||
(not community-chat?)
|
||||
#(rf/dispatch [:chat.ui/show-profile contact-id]))
|
||||
:type :action
|
||||
:action-icon (cond
|
||||
(= chat-type :community-chat) :i/communities
|
||||
contact-request-pending? :i/pending-state
|
||||
:else :i/add-user)
|
||||
community-chat? :i/communities
|
||||
contact-request-pending? :i/pending-state
|
||||
:else :i/add-user)
|
||||
:action-label (cond
|
||||
(= chat-type :community-chat)
|
||||
(if joined
|
||||
community-chat?
|
||||
(cond
|
||||
pending?
|
||||
(i18n/label :t/request-to-join-community-pending)
|
||||
|
||||
joined
|
||||
(i18n/label :t/no-permissions-to-post)
|
||||
|
||||
:else
|
||||
(i18n/label :t/join-community-to-post))
|
||||
|
||||
(= chat-type :group-chat)
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
:as chat} (rf/sub [:chats/chat-by-id chat-id])
|
||||
pins-count (rf/sub [:chats/pin-messages-count chat-id])
|
||||
items (rf/sub [:communities/sorted-community-members-section-list
|
||||
community-id])
|
||||
community-id chat-id])
|
||||
theme (quo.theme/use-theme)]
|
||||
(rn/use-mount (fn []
|
||||
(rf/dispatch [:pin-message/load-pin-messages chat-id])))
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
|
||||
(rf/reg-event-fx :community/fetch
|
||||
(fn [_]
|
||||
{:json-rpc/call [{:method "wakuext_communities"
|
||||
{:json-rpc/call [{:method "wakuext_serializedCommunities"
|
||||
:params []
|
||||
:on-success #(rf/dispatch [:community/fetch-success %])
|
||||
:on-error #(log/error "failed to fetch communities" %)}
|
||||
@@ -230,7 +230,7 @@
|
||||
(when community
|
||||
{:db (update db :communities/fetching-communities dissoc community-id)
|
||||
:fx [[:dispatch [:communities/handle-community community]]
|
||||
[:dispatch [:communities/update-last-opened-at community-id]]
|
||||
[:dispatch [:chat.ui/spectate-community community-id]]
|
||||
[:dispatch
|
||||
[:chat.ui/cache-link-preview-data (link-preview.events/community-link community-id)
|
||||
community]]]}))
|
||||
@@ -251,7 +251,7 @@
|
||||
:error err}))
|
||||
|
||||
(defn fetch-community
|
||||
[{:keys [db]} [{:keys [community-id update-last-opened-at?]}]]
|
||||
[{:keys [db]} [{:keys [community-id]}]]
|
||||
(when (and community-id
|
||||
(not (get-in db [:communities community-id]))
|
||||
(not (get-in db [:communities/fetching-communities community-id])))
|
||||
@@ -262,11 +262,8 @@
|
||||
:WaitForResponse true}]
|
||||
:on-success (fn [community]
|
||||
(if community
|
||||
(do (when update-last-opened-at?
|
||||
(rf/dispatch [:communities/update-last-opened-at
|
||||
community-id]))
|
||||
(rf/dispatch [:chat.ui/community-fetched community-id
|
||||
community]))
|
||||
(rf/dispatch [:chat.ui/community-fetched community-id
|
||||
community])
|
||||
(failed-to-fetch-community
|
||||
community-id
|
||||
"community wasn't found at the store node")))
|
||||
@@ -280,8 +277,7 @@
|
||||
[:schema
|
||||
[:vector
|
||||
[:map {:closed true}
|
||||
[:community-id {:optional true} :string]
|
||||
[:update-last-opened-at? {:optional true} [:maybe :boolean]]]]]]]
|
||||
[:community-id {:optional true} :string]]]]]]
|
||||
[:maybe
|
||||
[:map
|
||||
[:db map?]
|
||||
@@ -340,10 +336,9 @@
|
||||
(rf/merge
|
||||
cofx
|
||||
{:fx [[:dispatch [:chat.ui/spectate-community community-id]]
|
||||
[:dispatch [:communities/update-last-opened-at community-id]]
|
||||
[:dispatch
|
||||
[:communities/fetch-community
|
||||
{:community-id community-id
|
||||
:update-last-opened-at? true}]]
|
||||
[:communities/fetch-community {:community-id community-id}]]
|
||||
[:dispatch [:navigate-to :community-overview community-id]]
|
||||
(when (get-in db [:communities community-id :joined])
|
||||
[:dispatch
|
||||
@@ -358,10 +353,7 @@
|
||||
(let [community-id (or community-id (get-in db [:chats chat-id :community-id]))]
|
||||
(merge
|
||||
{:fx [(when community-id
|
||||
[:dispatch
|
||||
[:communities/fetch-community
|
||||
{:community-id community-id
|
||||
:update-last-opened-at? true}]])
|
||||
[:dispatch [:communities/fetch-community {:community-id community-id}]])
|
||||
(if pop-to-root?
|
||||
[:dispatch [:chat/pop-to-root-and-navigate-to-chat chat-id]]
|
||||
[:dispatch
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
(testing "dispatch fxs"
|
||||
(is (match?
|
||||
{:fx [[:dispatch [:communities/handle-community {:id community-id}]]
|
||||
[:dispatch [:communities/update-last-opened-at community-id]]
|
||||
[:dispatch [:chat.ui/spectate-community community-id]]
|
||||
[:dispatch
|
||||
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
||||
{:id community-id}]]]}
|
||||
@@ -60,7 +60,7 @@
|
||||
(testing "dispatch fxs, do not spectate community"
|
||||
(is (match?
|
||||
{:fx [[:dispatch [:communities/handle-community {:id community-id}]]
|
||||
[:dispatch [:communities/update-last-opened-at community-id]]
|
||||
[:dispatch [:chat.ui/spectate-community community-id]]
|
||||
[:dispatch
|
||||
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
||||
{:id community-id}]]]}
|
||||
@@ -71,7 +71,7 @@
|
||||
(testing "dispatch fxs, do not spectate community"
|
||||
(is (match?
|
||||
{:fx [[:dispatch [:communities/handle-community {:id community-id}]]
|
||||
[:dispatch [:communities/update-last-opened-at community-id]]
|
||||
[:dispatch [:chat.ui/spectate-community community-id]]
|
||||
[:dispatch
|
||||
[:chat.ui/cache-link-preview-data "community-link+community-id"
|
||||
{:id community-id}]]]}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(def background-container
|
||||
{:background-color colors/neutral-95
|
||||
{:background-color colors/neutral-100
|
||||
:flex-direction :row
|
||||
:position :absolute
|
||||
:overflow :hidden
|
||||
|
||||
@@ -29,8 +29,8 @@
|
||||
[rn/image
|
||||
{:resize-mode :stretch
|
||||
:resize-method :scale
|
||||
:style {:margin-top 32
|
||||
:width content-width}
|
||||
:style {:top 138
|
||||
:width content-width}
|
||||
:source (resources/get-image :onboarding-illustration)}])
|
||||
|
||||
(defonce progress (atom nil))
|
||||
|
||||
+1
-12
@@ -1,4 +1,4 @@
|
||||
(ns status-im.contexts.onboarding.new-to-status.style
|
||||
(ns status-im.contexts.onboarding.create-or-sync-profile.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
@@ -24,15 +24,4 @@
|
||||
(def subtitle-container
|
||||
{:margin-top 24})
|
||||
|
||||
(def doc-main-content
|
||||
{:color colors/white
|
||||
:margin-bottom 4})
|
||||
|
||||
(def doc-subtitle
|
||||
{:margin-top 20
|
||||
:margin-bottom 4})
|
||||
|
||||
(def doc-content
|
||||
{:color colors/white-opa-70})
|
||||
|
||||
(def space-between-suboptions {:height 12})
|
||||
@@ -0,0 +1,141 @@
|
||||
(ns status-im.contexts.onboarding.create-or-sync-profile.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
re-frame.db
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.config :as config]
|
||||
[status-im.contexts.onboarding.create-or-sync-profile.style :as style]
|
||||
[status-im.contexts.onboarding.getting-started-doc.view :as getting-started-doc]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- navigate-to-create-profile
|
||||
[]
|
||||
(debounce/throttle-and-dispatch
|
||||
[:onboarding/navigate-to-create-profile]
|
||||
1000))
|
||||
|
||||
(defn- navigate-to-sign-in-by-syncing
|
||||
[]
|
||||
(debounce/throttle-and-dispatch
|
||||
[:onboarding/navigate-to-sign-in-by-syncing]
|
||||
1000))
|
||||
|
||||
(defn- navigate-to-sign-in-by-seed-phrase
|
||||
[create-profile?]
|
||||
(rf/dispatch [:onboarding/navigate-to-sign-in-by-seed-phrase
|
||||
(if create-profile?
|
||||
:screen/onboarding.new-to-status
|
||||
:screen/onboarding.sync-or-recover-profile)]))
|
||||
|
||||
(defn- option-card-max-height
|
||||
[window-height]
|
||||
(- window-height
|
||||
(* 2 56) ;; two other list items
|
||||
(* 2 16) ;; spacing between items
|
||||
220) ;; extra spacing (top bar)
|
||||
)
|
||||
|
||||
(defn- create-profile-option-card
|
||||
[window-height]
|
||||
[quo/small-option-card
|
||||
{:variant :main
|
||||
:title (i18n/label :t/generate-keys)
|
||||
:subtitle (i18n/label :t/generate-keys-subtitle)
|
||||
:button-label (i18n/label :t/lets-go)
|
||||
:accessibility-label :generate-key-option-card
|
||||
:image (resources/get-image :generate-keys)
|
||||
:max-height (option-card-max-height window-height)
|
||||
:on-press navigate-to-create-profile}])
|
||||
|
||||
(defn- sync-profile-option-card
|
||||
[window-height]
|
||||
[quo/small-option-card
|
||||
{:variant :main
|
||||
:title (i18n/label :t/sign-in-by-syncing)
|
||||
:subtitle (i18n/label :t/if-you-have-status-on-another-device)
|
||||
:button-label (i18n/label :t/scan-sync-code)
|
||||
:accessibility-label :scan-sync-code-option-card
|
||||
:image (resources/get-image :generate-keys)
|
||||
:max-height (option-card-max-height window-height)
|
||||
:on-press navigate-to-sign-in-by-syncing}])
|
||||
|
||||
(defn sign-in-options
|
||||
[sign-in-type]
|
||||
(let [window-height (rf/sub [:dimensions/window-height])
|
||||
create-profile? (= sign-in-type :create-profile)
|
||||
nav-to-seed-phrase-with-cur-screen (rn/use-callback
|
||||
#(navigate-to-sign-in-by-seed-phrase
|
||||
create-profile?)
|
||||
[create-profile?])
|
||||
main-option-card (if create-profile?
|
||||
create-profile-option-card
|
||||
sync-profile-option-card)]
|
||||
[rn/view {:style style/options-container}
|
||||
[quo/text
|
||||
{:style style/title
|
||||
:size :heading-1
|
||||
:weight :semi-bold}
|
||||
(i18n/label (if create-profile? :t/create-profile :t/sync-or-recover-profile))]
|
||||
[main-option-card window-height]
|
||||
[rn/view {:style style/subtitle-container}
|
||||
[quo/text
|
||||
{:style style/subtitle
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
(i18n/label (if create-profile? :t/experienced-web3 :t/dont-have-statatus-on-another-device))]]
|
||||
[rn/view
|
||||
[quo/small-option-card
|
||||
{:variant :icon
|
||||
:title (i18n/label :t/use-recovery-phrase)
|
||||
:subtitle (i18n/label :t/use-recovery-phrase-subtitle)
|
||||
:accessibility-label :use-recovery-phrase-option-card
|
||||
:image (resources/get-image :ethereum-address)
|
||||
:on-press nav-to-seed-phrase-with-cur-screen}]
|
||||
[rn/view {:style style/space-between-suboptions}]
|
||||
(when config/show-not-implemented-features?
|
||||
[quo/small-option-card
|
||||
{:variant :icon
|
||||
:title (i18n/label :t/use-keycard)
|
||||
:subtitle (i18n/label :t/use-keycard-subtitle)
|
||||
:accessibility-label :use-keycard-option-card
|
||||
:image (resources/get-image :use-keycard)
|
||||
:on-press status-im.common.not-implemented/alert}])]]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
(rf/dispatch [:onboarding/overlay-dismiss])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn- navigate-to-quo-preview
|
||||
[]
|
||||
(rf/dispatch [:navigate-to :quo-preview]))
|
||||
|
||||
(defn- internal-view
|
||||
[sign-in-type]
|
||||
(let [{:keys [top]} (safe-area/get-insets)]
|
||||
[rn/view {:style style/content-container}
|
||||
[quo/page-nav
|
||||
{:margin-top top
|
||||
:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press getting-started-doc/show-as-bottom-sheet}
|
||||
(when config/quo-preview-enabled?
|
||||
{:icon-name :i/reveal-whitelist
|
||||
:on-press navigate-to-quo-preview})]}]
|
||||
[sign-in-options sign-in-type]]))
|
||||
|
||||
(defn create-profile
|
||||
[]
|
||||
[internal-view :create-profile])
|
||||
|
||||
(defn sync-or-recover-profile
|
||||
[]
|
||||
[internal-view :sync-or-recover-profile])
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.onboarding.enable-notifications.style :as style]
|
||||
@@ -36,7 +35,7 @@
|
||||
{:permissions [:post-notifications]
|
||||
:on-allowed #(log/info "push notification permissions were allowed")
|
||||
:on-denied #(log/error "user denied push notification permissions")}])
|
||||
(rf/dispatch [:push-notifications/switch true platform/ios?])
|
||||
(rf/dispatch [:push-notifications/switch true])
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.welcome
|
||||
:screen/onboarding.enable-notifications]]))
|
||||
|
||||
@@ -15,7 +15,10 @@
|
||||
[{:keys [db]} onboarding-data]
|
||||
{:db (update db :onboarding/profile merge onboarding-data)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.create-profile-password :screen/onboarding.new-to-status]]})
|
||||
[:screen/onboarding.create-profile-password
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]})
|
||||
|
||||
(rf/defn enable-biometrics
|
||||
{:events [:onboarding/enable-biometrics]}
|
||||
@@ -25,13 +28,24 @@
|
||||
{:on-success #(rf/dispatch [:onboarding/biometrics-done])
|
||||
:on-fail #(rf/dispatch [:onboarding/biometrics-fail %])}]]]})
|
||||
|
||||
(rf/defn navigate-to-enable-notifications
|
||||
{:events [:onboarding/navigate-to-enable-notifications]}
|
||||
[{:keys [db]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:db (dissoc db :onboarding/profile)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications :screen/onboarding.enable-biometrics]]}))
|
||||
(rf/reg-event-fx :onboarding/navigate-to-sign-in-by-seed-phrase
|
||||
(fn [{:keys [db]} [from-screen]]
|
||||
{:db (assoc db :onboarding/navigated-to-enter-seed-phrase-from-screen from-screen)
|
||||
:fx [[:dispatch [:navigate-to-within-stack [:screen/onboarding.enter-seed-phrase from-screen]]]]}))
|
||||
|
||||
(rf/reg-event-fx :onboarding/navigate-to-enable-notifications-from-syncing
|
||||
(fn [{:keys [db]}]
|
||||
{:db (dissoc db :onboarding/profile)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications :screen/onboarding.enable-biometrics]]}))
|
||||
|
||||
(rf/reg-event-fx :onboarding/navigate-to-enable-notifications
|
||||
(fn [{:keys [db]}]
|
||||
{:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]}))
|
||||
|
||||
(rf/defn biometrics-done
|
||||
{:events [:onboarding/biometrics-done]}
|
||||
@@ -54,7 +68,10 @@
|
||||
(:onboarding/profile db)]
|
||||
(rf/merge cofx
|
||||
{:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.generating-keys :screen/onboarding.new-to-status]]
|
||||
[:screen/onboarding.generating-keys
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]
|
||||
:dispatch-later [{:ms constants/onboarding-generating-keys-animation-duration-ms
|
||||
:dispatch [:onboarding/navigate-to-identifiers]}]
|
||||
:db (-> db
|
||||
@@ -72,7 +89,7 @@
|
||||
(merge
|
||||
{:db (assoc db :profile/profiles-overview multiaccounts)}
|
||||
(when-not (seq multiaccounts)
|
||||
{:set-root :screen/onboarding.intro}))))
|
||||
{:dispatch [:init-root :screen/onboarding.intro]}))))
|
||||
|
||||
(rf/defn password-set
|
||||
{:events [:onboarding/password-set]}
|
||||
@@ -83,7 +100,10 @@
|
||||
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
|
||||
:dispatch (if supported-type
|
||||
[:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-biometrics :screen/onboarding.new-to-status]]
|
||||
[:screen/onboarding.enable-biometrics
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]
|
||||
[:onboarding/create-account-and-login])}))
|
||||
|
||||
(rf/defn navigate-to-enable-biometrics
|
||||
@@ -118,7 +138,10 @@
|
||||
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
|
||||
{:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]}))
|
||||
[:screen/onboarding.create-profile
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]}))
|
||||
|
||||
(rf/defn navigate-to-create-profile
|
||||
{:events [:onboarding/navigate-to-create-profile]}
|
||||
@@ -128,6 +151,13 @@
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]})
|
||||
|
||||
(rf/reg-event-fx :onboarding/navigate-to-sign-in-by-syncing
|
||||
(fn [{:keys [db]}]
|
||||
;; Restart the flow
|
||||
{:db (dissoc db :onboarding/profile)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.sign-in-intro :screen/onboarding.sync-or-recover-profile]]}))
|
||||
|
||||
(rf/reg-event-fx :onboarding/set-auth-method
|
||||
(fn [{:keys [db]} [auth-method]]
|
||||
{:db (assoc db :auth-method auth-method)}))
|
||||
@@ -151,7 +181,8 @@
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:onboarding/set-auth-method auth-method])
|
||||
(when syncing?
|
||||
(rf/dispatch [:onboarding/navigate-to-enable-notifications])))
|
||||
(rf/dispatch
|
||||
[:onboarding/navigate-to-enable-notifications-from-syncing])))
|
||||
:on-error #(log/error "failed to save biometrics"
|
||||
{:key-uid key-uid
|
||||
:error %})}))))
|
||||
@@ -161,6 +192,9 @@
|
||||
[{:keys [db]}]
|
||||
(if (:onboarding/generated-keys? db)
|
||||
{:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.identifiers :screen/onboarding.new-to-status]]}
|
||||
[:screen/onboarding.identifiers
|
||||
(get db
|
||||
:onboarding/navigated-to-enter-seed-phrase-from-screen
|
||||
:screen/onboarding.new-to-status)]]}
|
||||
{:dispatch-later [{:ms constants/onboarding-generating-keys-navigation-retry-ms
|
||||
:dispatch [:onboarding/navigate-to-identifiers]}]}))
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns status-im.contexts.onboarding.getting-started-doc.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def main-content
|
||||
{:color colors/white
|
||||
:margin-bottom 4})
|
||||
|
||||
(def subtitle
|
||||
{:margin-top 20
|
||||
:margin-bottom 4})
|
||||
|
||||
(def content
|
||||
{:color colors/white-opa-70})
|
||||
@@ -0,0 +1,50 @@
|
||||
(ns status-im.contexts.onboarding.getting-started-doc.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[status-im.contexts.onboarding.getting-started-doc.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn getting-started-doc
|
||||
[]
|
||||
[quo/documentation-drawers
|
||||
{:title (i18n/label :t/getting-started-with-status)
|
||||
:shell? true}
|
||||
[:<>
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/main-content}
|
||||
(i18n/label :t/getting-started-description)]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:style style/subtitle
|
||||
:weight :semi-bold}
|
||||
(i18n/label :t/generate-keys)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/content}
|
||||
(i18n/label :t/getting-started-generate-keys-description)]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:style style/subtitle
|
||||
:weight :semi-bold}
|
||||
(i18n/label :t/getting-started-generate-keys-from-recovery-phrase)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/content}
|
||||
(i18n/label :t/getting-started-generate-keys-from-recovery-phrase-description)]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:style style/subtitle
|
||||
:weight :semi-bold}
|
||||
(i18n/label :t/getting-started-generate-keys-on-keycard)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/content}
|
||||
(i18n/label :t/getting-started-generate-keys-on-keycard-description)]]])
|
||||
|
||||
(defn show-as-bottom-sheet
|
||||
[]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content getting-started-doc
|
||||
:shell? true}]))
|
||||
@@ -20,6 +20,10 @@
|
||||
{:text (i18n/label :t/emojihash)
|
||||
:sub-text (i18n/label :t/emojihash-description)}])
|
||||
|
||||
(defn- navigate-to-enable-notifications
|
||||
[]
|
||||
(rf/dispatch [:onboarding/navigate-to-enable-notifications]))
|
||||
|
||||
(defn f-view
|
||||
[]
|
||||
(let [progress (atom nil)
|
||||
@@ -62,9 +66,7 @@
|
||||
{:accessibility-label :skip-identifiers
|
||||
:type :grey
|
||||
:background :blur
|
||||
:on-press #(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications
|
||||
:screen/onboarding.new-to-status]])
|
||||
:on-press navigate-to-enable-notifications
|
||||
:container-style style/button}
|
||||
(i18n/label :t/continue)]]]]))
|
||||
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
:justify-content :flex-end})
|
||||
|
||||
(def text-container
|
||||
{:flex 1
|
||||
:max-width 180
|
||||
:flex-wrap :wrap})
|
||||
{:flex 1
|
||||
:text-align :center
|
||||
:margin-top 16
|
||||
:flex-wrap :wrap})
|
||||
|
||||
(def plain-text
|
||||
{:color colors/white-opa-70})
|
||||
@@ -17,3 +18,10 @@
|
||||
(def highlighted-text
|
||||
{:flex 1
|
||||
:color colors/white})
|
||||
|
||||
(def bottom-actions-container
|
||||
{:position :absolute
|
||||
:background-color colors/onboarding-header-black
|
||||
:left 0
|
||||
:right 0
|
||||
:padding-bottom 40})
|
||||
|
||||
@@ -2,12 +2,10 @@
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.onboarding.common.background.view :as background]
|
||||
[status-im.contexts.onboarding.common.overlay.view :as overlay]
|
||||
[status-im.contexts.onboarding.intro.style :as style]
|
||||
[status-im.contexts.onboarding.terms.view :as terms]
|
||||
[status-im.contexts.syncing.scan-sync-code.view :as scan-sync-code]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -15,40 +13,37 @@
|
||||
[]
|
||||
[rn/view {:style style/page-container}
|
||||
[background/view false]
|
||||
[quo/drawer-buttons
|
||||
{:on-init (fn [reset-top-animation-fn]
|
||||
(reset! scan-sync-code/dismiss-animations reset-top-animation-fn))
|
||||
:animations-duration constants/onboarding-modal-animation-duration
|
||||
:animations-delay constants/onboarding-modal-animation-delay
|
||||
:top-card {:on-press #(rf/dispatch [:open-modal
|
||||
:screen/onboarding.sign-in-intro])
|
||||
:heading (i18n/label :t/sign-in)
|
||||
:animated-heading (i18n/label :t/sign-in-by-syncing)
|
||||
:accessibility-label :already-use-status-button}
|
||||
:bottom-card {:on-press (fn []
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch
|
||||
[:open-modal :screen/onboarding.new-to-status]))
|
||||
:heading (i18n/label :t/new-to-status)
|
||||
:accessibility-label :new-to-status-button}}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style style/plain-text}
|
||||
(i18n/label :t/you-already-use-status)]
|
||||
[quo/text {:style style/text-container}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style style/plain-text}
|
||||
(i18n/label :t/by-continuing-you-accept)]
|
||||
[quo/text
|
||||
{:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [terms/terms-of-use])
|
||||
:shell? true}])
|
||||
:size :paragraph-2
|
||||
:weight :regular
|
||||
:style style/highlighted-text}
|
||||
(i18n/label :t/terms-of-service)]]]
|
||||
[quo/bottom-actions
|
||||
{:container-style style/bottom-actions-container
|
||||
:actions :two-vertical-actions
|
||||
:description :bottom
|
||||
:description-text [quo/text
|
||||
{:style style/text-container
|
||||
:size :paragraph-2
|
||||
:weight :regular}
|
||||
[quo/text {:style style/plain-text}
|
||||
(i18n/label :t/by-continuing-you-accept)]
|
||||
[quo/text
|
||||
{:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [terms/terms-of-use])
|
||||
:shell? true}])
|
||||
:style style/highlighted-text}
|
||||
(i18n/label :t/terms-of-service)]]
|
||||
:button-one-label (i18n/label :t/sync-or-recover-profile)
|
||||
:button-one-props {:type :dark-grey
|
||||
:accessibility-label :already-use-status-button
|
||||
:on-press (fn []
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch
|
||||
[:open-modal
|
||||
:screen/onboarding.sync-or-recover-profile]))}
|
||||
:button-two-label (i18n/label :t/create-profile)
|
||||
:button-two-props {:accessibility-label :new-to-status-button
|
||||
:on-press
|
||||
(fn []
|
||||
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
|
||||
(blur-show-fn))
|
||||
(rf/dispatch
|
||||
[:open-modal :screen/onboarding.new-to-status]))}}]
|
||||
[overlay/view]])
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
(ns status-im.contexts.onboarding.new-to-status.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
re-frame.db
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.config :as config]
|
||||
[status-im.contexts.onboarding.new-to-status.style :as style]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn sign-in-options
|
||||
[]
|
||||
(let [window (rf/sub [:dimensions/window])]
|
||||
[rn/view {:style style/options-container}
|
||||
[quo/text
|
||||
{:style style/title
|
||||
:size :heading-1
|
||||
:weight :semi-bold}
|
||||
(i18n/label :t/new-to-status)]
|
||||
[quo/small-option-card
|
||||
{:variant :main
|
||||
:title (i18n/label :t/generate-keys)
|
||||
:subtitle (i18n/label :t/generate-keys-subtitle)
|
||||
:button-label (i18n/label :t/lets-go)
|
||||
:image (resources/get-image :generate-keys)
|
||||
:max-height (- (:height window)
|
||||
(* 2 56) ;; two other list items
|
||||
(* 2 16) ;; spacing between items
|
||||
220) ;; extra spacing (top bar)
|
||||
:on-press #(debounce/throttle-and-dispatch
|
||||
[:onboarding/navigate-to-create-profile]
|
||||
1000)}]
|
||||
[rn/view {:style style/subtitle-container}
|
||||
[quo/text
|
||||
{:style style/subtitle
|
||||
:size :paragraph-2
|
||||
:weight :medium}
|
||||
(i18n/label :t/experienced-web3)]]
|
||||
[rn/view
|
||||
[quo/small-option-card
|
||||
{:variant :icon
|
||||
:title (i18n/label :t/use-recovery-phrase)
|
||||
:subtitle (i18n/label :t/use-recovery-phrase-subtitle)
|
||||
:image (resources/get-image :ethereum-address)
|
||||
:on-press #(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enter-seed-phrase
|
||||
:screen/onboarding.new-to-status]])}]
|
||||
[rn/view {:style style/space-between-suboptions}]
|
||||
(when config/show-not-implemented-features?
|
||||
[quo/small-option-card
|
||||
{:variant :icon
|
||||
:title (i18n/label :t/use-keycard)
|
||||
:subtitle (i18n/label :t/use-keycard-subtitle)
|
||||
:image (resources/get-image :use-keycard)
|
||||
:on-press #(js/alert "TODO: to be implemented")}])]]))
|
||||
|
||||
(defn getting-started-doc
|
||||
[]
|
||||
[quo/documentation-drawers
|
||||
{:title (i18n/label :t/getting-started-with-status)
|
||||
:shell? true}
|
||||
[:<>
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/doc-main-content}
|
||||
(i18n/label :t/getting-started-description)]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:style style/doc-subtitle
|
||||
:weight :semi-bold}
|
||||
(i18n/label :t/generate-keys)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/doc-content}
|
||||
(i18n/label :t/getting-started-generate-keys-description)]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:style style/doc-subtitle
|
||||
:weight :semi-bold}
|
||||
(i18n/label :t/getting-started-generate-keys-from-recovery-phrase)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/doc-content}
|
||||
(i18n/label :t/getting-started-generate-keys-from-recovery-phrase-description)]
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
:style style/doc-subtitle
|
||||
:weight :semi-bold}
|
||||
(i18n/label :t/getting-started-generate-keys-on-keycard)]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/doc-content}
|
||||
(i18n/label :t/getting-started-generate-keys-on-keycard-description)]]])
|
||||
|
||||
(defn new-to-status
|
||||
[]
|
||||
(let [{:keys [top]} (safe-area/get-insets)]
|
||||
[rn/view {:style style/content-container}
|
||||
[quo/page-nav
|
||||
{:margin-top top
|
||||
:type :no-title
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(do
|
||||
(rf/dispatch [:onboarding/overlay-dismiss])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
:right-side [{:icon-name :i/info
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content getting-started-doc
|
||||
:shell? true}])}
|
||||
(when config/quo-preview-enabled?
|
||||
{:icon-name :i/reveal-whitelist
|
||||
:on-press #(rf/dispatch [:navigate-to :quo-preview])})]}]
|
||||
[sign-in-options]]))
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im.contexts.preview.quo.settings.category
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
@@ -17,6 +18,24 @@
|
||||
:image-props :i/browser
|
||||
:image-size 32})))
|
||||
|
||||
(defn create-data-item-array
|
||||
[n]
|
||||
(vec
|
||||
(for [i (range n)]
|
||||
{:blur? false
|
||||
:description :default
|
||||
:icon-right? true
|
||||
:right-icon :i/chevron-right
|
||||
:icon-color colors/neutral-10
|
||||
:card? false
|
||||
:label :preview
|
||||
:status :default
|
||||
:size :default
|
||||
:right-content {:type :accounts
|
||||
:data [{:emoji "🔥" :customization-color :yellow}]}
|
||||
:title (str "Item title " i)
|
||||
:subtitle "Item subtitle"})))
|
||||
|
||||
(def descriptor
|
||||
[{:key :blur? :type :boolean}
|
||||
{:key :list-type
|
||||
@@ -24,7 +43,11 @@
|
||||
:options [{:key :settings
|
||||
:value :settings}
|
||||
{:key :reorder
|
||||
:value :reorder}]}])
|
||||
:value :reorder}
|
||||
{:key :data-item
|
||||
:value :data-item}]}])
|
||||
|
||||
(def ^:constant n-items 5)
|
||||
|
||||
(defn view
|
||||
[]
|
||||
@@ -32,7 +55,10 @@
|
||||
:blur? false
|
||||
:list-type :settings})]
|
||||
(fn []
|
||||
(let [data (create-item-array 5)]
|
||||
(let [list-type (:list-type @state)
|
||||
data (if (= list-type :data-item)
|
||||
(create-data-item-array n-items)
|
||||
(create-item-array n-items))]
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
|
||||
@@ -51,7 +51,9 @@
|
||||
{:value "Saved address"
|
||||
:key :saved-address}
|
||||
{:value "Account"
|
||||
:key :account}]}])
|
||||
:key :account}
|
||||
{:value "Dapp"
|
||||
:key :dapp}]}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
:options [{:key :usd}
|
||||
{:key :eur}]}
|
||||
{:key :error?
|
||||
:type :boolean}
|
||||
{:key :allow-selection?
|
||||
:type :boolean}])
|
||||
|
||||
(defn view
|
||||
@@ -33,7 +35,8 @@
|
||||
:networks networks
|
||||
:title title
|
||||
:customization-color :blue
|
||||
:show-keyboard? false})
|
||||
:show-keyboard? false
|
||||
:allow-selection? true})
|
||||
value (reagent/atom "")
|
||||
set-value (fn [v]
|
||||
(swap! value str v))
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.profile.edit.style :as style]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -19,7 +20,7 @@
|
||||
:on-press #(rf/dispatch [:open-modal :edit-name])
|
||||
:blur? true
|
||||
:label :text
|
||||
:label-props full-name
|
||||
:label-props (utils/truncate-str full-name constants/profile-name-max-length)
|
||||
:action :arrow
|
||||
:container-style style/item-container}
|
||||
{:title (i18n/label :t/bio)
|
||||
|
||||
@@ -45,14 +45,14 @@
|
||||
(assoc :profile/profiles-overview profiles)
|
||||
(update :profile/login #(select-profile % key-uid)))
|
||||
db)
|
||||
:fx [[:set-root :screen/profile.profiles]
|
||||
:fx [[:dispatch [:init-root :screen/profile.profiles]]
|
||||
(when key-uid
|
||||
[:effects.biometric/check-if-available
|
||||
{:key-uid key-uid
|
||||
:on-success (fn [auth-method]
|
||||
(rf/dispatch [:profile.login/check-biometric-success key-uid
|
||||
auth-method]))}])]})
|
||||
{:fx [[:set-root :screen/onboarding.intro]]})))
|
||||
{:fx [[:dispatch [:init-root :screen/onboarding.intro]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:profile/update-setting-from-backup
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
|
||||
(cond
|
||||
pairing-completed?
|
||||
[[:set-root :screen/onboarding.syncing-results]]
|
||||
[[:dispatch [:init-root :screen/onboarding.syncing-results]]]
|
||||
|
||||
(get db :onboarding/new-account?)
|
||||
[[:dispatch [:onboarding/finalize-setup]]]
|
||||
@@ -85,7 +85,7 @@
|
||||
constants/theme-type-dark)
|
||||
:shell-stack
|
||||
false]]
|
||||
[:set-root :shell-stack]
|
||||
[:dispatch [:init-root :shell-stack]]
|
||||
[:dispatch [:profile/show-testnet-mode-banner-if-enabled]]]))})))
|
||||
|
||||
;; login phase 2: we want to load and show chats faster, so we split login into 2 phases
|
||||
@@ -179,7 +179,7 @@
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/login :password] password)
|
||||
(assoc-in [:profile/login :processing] true))
|
||||
:fx [[:set-root :progress]
|
||||
:fx [[:dispatch [:init-root :progress]]
|
||||
[:effects.profile/login
|
||||
[(get-in db [:profile/login :key-uid])
|
||||
(security/safe-unmask-data password)]]]})))
|
||||
|
||||
@@ -1,24 +1,5 @@
|
||||
(ns status-im.contexts.settings.wallet.data-store)
|
||||
|
||||
(defn extract-keypair-name
|
||||
[db key-uids-set]
|
||||
(when (= (count key-uids-set) 1)
|
||||
(let [key-uid (first key-uids-set)
|
||||
keypairs (get-in db [:wallet :keypairs])]
|
||||
(->> (filter #(= (:key-uid %) key-uid) keypairs)
|
||||
first
|
||||
:name))))
|
||||
|
||||
(defn update-keypair
|
||||
[keypairs key-uid update-fn]
|
||||
(mapcat (fn [keypair]
|
||||
(if (= (keypair :key-uid) key-uid)
|
||||
(if-let [updated (update-fn keypair)]
|
||||
[updated]
|
||||
[])
|
||||
[keypair]))
|
||||
keypairs))
|
||||
|
||||
(defn make-accounts-fully-operable
|
||||
"Updates accounts to be fully operable based on specified key-uids and an optional operable condition.
|
||||
|
||||
@@ -32,10 +13,10 @@
|
||||
- A new map with accounts updated to be fully operable where the conditions are met."
|
||||
[{:keys [accounts key-uids-set operable-condition]}]
|
||||
(reduce-kv
|
||||
(fn [acc k account]
|
||||
(if (and (contains? key-uids-set (:key-uid account))
|
||||
(fn [acc k {:keys [key-uid] :as account}]
|
||||
(if (and (contains? key-uids-set key-uid)
|
||||
(or (nil? operable-condition)
|
||||
(= (keyword (:operable account)) operable-condition)))
|
||||
(= (:operable account) operable-condition)))
|
||||
(assoc acc k (assoc account :operable :fully))
|
||||
(assoc acc k account)))
|
||||
{}
|
||||
@@ -44,7 +25,7 @@
|
||||
(defn- make-keypairs-accounts-fully-operable
|
||||
[accounts operable-condition]
|
||||
(map (fn [account]
|
||||
(if (or (nil? operable-condition) (= (keyword (:operable account)) operable-condition))
|
||||
(if (or (nil? operable-condition) (= (:operable account) operable-condition))
|
||||
(assoc account :operable :fully)
|
||||
account))
|
||||
accounts))
|
||||
@@ -53,27 +34,30 @@
|
||||
"Updates keypairs' accounts to be fully operable based on specified key-uids and an optional operable condition.
|
||||
|
||||
Parameters:
|
||||
- :keypairs (seq): A sequence of keypair maps.
|
||||
- :keypairs (map): A map of keypair key-uid to keypair details.
|
||||
- :key-uids-set (set): A set of key-uids that need to be checked and updated.
|
||||
- :operable-condition (keyword, optional): The condition that the keypair's accounts' operability must meet to be updated.
|
||||
If nil or not provided, the function will update all keypairs' accounts.
|
||||
|
||||
Returns:
|
||||
- A new sequence with keypairs updated to be fully operable where the conditions are met."
|
||||
- A new map with keypairs updated to be fully operable where the conditions are met."
|
||||
[{:keys [keypairs key-uids-set operable-condition]}]
|
||||
(map (fn [keypair]
|
||||
(if (contains? key-uids-set (:key-uid keypair))
|
||||
(-> keypair
|
||||
(update :accounts #(make-keypairs-accounts-fully-operable % operable-condition))
|
||||
(assoc :lowest-operability :fully))
|
||||
keypair))
|
||||
keypairs))
|
||||
(reduce-kv (fn [acc k keypair]
|
||||
(if (contains? key-uids-set k)
|
||||
(assoc acc
|
||||
k
|
||||
(-> keypair
|
||||
(update :accounts make-keypairs-accounts-fully-operable operable-condition)
|
||||
(assoc :lowest-operability :fully)))
|
||||
(assoc acc k keypair)))
|
||||
{}
|
||||
keypairs))
|
||||
|
||||
(defn map-addresses-to-key-uids
|
||||
(defn get-keypair-key-uids-set-from-addresses
|
||||
[db addresses]
|
||||
(reduce (fn [key-uid-set address]
|
||||
(if-let [account (get-in db [:wallet :accounts address])]
|
||||
(conj key-uid-set (:key-uid account))
|
||||
(if-let [account-key-uid (get-in db [:wallet :accounts address :key-uid])]
|
||||
(conj key-uid-set account-key-uid)
|
||||
key-uid-set))
|
||||
#{}
|
||||
addresses))
|
||||
|
||||
@@ -10,9 +10,7 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/rename-keypair-success
|
||||
(fn [{:keys [db]} [key-uid name]]
|
||||
{:db (update-in db
|
||||
[:wallet :keypairs]
|
||||
#(data-store/update-keypair % key-uid (fn [keypair] (assoc keypair :name name))))
|
||||
{:db (update-in db [:wallet :keypairs key-uid] assoc :name name)
|
||||
:fx [[:dispatch [:navigate-back]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
@@ -49,9 +47,7 @@
|
||||
|
||||
(rf/reg-event-fx :wallet/remove-keypair-success
|
||||
(fn [{:keys [db]} [key-uid]]
|
||||
{:db (update-in db
|
||||
[:wallet :keypairs]
|
||||
#(data-store/update-keypair % key-uid (fn [_] nil)))
|
||||
{:db (update-in db [:wallet :keypairs] dissoc key-uid)
|
||||
:fx [[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch
|
||||
[:toasts/upsert
|
||||
@@ -71,8 +67,11 @@
|
||||
|
||||
(defn make-keypairs-accounts-fully-operable
|
||||
[{:keys [db]} [key-uids-to-update]]
|
||||
(let [key-uids-set (set key-uids-to-update)
|
||||
keypair-name (data-store/extract-keypair-name db key-uids-set)]
|
||||
(let [key-uids-set (set key-uids-to-update)
|
||||
single-keypair-to-update? (= (count key-uids-to-update) 1)
|
||||
keypair-name (when single-keypair-to-update?
|
||||
(let [key-uid (first key-uids-set)]
|
||||
(get-in db [:wallet :keypairs key-uid :name])))]
|
||||
{:db (->
|
||||
db
|
||||
(update-in [:wallet :accounts]
|
||||
@@ -85,7 +84,7 @@
|
||||
[:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text (if (= (count key-uids-to-update) 1)
|
||||
:text (if single-keypair-to-update?
|
||||
(i18n/label :t/key-pair-imported-successfully {:name keypair-name})
|
||||
(i18n/label :t/key-pairs-successfully-imported
|
||||
{:count (count key-uids-to-update)}))}]]]}))
|
||||
@@ -93,23 +92,28 @@
|
||||
(rf/reg-event-fx :wallet/make-keypairs-accounts-fully-operable make-keypairs-accounts-fully-operable)
|
||||
|
||||
(defn connection-string-for-import-keypair
|
||||
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string]}]]
|
||||
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string on-success]}]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:effects.syncing/import-keypairs-keystores
|
||||
{:key-uid key-uid
|
||||
:sha3-pwd sha3-pwd
|
||||
:keypairs-key-uids keypairs-key-uids
|
||||
:connection-string connection-string
|
||||
:on-success #(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable %])
|
||||
:on-fail #(rf/dispatch [:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text %}])}]]}))
|
||||
:on-success (fn [key-uids]
|
||||
(rf/call-continuation on-success)
|
||||
(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable key-uids]))
|
||||
:on-fail (fn [error]
|
||||
(log/error "failed to import missing key pairs with connection string"
|
||||
{:error error})
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:type :negative
|
||||
:theme :dark
|
||||
:text (i18n/label :t/incorrect-qr-code)}]))}]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/connection-string-for-import-keypair connection-string-for-import-keypair)
|
||||
|
||||
(defn success-keypair-qr-scan
|
||||
[_ [connection-string keypairs-key-uids]]
|
||||
[_ [connection-string keypairs-key-uids on-import-success]]
|
||||
{:fx [[:dispatch
|
||||
[:standard-auth/authorize-with-password
|
||||
{:blur? true
|
||||
@@ -121,7 +125,8 @@
|
||||
[:wallet/connection-string-for-import-keypair
|
||||
{:connection-string connection-string
|
||||
:keypairs-key-uids keypairs-key-uids
|
||||
:sha3-pwd password}]))}]]]})
|
||||
:sha3-pwd password
|
||||
:on-success on-import-success}]))}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/success-keypair-qr-scan success-keypair-qr-scan)
|
||||
|
||||
@@ -147,7 +152,7 @@
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "accounts_makePrivateKeyKeypairFullyOperable"
|
||||
:params [(security/safe-unmask-data private-key)
|
||||
(-> password security/safe-unmask-data native-module/sha3)]
|
||||
(security/safe-unmask-data password)]
|
||||
:on-success on-success
|
||||
:on-error on-error}]]]})
|
||||
|
||||
@@ -231,7 +236,7 @@
|
||||
|
||||
(defn make-partially-operable-accounts-fully-operable-success
|
||||
[{:keys [db]} [addresses]]
|
||||
(let [key-uids-to-update (data-store/map-addresses-to-key-uids db addresses)]
|
||||
(let [key-uids-to-update (data-store/get-keypair-key-uids-set-from-addresses db addresses)]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :accounts]
|
||||
#(data-store/make-accounts-fully-operable {:accounts %
|
||||
|
||||
@@ -1,104 +1,100 @@
|
||||
(ns status-im.contexts.settings.wallet.events-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
[cljs.test :refer-macros [deftest is]]
|
||||
matcher-combinators.test
|
||||
[native-module.core :as native-module]
|
||||
[status-im.contexts.settings.wallet.events :as sut]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(def mock-key-uid "key-1")
|
||||
(defn mock-db
|
||||
[keypairs accounts]
|
||||
{:wallet {:keypairs keypairs
|
||||
:accounts accounts}
|
||||
:profile/profile {:key-uid "test-key-uid"}})
|
||||
(def test-profile {:key-uid "test-key-uid"})
|
||||
(def test-keypair-key-uid "key-1")
|
||||
|
||||
(deftest rename-keypair-test
|
||||
(let [new-keypair-name "key pair new"
|
||||
cofx {:db {}}]
|
||||
(testing "rename-keypair"
|
||||
(let [expected {:fx [[:json-rpc/call
|
||||
[{:method "accounts_updateKeypairName"
|
||||
:params [mock-key-uid new-keypair-name]
|
||||
:on-success [:wallet/rename-keypair-success mock-key-uid
|
||||
new-keypair-name]
|
||||
:on-error fn?}]]]}]
|
||||
(is (match? expected
|
||||
(sut/rename-keypair cofx
|
||||
[{:key-uid mock-key-uid
|
||||
:keypair-name new-keypair-name}])))))))
|
||||
cofx {:db {}}
|
||||
expected {:fx [[:json-rpc/call
|
||||
[{:method "accounts_updateKeypairName"
|
||||
:params [test-keypair-key-uid new-keypair-name]
|
||||
:on-success [:wallet/rename-keypair-success test-keypair-key-uid
|
||||
new-keypair-name]
|
||||
:on-error fn?}]]]}]
|
||||
(is (match? expected
|
||||
(sut/rename-keypair cofx
|
||||
[{:key-uid test-keypair-key-uid
|
||||
:keypair-name new-keypair-name}])))))
|
||||
|
||||
(deftest get-keypair-export-connection-test
|
||||
(let [cofx {:db (mock-db [] {})}
|
||||
(let [cofx {:db {:profile/profile test-profile}}
|
||||
sha3-pwd "test-password"
|
||||
user-key-uid "test-key-uid"
|
||||
callback (fn [connect-string] (println "callback" connect-string))]
|
||||
(testing "get-keypair-export-connection"
|
||||
(let [expected {:fx [[:effects.syncing/export-keypairs-keystores
|
||||
callback (fn [connect-string] (println "callback" connect-string))
|
||||
expected {:fx [[:effects.syncing/export-keypairs-keystores
|
||||
{:key-uid user-key-uid
|
||||
:sha3-pwd sha3-pwd
|
||||
:keypair-key-uid mock-key-uid
|
||||
:keypair-key-uid test-keypair-key-uid
|
||||
:on-success fn?
|
||||
:on-fail fn?}]]}]
|
||||
(is (match? expected
|
||||
(sut/get-keypair-export-connection
|
||||
cofx
|
||||
[{:sha3-pwd sha3-pwd :keypair-key-uid mock-key-uid :callback callback}])))))))
|
||||
(is (match?
|
||||
expected
|
||||
(sut/get-keypair-export-connection
|
||||
cofx
|
||||
[{:sha3-pwd sha3-pwd :keypair-key-uid test-keypair-key-uid :callback callback}])))))
|
||||
|
||||
(deftest remove-keypair-test
|
||||
(let [cofx {:db {}}]
|
||||
(testing "remove-keypair"
|
||||
(let [expected {:fx [[:json-rpc/call
|
||||
[{:method "accounts_deleteKeypair"
|
||||
:params [mock-key-uid]
|
||||
:on-success [:wallet/remove-keypair-success mock-key-uid]
|
||||
:on-error fn?}]]]}]
|
||||
(is (match? expected
|
||||
(sut/remove-keypair cofx [mock-key-uid])))))))
|
||||
(let [cofx {:db {}}
|
||||
expected {:fx [[:json-rpc/call
|
||||
[{:method "accounts_deleteKeypair"
|
||||
:params [test-keypair-key-uid]
|
||||
:on-success [:wallet/remove-keypair-success test-keypair-key-uid]
|
||||
:on-error fn?}]]]}]
|
||||
(is (match? expected
|
||||
(sut/remove-keypair cofx [test-keypair-key-uid])))))
|
||||
|
||||
(deftest make-keypairs-accounts-fully-operable-test
|
||||
(let [db (mock-db [{:key-uid mock-key-uid
|
||||
:lowest-operability :no
|
||||
:accounts [{:key-uid mock-key-uid :operable "no"}]}]
|
||||
{"0x1" {:key-uid mock-key-uid :operable "no"}})
|
||||
key-uids-to-update [mock-key-uid]]
|
||||
(testing "make-keypairs-accounts-fully-operable"
|
||||
(let [effects (sut/make-keypairs-accounts-fully-operable {:db db} [key-uids-to-update])
|
||||
result-db (:db effects)
|
||||
updated-keypair (some #(when (= (:key-uid %) mock-key-uid) %)
|
||||
(get-in result-db [:wallet :keypairs]))
|
||||
updated-account (get-in result-db [:wallet :accounts "0x1"])]
|
||||
(is (= (keyword (-> updated-keypair :accounts first :operable)) :fully))
|
||||
(is (= (keyword (:operable updated-account)) :fully))
|
||||
(is (= (:lowest-operability updated-keypair) :fully))))))
|
||||
(let [db {:wallet {:keypairs {test-keypair-key-uid {:key-uid
|
||||
test-keypair-key-uid
|
||||
:lowest-operability :no
|
||||
:accounts
|
||||
[{:key-uid
|
||||
test-keypair-key-uid
|
||||
:operable :no}]}}
|
||||
:accounts {"0x1" {:key-uid test-keypair-key-uid
|
||||
:operable :no}}}
|
||||
:profile/profile test-profile}
|
||||
key-uids-to-update [test-keypair-key-uid]
|
||||
effects (sut/make-keypairs-accounts-fully-operable {:db db} [key-uids-to-update])
|
||||
result-db (:db effects)
|
||||
updated-keypair (get-in result-db [:wallet :keypairs test-keypair-key-uid])
|
||||
updated-account (get-in result-db [:wallet :accounts "0x1"])]
|
||||
(is (= (-> updated-keypair :accounts first :operable) :fully))
|
||||
(is (= (:operable updated-account) :fully))
|
||||
(is (= (:lowest-operability updated-keypair) :fully))))
|
||||
|
||||
(deftest connection-string-for-import-keypair-test
|
||||
(let [cofx {:db (mock-db [] {})}
|
||||
(let [cofx {:db {:profile/profile test-profile}}
|
||||
sha3-pwd "test-password"
|
||||
user-key-uid "test-key-uid"
|
||||
connection-string "test-connection-string"]
|
||||
(testing "connection-string-for-import-keypair"
|
||||
(let [expected {:fx [[:effects.syncing/import-keypairs-keystores
|
||||
{:key-uid user-key-uid
|
||||
:sha3-pwd sha3-pwd
|
||||
:keypairs-key-uids [mock-key-uid]
|
||||
:connection-string connection-string
|
||||
:on-success fn?
|
||||
:on-fail fn?}]]}]
|
||||
(is (match? expected
|
||||
(sut/connection-string-for-import-keypair cofx
|
||||
[{:sha3-pwd sha3-pwd
|
||||
:keypairs-key-uids [mock-key-uid]
|
||||
:connection-string
|
||||
connection-string}])))))))
|
||||
connection-string "test-connection-string"
|
||||
expected {:fx [[:effects.syncing/import-keypairs-keystores
|
||||
{:key-uid user-key-uid
|
||||
:sha3-pwd sha3-pwd
|
||||
:keypairs-key-uids [test-keypair-key-uid]
|
||||
:connection-string connection-string
|
||||
:on-success fn?
|
||||
:on-fail fn?}]]}]
|
||||
(is (match? expected
|
||||
(sut/connection-string-for-import-keypair cofx
|
||||
[{:sha3-pwd sha3-pwd
|
||||
:keypairs-key-uids [test-keypair-key-uid]
|
||||
:connection-string
|
||||
connection-string}])))))
|
||||
|
||||
(deftest success-keypair-qr-scan-test
|
||||
(let [connection-string "valid-connection-string"
|
||||
keypairs-key-uids ["keypair-uid"]]
|
||||
(testing "success-keypair-qr-scan"
|
||||
(let [effects (sut/success-keypair-qr-scan nil [connection-string keypairs-key-uids])
|
||||
fx (:fx effects)]
|
||||
(is (some? fx))))))
|
||||
keypairs-key-uids [test-keypair-key-uid]
|
||||
effects (sut/success-keypair-qr-scan nil [connection-string keypairs-key-uids])
|
||||
fx (:fx effects)]
|
||||
(is (some? fx))))
|
||||
|
||||
(deftest wallet-validate-seed-phrase-test
|
||||
(let [cofx {:db {}}
|
||||
|
||||
@@ -41,31 +41,37 @@
|
||||
[quo/action-drawer
|
||||
[(when has-paired-device
|
||||
(if-not missing-keypair?
|
||||
[{:icon :i/qr-code
|
||||
[{:blur? true
|
||||
:icon :i/qr-code
|
||||
:accessibility-label :show-key-pr-qr
|
||||
:label (i18n/label :t/show-encrypted-qr-of-key-pairs)
|
||||
:on-press on-show-qr}]
|
||||
[{:icon :i/scan
|
||||
[{:blur? true
|
||||
:icon :i/scan
|
||||
:accessibility-label :import-by-scan-qr
|
||||
:label (i18n/label :t/import-by-scanning-encrypted-qr)
|
||||
:on-press on-scan-qr}]))
|
||||
(when (= (:type drawer-props) :keypair)
|
||||
[(when missing-keypair?
|
||||
(case (:type keypair)
|
||||
:seed {:icon :i/seed
|
||||
:seed {:blur? true
|
||||
:icon :i/seed
|
||||
:accessibility-label :import-seed-phrase
|
||||
:label (i18n/label :t/import-by-entering-recovery-phrase)
|
||||
:on-press on-import-seed-phrase}
|
||||
:key {:icon :i/key
|
||||
:key {:blur? true
|
||||
:icon :i/key
|
||||
:accessibility-label :import-private-key
|
||||
:label (i18n/label :t/import-by-entering-private-key)
|
||||
:on-press on-import-private-key}
|
||||
nil))
|
||||
{:icon :i/edit
|
||||
{:blur? true
|
||||
:icon :i/edit
|
||||
:accessibility-label :rename-key-pair
|
||||
:label (i18n/label :t/rename-key-pair)
|
||||
:on-press on-rename-keypair}
|
||||
{:icon :i/delete
|
||||
{:blur? true
|
||||
:icon :i/delete
|
||||
:accessibility-label :remove-key-pair
|
||||
:add-divider? true
|
||||
:danger? true
|
||||
|
||||
+6
-3
@@ -11,13 +11,16 @@
|
||||
[]
|
||||
(let [keypairs-key-uids (rf/sub [:get-screen-params])
|
||||
on-success-scan (rn/use-callback (fn [scanned-text]
|
||||
(rf/dispatch [:wallet/success-keypair-qr-scan scanned-text
|
||||
keypairs-key-uids])
|
||||
(rf/dispatch [:wallet/success-keypair-qr-scan
|
||||
scanned-text
|
||||
keypairs-key-uids
|
||||
[:navigate-back]])
|
||||
[keypairs-key-uids]))]
|
||||
[scan-qr-code/view
|
||||
{:title (i18n/label :t/scan-key-pairs-qr-code)
|
||||
:subtitle (i18n/label :t/find-it-in-setting)
|
||||
:share-button? false
|
||||
:import-keypair? true
|
||||
:validate-fn sync-utils/valid-connection-string?
|
||||
:error-message (i18n/label :t/invalid-qr)
|
||||
:error-message (i18n/label :t/invalid-key-pair-qr)
|
||||
:on-success-scan on-success-scan}]))
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
{:margin-bottom 8})
|
||||
|
||||
(def bottom-action
|
||||
{:margin-horizontal -20})
|
||||
{:margin-horizontal -20
|
||||
:margin-vertical -12})
|
||||
|
||||
(def error-container
|
||||
{:margin-left 20
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.common.validation.keypair :as keypair-validator]
|
||||
[status-im.constants :as constants]
|
||||
@@ -14,19 +15,24 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{:keys [name key-uid]} (rf/sub [:get-screen-params])
|
||||
(let [insets (safe-area/get-insets)
|
||||
{existing-keypair-name :name
|
||||
:keys [key-uid]} (rf/sub [:get-screen-params])
|
||||
existing-keypair-names (rf/sub [:wallet/keypair-names])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
[unsaved-keypair-name set-unsaved-keypair-name] (rn/use-state name)
|
||||
[unsaved-keypair-name set-unsaved-keypair-name] (rn/use-state existing-keypair-name)
|
||||
[error-msg set-error-msg] (rn/use-state nil)
|
||||
[typing? set-typing?] (rn/use-state false)
|
||||
validate-keypair-name (rn/use-callback
|
||||
(debounce/debounce
|
||||
(fn [name]
|
||||
(fn [input-name]
|
||||
(set-error-msg
|
||||
(keypair-validator/validation-keypair-name
|
||||
name))
|
||||
input-name
|
||||
existing-keypair-names))
|
||||
(set-typing? false))
|
||||
300))
|
||||
300)
|
||||
[existing-keypair-names])
|
||||
on-change-text (rn/use-callback (fn [text]
|
||||
(set-typing? true)
|
||||
(set-unsaved-keypair-name
|
||||
@@ -40,45 +46,57 @@
|
||||
:keypair-name
|
||||
unsaved-keypair-name}])
|
||||
[unsaved-keypair-name key-uid])]
|
||||
[floating-button-page/view
|
||||
{:header [quo/page-nav
|
||||
{:icon-name :i/close
|
||||
:on-press navigate-back
|
||||
:accessibility-label :top-bar}]
|
||||
:footer [quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/save)
|
||||
:button-one-props {:disabled? (or typing?
|
||||
(string/blank? unsaved-keypair-name)
|
||||
(not (string/blank? error-msg)))
|
||||
:customization-color customization-color
|
||||
:on-press on-save}
|
||||
:container-style style/bottom-action}]}
|
||||
[quo/page-top
|
||||
{:container-style style/header-container
|
||||
:title (i18n/label :t/rename-key-pair)
|
||||
:description :context-tag
|
||||
:context-tag {:type :icon
|
||||
:size 24
|
||||
:context name
|
||||
:icon :i/seed-phrase}}]
|
||||
[quo/input
|
||||
{:container-style {:margin-horizontal 20}
|
||||
:placeholder (i18n/label :t/keypair-name-input-placeholder)
|
||||
:label (i18n/label :t/keypair-name)
|
||||
:default-value unsaved-keypair-name
|
||||
:char-limit constants/key-pair-name-max-length
|
||||
:max-length constants/key-pair-name-max-length
|
||||
:auto-focus true
|
||||
:clearable? (not (string/blank? unsaved-keypair-name))
|
||||
:on-clear on-clear
|
||||
:on-change-text on-change-text
|
||||
:error? (not (string/blank? error-msg))}]
|
||||
(when-not (string/blank? error-msg)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:container-style style/error-container}
|
||||
error-msg])]))
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
:blur? true
|
||||
:header [quo/page-nav
|
||||
{:margin-top (:top insets)
|
||||
:icon-name :i/close
|
||||
:background :blur
|
||||
:on-press navigate-back
|
||||
:accessibility-label :top-bar}]
|
||||
:footer [quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:blur? true
|
||||
:button-one-label (i18n/label :t/save)
|
||||
:button-one-props {:blur? true
|
||||
:disabled? (or typing?
|
||||
(= existing-keypair-name
|
||||
unsaved-keypair-name)
|
||||
(string/blank?
|
||||
unsaved-keypair-name)
|
||||
(not (string/blank?
|
||||
error-msg)))
|
||||
:customization-color customization-color
|
||||
:on-press on-save}
|
||||
:container-style style/bottom-action}]}
|
||||
[quo/page-top
|
||||
{:container-style style/header-container
|
||||
:title (i18n/label :t/rename-key-pair)
|
||||
:description :context-tag
|
||||
:blur? true
|
||||
:context-tag {:type :icon
|
||||
:size 24
|
||||
:context existing-keypair-name
|
||||
:icon :i/seed-phrase}}]
|
||||
[quo/input
|
||||
{:blur? true
|
||||
:container-style {:margin-horizontal 20}
|
||||
:placeholder (i18n/label :t/keypair-name-input-placeholder)
|
||||
:label (i18n/label :t/keypair-name)
|
||||
:default-value unsaved-keypair-name
|
||||
:char-limit constants/key-pair-name-max-length
|
||||
:auto-focus true
|
||||
:clearable? (not (string/blank? unsaved-keypair-name))
|
||||
:on-clear on-clear
|
||||
:on-change-text on-change-text
|
||||
:error? (not (string/blank? error-msg))}]
|
||||
(when-not (string/blank? error-msg)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:container-style style/error-container}
|
||||
error-msg])]]))
|
||||
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
(ns status-im.contexts.settings.wallet.keypairs-and-accounts.view
|
||||
(:require [quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.actions.view :as actions]
|
||||
[status-im.contexts.settings.wallet.keypairs-and-accounts.style :as style]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.address :as utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -17,13 +17,12 @@
|
||||
(defn on-options-press
|
||||
[{:keys [drawer-props keypair]}]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [actions/view
|
||||
{:drawer-props drawer-props
|
||||
:keypair keypair}])
|
||||
{:content (fn [] [actions/view
|
||||
{:drawer-props drawer-props
|
||||
:keypair keypair}])
|
||||
|
||||
:blur-background colors/bottom-sheet-background-blur
|
||||
:theme (:theme drawer-props)
|
||||
:shell? true}]))
|
||||
:theme (:theme drawer-props)
|
||||
:shell? true}]))
|
||||
|
||||
(defn options-drawer-props
|
||||
[{{:keys [name]} :keypair
|
||||
@@ -70,7 +69,7 @@
|
||||
{:blur? true
|
||||
:status-indicator false
|
||||
:stored :on-device
|
||||
:action :options
|
||||
:action (if default-keypair? :none :options)
|
||||
:accounts accounts
|
||||
:customization-color customization-color
|
||||
:container-style style/keypair-container-style
|
||||
@@ -83,17 +82,16 @@
|
||||
(defn on-missing-keypair-options-press
|
||||
[_event keypair-data]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:blur-background colors/bottom-sheet-background-blur
|
||||
:content (fn [] [actions/view
|
||||
{:keypair keypair-data
|
||||
:drawer-props (options-drawer-props
|
||||
{:theme :dark
|
||||
:type :keypair
|
||||
:stored :missing
|
||||
:blur? true
|
||||
:keypair keypair-data})}])}]))
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content (fn [] [actions/view
|
||||
{:keypair keypair-data
|
||||
:drawer-props (options-drawer-props
|
||||
{:theme :dark
|
||||
:type :keypair
|
||||
:stored :missing
|
||||
:blur? true
|
||||
:keypair keypair-data})}])}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
@@ -127,6 +125,7 @@
|
||||
:header (when (seq missing-keypairs)
|
||||
[quo/missing-keypairs
|
||||
{:blur? true
|
||||
:show-import-all? (ff/enabled? ::ff/settings.import-all-keypairs)
|
||||
:keypairs missing-keypairs
|
||||
:on-import-press on-import-press
|
||||
:container-style style/missing-keypairs-container-style
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im.contexts.settings.wallet.network-settings.view
|
||||
(:require [quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
@@ -80,12 +79,11 @@
|
||||
(defn on-change-testnet
|
||||
[{:keys [enable? blur? theme]}]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [testnet/view
|
||||
{:enable? enable?
|
||||
:blur? blur?}])
|
||||
:theme theme
|
||||
:shell? blur?
|
||||
:blur-background colors/bottom-sheet-background-blur}]))
|
||||
{:content (fn [] [testnet/view
|
||||
{:enable? enable?
|
||||
:blur? blur?}])
|
||||
:theme theme
|
||||
:shell? blur?}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
|
||||
+2
-1
@@ -27,4 +27,5 @@
|
||||
{:color colors/white-opa-40})
|
||||
|
||||
(def saved-address-item
|
||||
{:margin-top 4})
|
||||
{:margin-top 4
|
||||
:background-color colors/white-opa-5})
|
||||
|
||||
+3
-3
@@ -49,6 +49,7 @@
|
||||
:multiline? true
|
||||
:on-clear clear-input
|
||||
:return-key-type :done
|
||||
:auto-focus true
|
||||
:clearable? (not empty-input?)
|
||||
:on-change-text on-change-text
|
||||
:button (when empty-input?
|
||||
@@ -83,7 +84,7 @@
|
||||
[quo/info-message
|
||||
{:accessibility-label :error-message
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:icon :i/alert
|
||||
:type :error
|
||||
:style style/info-message}
|
||||
error-msg])))
|
||||
@@ -91,8 +92,7 @@
|
||||
(defn- existing-saved-address
|
||||
[{:keys [address]}]
|
||||
(let [{:keys [name customization-color chain-short-names ens ens?]}
|
||||
(rf/sub [:wallet/saved-address-by-address
|
||||
address])]
|
||||
(rf/sub [:wallet/saved-address-by-address address])]
|
||||
[rn/view {:style style/existing-saved-address-container}
|
||||
[quo/text
|
||||
{:size :paragraph-1
|
||||
|
||||
@@ -93,20 +93,19 @@
|
||||
:subtitle-type :default
|
||||
:label :none
|
||||
:blur? true
|
||||
:icon-right? (not ens?)
|
||||
:right-icon :i/advanced
|
||||
:right-icon (when-not ens? :i/advanced)
|
||||
:card? true
|
||||
:title (i18n/label :t/address)
|
||||
:subtitle ens
|
||||
:custom-subtitle address-text
|
||||
:on-press open-network-preferences
|
||||
:on-press (when-not ens? open-network-preferences)
|
||||
:container-style style/data-item}
|
||||
ens?
|
||||
(dissoc :custom-subtitle))
|
||||
[ens ens? open-network-preferences address-text])]
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
{:footer-container-padding (if edit? (+ (safe-area/get-bottom) 12) 0)
|
||||
:header [quo/page-nav
|
||||
{:type :no-title
|
||||
:background :blur
|
||||
@@ -133,7 +132,7 @@
|
||||
:container-style style/avatar}]
|
||||
[quo/title-input
|
||||
{:blur? true
|
||||
:auto-focus true
|
||||
:auto-focus (not edit?)
|
||||
:max-length 24
|
||||
:size :heading-1
|
||||
:placeholder placeholder
|
||||
|
||||
+11
-8
@@ -2,20 +2,24 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.settings.wallet.saved-addresses.sheets.remove-address.view :as remove-address]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [name full-address chain-short-names address] :as opts}]
|
||||
(let [open-send-flow (rn/use-callback
|
||||
(let [[_ splitted-address] (network-utils/split-network-full-address address)
|
||||
open-send-flow (rn/use-callback
|
||||
#(rf/dispatch [:wallet/select-send-address
|
||||
{:address full-address
|
||||
:recipient full-address
|
||||
:recipient {:label (utils/get-shortened-address
|
||||
splitted-address)
|
||||
:recipient-type :saved-address}
|
||||
:stack-id :wallet-select-address
|
||||
:start-flow? true}])
|
||||
[full-address])
|
||||
@@ -52,11 +56,10 @@
|
||||
open-remove-confirmation-sheet (rn/use-callback
|
||||
#(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:blur-background colors/bottom-sheet-background-blur
|
||||
:content (fn []
|
||||
[remove-address/view opts])}])
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content (fn []
|
||||
[remove-address/view opts])}])
|
||||
[opts])
|
||||
open-show-address-qr (rn/use-callback
|
||||
#(rf/dispatch [:open-modal
|
||||
|
||||
@@ -73,27 +73,34 @@
|
||||
|
||||
(defn- filtered-list
|
||||
[{:keys [search-text]}]
|
||||
[rn/flat-list
|
||||
{:key-fn :address
|
||||
:data (rf/sub [:wallet/filtered-saved-addresses search-text])
|
||||
:render-fn saved-address
|
||||
:shows-vertical-scroll-indicator false
|
||||
:keyboard-should-persist-taps :always
|
||||
:content-container-style {:flex-grow 1}
|
||||
:empty-component [empty-result]}])
|
||||
(let [search-result (rf/sub [:wallet/filtered-saved-addresses search-text])]
|
||||
(if (empty? search-result)
|
||||
[empty-result]
|
||||
[rn/flat-list
|
||||
{:key-fn :address
|
||||
:data search-result
|
||||
:render-fn saved-address
|
||||
:shows-vertical-scroll-indicator false
|
||||
:keyboard-should-persist-taps :always
|
||||
:content-container-style {:flex-grow 1}
|
||||
:bounces false
|
||||
:over-scroll-mode :never}])))
|
||||
|
||||
(defn- unfiltered-list
|
||||
[{:keys [grouped-saved-addresses]}]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:shows-vertical-scroll-indicator false
|
||||
:sticky-section-headers-enabled false
|
||||
:keyboard-should-persist-taps :always
|
||||
:render-section-header-fn header
|
||||
:sections grouped-saved-addresses
|
||||
:render-fn saved-address
|
||||
:content-container-style {:flex-grow 1}
|
||||
:empty-component [empty-list]}])
|
||||
(if (empty? grouped-saved-addresses)
|
||||
[empty-list]
|
||||
[rn/section-list
|
||||
{:key-fn :title
|
||||
:shows-vertical-scroll-indicator false
|
||||
:sticky-section-headers-enabled false
|
||||
:keyboard-should-persist-taps :always
|
||||
:render-section-header-fn header
|
||||
:sections grouped-saved-addresses
|
||||
:render-fn saved-address
|
||||
:bounces false
|
||||
:over-scroll-mode :never
|
||||
:content-container-style {:flex-grow 1}}]))
|
||||
|
||||
(defn- navigate-back
|
||||
[]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.contexts.settings.wallet.wallet-options.style :as style]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -16,16 +15,14 @@
|
||||
|
||||
(defn basic-settings-options
|
||||
[]
|
||||
[(when (ff/enabled? ::ff/settings.keypairs-and-accounts)
|
||||
{:title (i18n/label :t/keypairs-and-accounts)
|
||||
:blur? true
|
||||
:on-press open-keypairs-and-accounts-settings-modal
|
||||
:action :arrow})
|
||||
(when (ff/enabled? ::ff/settings.saved-addresses)
|
||||
{:title (i18n/label :t/saved-addresses)
|
||||
:blur? true
|
||||
:on-press open-saved-addresses-settings-modal
|
||||
:action :arrow})])
|
||||
[{:title (i18n/label :t/keypairs-and-accounts)
|
||||
:blur? true
|
||||
:on-press open-keypairs-and-accounts-settings-modal
|
||||
:action :arrow}
|
||||
{:title (i18n/label :t/saved-addresses)
|
||||
:blur? true
|
||||
:on-press open-saved-addresses-settings-modal
|
||||
:action :arrow}])
|
||||
|
||||
(defn basic-settings
|
||||
[]
|
||||
@@ -74,7 +71,5 @@
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/wallet)
|
||||
:title-accessibility-label :wallet-settings-header}]
|
||||
(when (or (ff/enabled? ::ff/settings.keypairs-and-accounts)
|
||||
(ff/enabled? ::ff/settings.saved-addresses))
|
||||
[basic-settings])
|
||||
[basic-settings]
|
||||
[advanced-settings]]))
|
||||
|
||||
@@ -1,26 +1,33 @@
|
||||
(ns status-im.contexts.shell.qr-reader.sheets.scanned-wallet-address
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[address]
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:title address
|
||||
:type :address}]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/send
|
||||
:accessibility-label :send-asset
|
||||
:label (i18n/label :t/send-to-this-address)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:wallet/select-send-address
|
||||
{:address address
|
||||
:recipient address
|
||||
:stack-id :wallet-select-address
|
||||
:start-flow? true}]))}
|
||||
{:icon :i/save
|
||||
:accessibility-label :save-address
|
||||
:label (i18n/label :t/save-address)
|
||||
:on-press #(js/alert "feature not implemented")}]]]])
|
||||
(let [[_ splitted-address] (network-utils/split-network-full-address address)]
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:title address
|
||||
:type :address}]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/send
|
||||
:accessibility-label :send-asset
|
||||
:label (i18n/label :t/send-to-this-address)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:wallet/select-send-address
|
||||
{:address address
|
||||
:recipient {:recipient-type :address
|
||||
:label (utils/get-shortened-address
|
||||
splitted-address)}
|
||||
:stack-id :wallet-select-address
|
||||
:start-flow? true}]))}
|
||||
(when (ff/enabled? :ff/wallet.saved-addresses)
|
||||
{:icon :i/save
|
||||
:accessibility-label :save-address
|
||||
:label (i18n/label :t/save-address)
|
||||
:on-press #(js/alert "feature not implemented")})]]]]))
|
||||
|
||||
@@ -70,7 +70,15 @@
|
||||
{:keys [address path watch-only?]} (rf/sub [:wallet/current-viewing-account])
|
||||
{keypair-name :name
|
||||
keypair-type :type} (rf/sub [:wallet/current-viewing-account-keypair])
|
||||
networks (rf/sub [:wallet/network-preference-details])]
|
||||
networks (rf/sub [:wallet/network-preference-details])
|
||||
origin-type (case keypair-type
|
||||
:seed
|
||||
:recovery-phrase
|
||||
|
||||
:key
|
||||
:private-key
|
||||
|
||||
:default-keypair)]
|
||||
[rn/scroll-view
|
||||
{:style style/about-tab
|
||||
:content-container-style {:padding-bottom (+ constants/floating-shell-button-height 8)}}
|
||||
@@ -89,7 +97,7 @@
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet {:content about-options}])}]
|
||||
(when (not watch-only?)
|
||||
[quo/account-origin
|
||||
{:type (if (= keypair-type "seed") :recovery-phrase :default-keypair)
|
||||
{:type origin-type
|
||||
:stored :on-device
|
||||
:profile-picture (profile.utils/photo profile)
|
||||
:customization-color customization-color
|
||||
|
||||
@@ -16,12 +16,13 @@
|
||||
(rf/dispatch [:wallet/get-collectible-details id]))
|
||||
|
||||
(defn- on-collectible-long-press
|
||||
[{:keys [preview-url collectible-details]}]
|
||||
[{:keys [preview-url collectible-details id]}]
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[options-drawer/view
|
||||
{:name (:name collectible-details)
|
||||
:image (:uri preview-url)}])}]))
|
||||
:image (:uri preview-url)
|
||||
:id id}])}]))
|
||||
|
||||
(defn- on-end-reached
|
||||
[]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[status-im.contexts.wallet.add-account.create-account.utils :as create-account.utils]
|
||||
[status-im.contexts.wallet.data-store :as data-store]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.collection]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as transforms]))
|
||||
@@ -12,9 +13,11 @@
|
||||
(defn get-keypairs-success
|
||||
[{:keys [db]} [keypairs]]
|
||||
(let [parsed-keypairs (data-store/rpc->keypairs keypairs)
|
||||
default-key-uid (:key-uid (some #(when (= (:type %) :profile) %) parsed-keypairs))]
|
||||
default-key-uid (->> parsed-keypairs
|
||||
(some #(when (= (:type %) :profile) %))
|
||||
:key-uid)]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :keypairs] parsed-keypairs)
|
||||
(assoc-in [:wallet :keypairs] (utils.collection/index-by :key-uid parsed-keypairs))
|
||||
(assoc-in [:wallet :ui :create-account :selected-keypair-uid] default-key-uid))}))
|
||||
|
||||
(rf/reg-event-fx :wallet/get-keypairs-success get-keypairs-success)
|
||||
@@ -41,10 +44,10 @@
|
||||
|
||||
(defn seed-phrase-validated
|
||||
[{:keys [db]} [seed-phrase key-uid on-error]]
|
||||
(let [keypair-already-added? (->> db
|
||||
:wallet
|
||||
:keypairs
|
||||
(some #(= key-uid (:key-uid %))))]
|
||||
(let [keypair-already-added? (-> db
|
||||
:wallet
|
||||
:keypairs
|
||||
(contains? key-uid))]
|
||||
(if keypair-already-added?
|
||||
(do
|
||||
(on-error)
|
||||
@@ -121,7 +124,7 @@
|
||||
:on-success on-success
|
||||
:on-error (fn [error]
|
||||
(log/error
|
||||
"Failed to resolve next path derivation path"
|
||||
"Failed to resolve next derivation path"
|
||||
{:event :wallet/next-derivation-path
|
||||
:method "accounts_resolveSuggestedPathForKeypair"
|
||||
:error error
|
||||
@@ -188,7 +191,7 @@
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/derive-address-and-add-account
|
||||
(fn [_ [{:keys [password derived-from-address derivation-path account-preferences]}]]
|
||||
(fn [_ [{:keys [password derived-from-address derivation-path account-preferences key-uid]}]]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_getDerivedAddresses"
|
||||
:params [(security/safe-unmask-data password)
|
||||
@@ -196,9 +199,10 @@
|
||||
[derivation-path]]
|
||||
:on-success (fn [[derived-account]]
|
||||
(rf/dispatch [:wallet/add-account
|
||||
(assoc account-preferences :password password)
|
||||
(assoc account-preferences
|
||||
:key-uid key-uid
|
||||
:password password)
|
||||
derived-account]))
|
||||
:on-error #(log/info "Failed to get derived addresses"
|
||||
derived-from-address
|
||||
%)}]]]}))
|
||||
|
||||
:on-error [:wallet/log-rpc-error
|
||||
{:event :wallet/derive-address-and-add-account
|
||||
:params [derived-from-address [derivation-path]]}]}]]]}))
|
||||
|
||||
@@ -73,7 +73,7 @@
|
||||
[]
|
||||
(let [compressed-key (rf/sub [:profile/compressed-key])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
keypairs (rf/sub [:wallet/keypairs])
|
||||
keypairs (rf/sub [:wallet/keypairs-list])
|
||||
selected-keypair (rf/sub [:wallet/selected-keypair-uid])
|
||||
profile-picture (rf/sub [:profile/image])
|
||||
[selected-key-uid set-selected-key-uid] (rn/use-state selected-keypair)]
|
||||
@@ -105,8 +105,7 @@
|
||||
[quo/bottom-actions
|
||||
{:actions :one-action
|
||||
:button-one-label (i18n/label :t/confirm-account-origin)
|
||||
:button-one-props {:disabled? (= selected-keypair selected-key-uid)
|
||||
:customization-color customization-color
|
||||
:button-one-props {:customization-color customization-color
|
||||
:on-press #(rf/dispatch [:wallet/confirm-account-origin
|
||||
selected-key-uid])}
|
||||
:container-style style/bottom-action-container}]]))
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
:action-props {:on-press #(rf/dispatch [:standard-auth/authorize
|
||||
{:on-auth-success on-auth-success
|
||||
:auth-button-label (i18n/label :t/continue)}])
|
||||
|
||||
:button-text (i18n/label :t/edit)
|
||||
:icon-left :i/face-id
|
||||
:alignment :flex-start}
|
||||
@@ -70,7 +69,7 @@
|
||||
:icon-only? true
|
||||
:on-press #(rf/dispatch [:emoji-picker/open {:on-select on-select-emoji}])
|
||||
:container-style style/reaction-button-container}
|
||||
:i/reaction]])
|
||||
:i/edit]])
|
||||
|
||||
(defn- input
|
||||
[_]
|
||||
@@ -217,6 +216,7 @@
|
||||
[:wallet/derive-address-and-add-account
|
||||
{:password password
|
||||
:derived-from-address derived-from
|
||||
:key-uid key-uid
|
||||
:derivation-path @derivation-path
|
||||
:account-preferences preferences}])))
|
||||
[derived-from])]
|
||||
@@ -231,7 +231,7 @@
|
||||
{:account-color @account-color
|
||||
:slide-button-props {:on-auth-success on-auth-success
|
||||
:disabled? (or (empty? @account-name)
|
||||
(= "" @derivation-path)
|
||||
(string/blank? @derivation-path)
|
||||
(some? error))}}
|
||||
[avatar
|
||||
{:account-color @account-color
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.contexts.wallet.collectible.events
|
||||
(:require [camel-snake-kebab.extras :as cske]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.contexts.wallet.collectible.utils :as collectible-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.ethereum.chain :as chain]
|
||||
@@ -200,25 +201,35 @@
|
||||
|
||||
(rf/reg-event-fx :wallet/trigger-share-collectible
|
||||
(fn [_ [{:keys [title uri]}]]
|
||||
{:fx [[:effects.share/open
|
||||
{:title title
|
||||
:message title
|
||||
:url uri}]]}))
|
||||
{:fx [[:dispatch
|
||||
[:open-share
|
||||
{:options (if platform/ios?
|
||||
{:activityItemSources
|
||||
[{:placeholderItem {:type :text
|
||||
:content uri}
|
||||
:item {:default {:type :url
|
||||
:content uri}}
|
||||
:linkMetadata {:title title}}]}
|
||||
{:title title
|
||||
:subject title
|
||||
:url uri
|
||||
:isNewTask true})}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/share-collectible
|
||||
(fn [_ [{:keys [title uri in-sheet?]}]]
|
||||
(if in-sheet?
|
||||
(fn [{:keys [db]} [{:keys [title token-id contract-address chain-id]}]]
|
||||
(let [uri (collectible-utils/get-opensea-collectible-url
|
||||
{:chain-id chain-id
|
||||
:token-id token-id
|
||||
:contract-address contract-address
|
||||
:test-networks-enabled? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
:is-goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])})]
|
||||
{:fx [[:dispatch
|
||||
[:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 600
|
||||
:dispatch [:wallet/trigger-share-collectible
|
||||
{:title title
|
||||
:uri uri}]}]]}
|
||||
{:fx [[:dispatch
|
||||
[:wallet/trigger-share-collectible
|
||||
{:title title
|
||||
:uri uri}]]]})))
|
||||
:uri uri}]}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/navigate-to-opensea
|
||||
|
||||
@@ -7,15 +7,18 @@
|
||||
[utils.url :as url]))
|
||||
|
||||
(defn view
|
||||
[{:keys [image name chain-id address]}]
|
||||
(let [uri (url/replace-port image (rf/sub [:mediaserver/port]))]
|
||||
[{:keys [image name id]}]
|
||||
(let [chain-id (get-in id [:contract-id :chain-id])
|
||||
token-id (:token-id id)
|
||||
contract-address (get-in id [:contract-id :address])
|
||||
uri (url/replace-port image (rf/sub [:mediaserver/port]))]
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/link
|
||||
:accessibility-label :view-on-etherscan
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:wallet/navigate-to-chain-explorer-from-bottom-sheet
|
||||
(external-links/get-explorer-url-by-chain-id chain-id)
|
||||
address]))
|
||||
contract-address]))
|
||||
:label (i18n/label :t/view-on-eth)
|
||||
:right-icon :i/external}]
|
||||
[{:icon :i/save
|
||||
@@ -34,6 +37,14 @@
|
||||
:accessibility-label :share-collectible
|
||||
:label (i18n/label :t/share-collectible)
|
||||
:on-press #(rf/dispatch [:wallet/share-collectible
|
||||
{:in-sheet? true
|
||||
:title name
|
||||
:uri uri}])}]]]))
|
||||
{:token-id token-id
|
||||
:contract-address contract-address
|
||||
:chain-id chain-id
|
||||
:title name}])}]]]))
|
||||
|
||||
"222"
|
||||
"https://nft-cdn.alchemy.com/eth-mainnet/219530f9b3a7901f02169334d593823e"
|
||||
"Tengria #913"
|
||||
{:contract-id {:chain-id 1 :address "0x1a4ceef5d575c2228d142ef862a9b60be8161e7f"} :token-id "913"}
|
||||
|
||||
{:contract-id {:chain-id 1 :address "0x1a4ceef5d575c2228d142ef862a9b60be8161e7f"} :token-id "913"}
|
||||
|
||||
@@ -79,7 +79,8 @@
|
||||
(js/setTimeout #(rf/dispatch [:wallet/clear-last-collectible-details]) 700))
|
||||
|
||||
(defn animated-header
|
||||
[{:keys [scroll-amount title-opacity page-nav-type picture title description theme]}]
|
||||
[{:keys [scroll-amount title-opacity page-nav-type picture title description theme
|
||||
id]}]
|
||||
(let [blur-amount (header-animations/use-blur-amount scroll-amount)
|
||||
layer-opacity (header-animations/use-layer-opacity
|
||||
scroll-amount
|
||||
@@ -110,7 +111,8 @@
|
||||
{:content (fn []
|
||||
[options-drawer/view
|
||||
{:name title
|
||||
:image picture}])
|
||||
:image picture
|
||||
:id id}])
|
||||
:theme theme}])}]
|
||||
:center-opacity title-opacity}]]]]))
|
||||
|
||||
@@ -197,7 +199,8 @@
|
||||
[options-drawer/view
|
||||
{:name collectible-name
|
||||
:image
|
||||
preview-uri}])}])}])))
|
||||
preview-uri
|
||||
:id id}])}])}])))
|
||||
:on-collectible-load (fn []
|
||||
;; We need to delay the measurement because the
|
||||
;; navigation has an animation
|
||||
@@ -246,7 +249,8 @@
|
||||
{collection-name :name} collection-data]
|
||||
[rn/view {:style (style/background-color theme)}
|
||||
[animated-header
|
||||
{:scroll-amount scroll-amount
|
||||
{:id (:id collectible)
|
||||
:scroll-amount scroll-amount
|
||||
:title-opacity title-opacity
|
||||
:page-nav-type :title-description
|
||||
:picture preview-uri
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user