Compare commits
26
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6215acdd23 | ||
|
|
cec46f985a | ||
|
|
06b2996167 | ||
|
|
02e24208db | ||
|
|
84b8943fd4 | ||
|
|
c52b3e457e | ||
|
|
21cc8a199a | ||
|
|
59374543ef | ||
|
|
9f84a7b912 | ||
|
|
2b0847ef76 | ||
|
|
97b19c5440 | ||
|
|
b3e88508ac | ||
|
|
7b09402fcb | ||
|
|
a912125ba9 | ||
|
|
2d0437dd5e | ||
|
|
43651ef0d0 | ||
|
|
13232dc7b7 | ||
|
|
93b5f7a918 | ||
|
|
4898d32243 | ||
|
|
588692e0eb | ||
|
|
bd9e440839 | ||
|
|
940edc2e53 | ||
|
|
5a93cd755e | ||
|
|
942c130d23 | ||
|
|
bb8aad3be8 | ||
|
|
ba76b9fd51 |
@@ -4,7 +4,6 @@ DEFAULT_NETWORK=mainnet_rpc
|
||||
DEV_BUILD=1
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
|
||||
@@ -2,7 +2,7 @@ DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
FLEET=status.staging
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=0
|
||||
|
||||
@@ -3,7 +3,6 @@ DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=goerli_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=debug
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
|
||||
@@ -2,7 +2,6 @@ DEBUG_WEBVIEW=1
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ETHEREUM_DEV_CLUSTER=1
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=info
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
|
||||
@@ -2,7 +2,6 @@ DEBUG_WEBVIEW=0
|
||||
DEFAULT_NETWORK=mainnet_rpc
|
||||
ETHEREUM_DEV_CLUSTER=0
|
||||
EXTENSIONS=0
|
||||
FLEET=status.prod
|
||||
GROUP_CHATS_ENABLED=1
|
||||
LOG_LEVEL=
|
||||
MAILSERVER_CONFIRMATIONS_ENABLED=1
|
||||
|
||||
+14
-9
@@ -1,10 +1,15 @@
|
||||
*
|
||||
/*
|
||||
|
||||
# Format top-level js files.
|
||||
!*.js
|
||||
!*/
|
||||
*.clj-kondo
|
||||
*.shadow-cljs
|
||||
modules
|
||||
result
|
||||
target
|
||||
component-spec
|
||||
/app
|
||||
|
||||
# Ignore all except src/js/**/*.js
|
||||
!/src/
|
||||
/src/*
|
||||
!/src/js
|
||||
!/src/js/**/*.js
|
||||
|
||||
# Ignore all except translations/en.json
|
||||
!/translations/
|
||||
/translations/*
|
||||
!/translations/en.json
|
||||
|
||||
@@ -6,4 +6,8 @@ module.exports = {
|
||||
tabWidth: 2,
|
||||
trailingComma: 'all',
|
||||
useTabs: false,
|
||||
|
||||
// JSON sorting
|
||||
jsonSortOrder: '{ "/.*/": "caseInsensitiveLexical" } ',
|
||||
plugins: ['prettier-plugin-sort-json'],
|
||||
};
|
||||
|
||||
@@ -317,7 +317,7 @@ lint: ##@test Run code style checks
|
||||
scripts/lint/translations.clj && \
|
||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
||||
sh scripts/lint/trailing-newline.sh && \
|
||||
node_modules/.bin/prettier --write .
|
||||
node_modules/.bin/prettier --check .
|
||||
|
||||
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
||||
lint-fix: export TARGET := clojure
|
||||
|
||||
@@ -99,7 +99,7 @@ pipeline {
|
||||
--rerun_count=2 \
|
||||
--testrail_report=True \
|
||||
-m testrail_id \
|
||||
-m \"new_ui_critical or new_ui_medium\" \
|
||||
-m \"nightly\" \
|
||||
-k \"${params.KEYWORD_EXPRESSION}\" \
|
||||
--apk=${params.APK_URL ?: apk_path}
|
||||
"""
|
||||
|
||||
@@ -35,13 +35,11 @@ pipeline {
|
||||
description: 'OBSOLETE ARGUMENT TO BE REMOVED',
|
||||
defaultValue: 'DUMMY',
|
||||
)
|
||||
/* Commented to use TEST_MARKERS values from job params
|
||||
string(
|
||||
name: 'TEST_MARKERS',
|
||||
description: 'Marker expression for matching tests to run.',
|
||||
defaultValue: 'new_ui_critical',
|
||||
defaultValue: 'smoke',
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
options {
|
||||
|
||||
+2
-2
@@ -915,7 +915,7 @@ PODS:
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
- react-native-compat (2.12.2):
|
||||
- react-native-compat (2.11.2):
|
||||
- glog
|
||||
- RCT-Folly (= 2022.05.16.00)
|
||||
- React-Core
|
||||
@@ -1517,7 +1517,7 @@ SPEC CHECKSUMS:
|
||||
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
|
||||
react-native-blur: 799045500f56146afc46245148080e7b7623cb75
|
||||
react-native-cameraroll: af8eec1e585d053ff485d98ec837f9a8a11b5745
|
||||
react-native-compat: 84e00e8dcff9251278c0d48f2bce81f4502e3925
|
||||
react-native-compat: 3af9add14d349701306d3d052638435f6795ac2c
|
||||
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
|
||||
react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06
|
||||
react-native-hole-view: 6935448993bac79f2b5a4ad7e9741094cf810679
|
||||
|
||||
+2
-1
@@ -97,7 +97,8 @@
|
||||
"jest-silent-reporter": "^0.5.0",
|
||||
"nodemon": "^2.0.16",
|
||||
"nyc": "^14.1.1",
|
||||
"prettier": "^2.8.8",
|
||||
"prettier": "^3.3.3",
|
||||
"prettier-plugin-sort-json": "^4.0.0",
|
||||
"process": "0.11.10",
|
||||
"react-test-renderer": "18.1.0",
|
||||
"shadow-cljs": "2.26.2",
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
[{:keys [current-log-level
|
||||
telemetry-enabled?
|
||||
light-client-enabled?
|
||||
store-confirmations-enabled?
|
||||
current-fleet
|
||||
test-networks-enabled?
|
||||
is-goerli-enabled?
|
||||
@@ -77,6 +78,15 @@
|
||||
[:wakuv2.ui/toggle-light-client (not light-client-enabled?)])
|
||||
:accessory :switch
|
||||
:active light-client-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/store-confirmations)
|
||||
:accessibility-label :store-confirmations
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:wakuv2.ui/toggle-store-confirmations (not store-confirmations-enabled?)])
|
||||
:accessory :switch
|
||||
:active store-confirmations-enabled?}
|
||||
{:size :small
|
||||
:title "Testnet mode"
|
||||
:accessibility-label :test-networks-enabled
|
||||
@@ -114,13 +124,14 @@
|
||||
|
||||
(views/defview advanced-settings
|
||||
[]
|
||||
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
|
||||
is-goerli-enabled? [:profile/is-goerli-enabled?]
|
||||
light-client-enabled? [:profile/light-client-enabled?]
|
||||
telemetry-enabled? [:profile/telemetry-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
current-fleet [:fleets/current-fleet]
|
||||
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
|
||||
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
|
||||
is-goerli-enabled? [:profile/is-goerli-enabled?]
|
||||
light-client-enabled? [:profile/light-client-enabled?]
|
||||
store-confirmations-enabled? [:profile/store-confirmations-enabled?]
|
||||
telemetry-enabled? [:profile/telemetry-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
current-fleet [:fleets/current-fleet]
|
||||
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
|
||||
[:<>
|
||||
[quo/page-nav
|
||||
{:type :title
|
||||
@@ -130,13 +141,14 @@
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
[list/flat-list
|
||||
{:data (flat-list-data
|
||||
{:current-log-level current-log-level
|
||||
:telemetry-enabled? telemetry-enabled?
|
||||
:light-client-enabled? light-client-enabled?
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:is-goerli-enabled? is-goerli-enabled?
|
||||
:peer-syncing-enabled? peer-syncing-enabled?})
|
||||
{:current-log-level current-log-level
|
||||
:telemetry-enabled? telemetry-enabled?
|
||||
:light-client-enabled? light-client-enabled?
|
||||
:store-confirmations-enabled? store-confirmations-enabled?
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:is-goerli-enabled? is-goerli-enabled?
|
||||
:peer-syncing-enabled? peer-syncing-enabled?})
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn render-item}]]))
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
(ns legacy.status-im.utils.hex
|
||||
(:require
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defn normalize-hex
|
||||
[hex]
|
||||
(when hex
|
||||
(string/lower-case (if (string/starts-with? hex "0x")
|
||||
(subs hex 2)
|
||||
hex))))
|
||||
|
||||
(defn valid-hex?
|
||||
[hex]
|
||||
(let [hex (normalize-hex hex)]
|
||||
(and (re-matches #"^[0-9a-fA-F]+$" hex)
|
||||
(not= (js/parseInt hex 16) 0))))
|
||||
@@ -137,3 +137,19 @@
|
||||
:on-error #(log/error "failed to set light client"
|
||||
{:error %
|
||||
:enabled? enabled?})}]})
|
||||
|
||||
(rf/defn toggle-store-confirmations
|
||||
{:events [:wakuv2.ui/toggle-store-confirmations]}
|
||||
[{:keys [db]} enabled?]
|
||||
{:db (assoc-in db
|
||||
[:profile/profile :wakuv2-config :EnableStoreConfirmationForMessagesSent]
|
||||
enabled?)
|
||||
|
||||
:json-rpc/call [{:method "wakuext_setStoreConfirmationForMessagesSent"
|
||||
:params [{:enabled enabled?}]
|
||||
:on-success (fn []
|
||||
(log/info "store confirmation set successfully" enabled?)
|
||||
(re-frame/dispatch [:logout]))
|
||||
:on-error #(log/error "failed to set store confirmation"
|
||||
{:error %
|
||||
:enabled? enabled?})}]})
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns quo.components.avatars.token-avatar.view
|
||||
(:require [quo.components.avatars.token-avatar.style :as style]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[react-native.core :as rn]
|
||||
[react-native.hole-view :as hole-view]
|
||||
[react-native.platform :as platform]
|
||||
@@ -12,13 +13,14 @@
|
||||
[:map {:closed true}
|
||||
[:type {:optional true} [:enum :asset :collectible]]
|
||||
[:context? {:optional true} [:maybe :boolean]]
|
||||
[:image :schema.common/image-source]
|
||||
[:image {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:token {:optional true} [:maybe [:or :keyword :string]]]
|
||||
[:network-image {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type context? image network-image container-style]}]
|
||||
[{:keys [type context? image token network-image container-style]}]
|
||||
[rn/view
|
||||
{:style (merge style/container container-style)
|
||||
:accessibility-label :token-avatar}
|
||||
@@ -32,9 +34,11 @@
|
||||
[])
|
||||
:style style/hole-view}
|
||||
platform/android? (assoc :key context?))
|
||||
[rn/image
|
||||
{:source image
|
||||
:style (style/image type)}]]
|
||||
[token/view
|
||||
{:size :size-32
|
||||
:token token
|
||||
:style (style/image type)
|
||||
:image-source image}]]
|
||||
(when context?
|
||||
[rn/image
|
||||
{:source network-image
|
||||
|
||||
@@ -21,15 +21,17 @@
|
||||
(colors/theme-colors colors/white colors/neutral-95 theme))})
|
||||
|
||||
(defn buttons-container
|
||||
[actions]
|
||||
{:flex-direction (if (= actions :two-vertical-actions) :column :row)
|
||||
:justify-content :space-around
|
||||
:padding-vertical 12
|
||||
:gap 12
|
||||
:padding-horizontal 20})
|
||||
[actions container-style]
|
||||
(merge
|
||||
{:flex-direction (if (= actions :two-vertical-actions) :column :row)
|
||||
:justify-content :space-around
|
||||
:padding-vertical 12
|
||||
:gap 12
|
||||
:padding-horizontal 20}
|
||||
container-style))
|
||||
|
||||
(def button-container
|
||||
{:flex 1})
|
||||
{:flex-grow 1})
|
||||
|
||||
(def description-top
|
||||
{:flex-direction :row
|
||||
|
||||
@@ -30,7 +30,8 @@
|
||||
[:button-two-props {:optional true} [:maybe :map]]
|
||||
[:scroll? {:optional true} [:maybe :boolean]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
[:buttons-container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(def ^:private role-icon
|
||||
@@ -42,7 +43,7 @@
|
||||
(defn- view-internal
|
||||
[{:keys [actions description description-text description-top-text error-message role button-one-label
|
||||
button-two-label blur? button-one-props button-two-props scroll? container-style
|
||||
context-tag-props]}]
|
||||
buttons-container-style context-tag-props]}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view
|
||||
{:style (merge (style/container scroll? blur? theme) container-style)}
|
||||
@@ -72,14 +73,14 @@
|
||||
:context (i18n/label (keyword "t" role))}
|
||||
context-tag-props)]])
|
||||
|
||||
[rn/view {:style (style/buttons-container actions)}
|
||||
[rn/view {:style (style/buttons-container actions buttons-container-style)}
|
||||
(when (or (= actions :two-actions)
|
||||
(= actions :two-vertical-actions))
|
||||
[button/button
|
||||
(merge
|
||||
{:size 40
|
||||
:background (when (or blur? scroll?) :blur)
|
||||
:container-style style/button-container
|
||||
:background (when (or blur? scroll?) :blur)
|
||||
:theme theme
|
||||
:accessibility-label :button-two}
|
||||
button-two-props)
|
||||
|
||||
@@ -79,14 +79,20 @@
|
||||
[counter-view counter])
|
||||
[rn/view {:style (style/collectible-border theme)}]]]))
|
||||
|
||||
(defn invalid-image?
|
||||
[image-src]
|
||||
(or (nil? image-src)
|
||||
(string/blank? image-src)))
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [container-style square? on-press counter image-src native-ID supported-file?
|
||||
on-collectible-load aspect-ratio gradient-color-index]
|
||||
:or {gradient-color-index :gradient-1
|
||||
on-collectible-load (fn [])}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
[error? set-error] (rn/use-state (or (nil? image-src)
|
||||
(string/blank? image-src)))]
|
||||
[error? set-error] (rn/use-state (invalid-image? image-src))]
|
||||
(rn/use-effect #(set-error (invalid-image? image-src))
|
||||
[image-src])
|
||||
[rn/pressable
|
||||
{:style (merge container-style (style/container aspect-ratio))
|
||||
:accessibility-label :expanded-collectible
|
||||
|
||||
@@ -121,6 +121,7 @@
|
||||
[:card? {:optional true} [:maybe :boolean]]
|
||||
[:right-icon {:optional true} [:maybe :keyword]]
|
||||
[:right-content {:optional true} [:maybe :map]]
|
||||
[:icon-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:status {:optional true} [:maybe [:enum :default :loading]]]
|
||||
[:subtitle-type {:optional true} [:maybe [:enum :default :icon :network :account :editable]]]
|
||||
[:size {:optional true} [:maybe [:enum :default :small :large]]]
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
(ns quo.components.slideshow.slider-bar.component-spec
|
||||
(:require
|
||||
[quo.components.slideshow.slider-bar.view :as slider-bar]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Slideshow: slider-bar"
|
||||
(h/test "default render"
|
||||
(h/render-with-theme-provider [slider-bar/view {:accessibility-label :slider-bar}])
|
||||
(h/is-truthy (h/query-by-label-text :slider-bar)))
|
||||
|
||||
(h/test "render with total-amount and active-index"
|
||||
(h/render-with-theme-provider [slider-bar/view
|
||||
{:total-amount 4
|
||||
:active-index 1
|
||||
:accessibility-label :slider-bar}])
|
||||
(h/is-truthy (h/query-by-label-text :slider-bar))
|
||||
(h/is-equal 4 (count (h/query-all-by-label-text :slide-bar-item))))
|
||||
|
||||
(h/test "render with total-amount active-index and possible scroll"
|
||||
(h/render-with-theme-provider [slider-bar/view
|
||||
{:total-amount 10
|
||||
:active-index 7
|
||||
:accessibility-label :slider-bar}])
|
||||
(h/is-truthy (h/query-by-label-text :slider-bar))
|
||||
(h/is-equal 10 (count (h/query-all-by-label-text :slide-bar-item)))))
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns quo.components.slideshow.slider-bar.schema)
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map {:closed true}
|
||||
[:total-amount {:optional true} [:maybe :int]]
|
||||
[:active-index {:optional true} :int]
|
||||
[:customization-color {:optional true}
|
||||
[:maybe :schema.common/customization-color]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:accessibility-label {:optional true} [:maybe :keyword]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]
|
||||
:any])
|
||||
@@ -0,0 +1,31 @@
|
||||
(ns quo.components.slideshow.slider-bar.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def list-wrapper
|
||||
{:align-items :center})
|
||||
|
||||
(defn list-bar
|
||||
[bar-width]
|
||||
{:width bar-width})
|
||||
|
||||
(defn item-wrapper
|
||||
[{:keys [size spacing]}]
|
||||
{:width size
|
||||
:height size
|
||||
:margin-left spacing
|
||||
:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(defn item
|
||||
[{:keys [size spacing active? customization-color theme blur?]}]
|
||||
{:width size
|
||||
:height size
|
||||
:border-radius spacing
|
||||
:background-color
|
||||
(cond
|
||||
(and blur? active?) colors/white
|
||||
(and blur? (not active?)) colors/white-opa-10
|
||||
(and (not blur?) active?) (colors/resolve-color customization-color theme)
|
||||
:else (colors/theme-colors colors/neutral-20 colors/neutral-80 theme))})
|
||||
@@ -0,0 +1,150 @@
|
||||
(ns quo.components.slideshow.slider-bar.view
|
||||
(:require
|
||||
[quo.components.slideshow.slider-bar.schema :as component-schema]
|
||||
[quo.components.slideshow.slider-bar.style :as style]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(def item-size 8)
|
||||
(def item-spacing item-size)
|
||||
(def max-length 6)
|
||||
(def bar-width (* (+ item-spacing item-size) max-length))
|
||||
|
||||
(def micro-scale 0.25)
|
||||
(def small-scale 0.5)
|
||||
(def medium-scale 0.75)
|
||||
(def default-scale 1)
|
||||
|
||||
(def items-before-scroll
|
||||
(/ max-length 2))
|
||||
|
||||
(defn- calc-relative-index
|
||||
"Calculates item index in visible area"
|
||||
[index active-index total-length]
|
||||
(let [last-index (dec total-length)]
|
||||
(cond
|
||||
(< active-index items-before-scroll) index
|
||||
(> active-index
|
||||
(- last-index items-before-scroll)) (+ (- index total-length) max-length)
|
||||
:else (+ (- index active-index) items-before-scroll))))
|
||||
|
||||
(defn- calc-first-item-scale
|
||||
"Calculates scale for first item in visible area"
|
||||
[active-index]
|
||||
(cond
|
||||
(= active-index items-before-scroll) medium-scale
|
||||
(> active-index items-before-scroll) small-scale
|
||||
:else default-scale))
|
||||
|
||||
(defn- calc-second-item-scale
|
||||
"Calculates scale for second item in visible area"
|
||||
[active-index]
|
||||
(if (> active-index items-before-scroll)
|
||||
medium-scale
|
||||
default-scale))
|
||||
|
||||
(defn- calc-last-item-scale
|
||||
"Calculates scale for last item in visible area"
|
||||
[active-index total-length]
|
||||
(let [last-index (dec total-length)]
|
||||
(if (> active-index (- last-index items-before-scroll))
|
||||
medium-scale
|
||||
small-scale)))
|
||||
|
||||
(defn- calc-last-but-one-item-scale
|
||||
"Calculates scale for before last item in visible area"
|
||||
[active-index total-length]
|
||||
(if (> active-index (- (dec total-length) items-before-scroll))
|
||||
default-scale
|
||||
medium-scale))
|
||||
|
||||
(defn- get-scale
|
||||
[index active-index total-length]
|
||||
(let [relative-index (calc-relative-index index active-index total-length)]
|
||||
(if (or (= index active-index)
|
||||
(< total-length max-length))
|
||||
default-scale
|
||||
(cond
|
||||
(< relative-index 0) micro-scale
|
||||
(= relative-index 0) (calc-first-item-scale active-index)
|
||||
(= relative-index 1) (calc-second-item-scale active-index)
|
||||
(= relative-index 4) (calc-last-but-one-item-scale active-index total-length)
|
||||
(= relative-index 5) (calc-last-item-scale active-index total-length)
|
||||
(> relative-index 5) micro-scale
|
||||
:else
|
||||
default-scale))))
|
||||
|
||||
(defn- bar-item
|
||||
[index _ _ {:keys [active-index total-length customization-color theme blur?]}]
|
||||
(let [active? (= index active-index)
|
||||
shared-scale (reanimated/use-shared-value (get-scale index active-index total-length))]
|
||||
(rn/use-effect (fn []
|
||||
(let [new-scale-value (get-scale index active-index total-length)]
|
||||
(reanimated/animate shared-scale new-scale-value)))
|
||||
[index active-index total-length])
|
||||
[rn/view
|
||||
{:key index
|
||||
:style (style/item-wrapper {:size item-size
|
||||
:spacing item-spacing})}
|
||||
[reanimated/view
|
||||
{:accessibility-label :slide-bar-item
|
||||
:style
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:scale shared-scale}]}
|
||||
(style/item {:size item-size
|
||||
:spacing item-spacing
|
||||
:active? active?
|
||||
:customization-color customization-color
|
||||
:theme theme
|
||||
:blur? blur?}))}]]))
|
||||
|
||||
(defn- get-item-layout
|
||||
[_ index]
|
||||
(let [length (+ item-size item-spacing)]
|
||||
#js {:length length
|
||||
:index index
|
||||
:offset (* index length)}))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [customization-color blur? accessibility-label container-style]
|
||||
:as props}]
|
||||
(let [active-index (or (:active-index props) 0)
|
||||
total-amount (or (:total-amount props) 1)
|
||||
theme (quo.theme/use-theme)
|
||||
flat-list-ref (rn/use-ref-atom nil)
|
||||
set-flat-list-ref (rn/use-callback #(reset! flat-list-ref %))
|
||||
center-position 0.5
|
||||
data (range total-amount)
|
||||
scroll-to-index (rn/use-callback
|
||||
(fn []
|
||||
(some-> ^js @flat-list-ref
|
||||
(.scrollToIndex #js {:animated true
|
||||
:index active-index
|
||||
:viewOffset item-spacing
|
||||
:viewPosition center-position})))
|
||||
[flat-list-ref active-index])]
|
||||
(rn/use-effect scroll-to-index [active-index])
|
||||
[rn/view
|
||||
{:style (merge style/list-wrapper container-style)
|
||||
:accessibility-label accessibility-label}
|
||||
[reanimated/flat-list
|
||||
{:style (style/list-bar bar-width)
|
||||
:data data
|
||||
:scroll-enabled false
|
||||
:ref set-flat-list-ref
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:bounces false
|
||||
:horizontal true
|
||||
:extra-data (str active-index)
|
||||
:render-data {:active-index active-index
|
||||
:total-length total-amount
|
||||
:customization-color customization-color
|
||||
:theme theme
|
||||
:blur? blur?}
|
||||
:get-item-layout get-item-layout
|
||||
:render-fn bar-item
|
||||
:key-fn identity}]]))
|
||||
|
||||
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||
@@ -53,7 +53,7 @@
|
||||
(def ^:private ?network
|
||||
[:map
|
||||
[:network-logo {:optional true} [:maybe :schema.common/image-source]]
|
||||
[:network-name {:optional true} [:maybe :string]]])
|
||||
[:network-name {:optional true} [:maybe [:or :string :keyword]]]])
|
||||
|
||||
(def ^:private ?multinetwork
|
||||
[:map
|
||||
|
||||
@@ -41,7 +41,8 @@
|
||||
:align-items :center
|
||||
:height size
|
||||
:background-color background-color
|
||||
:border-radius border-radius}
|
||||
:border-radius border-radius
|
||||
:flex-shrink 1}
|
||||
(= state :selected) (assoc :height (+ size 2)
|
||||
:border-color border-color
|
||||
:border-width 1))))
|
||||
@@ -50,11 +51,13 @@
|
||||
[size]
|
||||
{:margin-right (if (= size 24) 6 10)
|
||||
:flex-direction :row
|
||||
:flex-shrink 1
|
||||
:align-items :center})
|
||||
|
||||
(defn tag-spacing
|
||||
[size]
|
||||
{:margin-left (if (= size 24) 4 8)})
|
||||
[size shrinkable?]
|
||||
(cond-> {:margin-left (if (= size 24) 4 8)}
|
||||
shrinkable? (assoc :flex-shrink 1)))
|
||||
|
||||
(defn text
|
||||
[theme]
|
||||
|
||||
@@ -17,17 +17,19 @@
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- tag-skeleton
|
||||
[{:keys [size text theme]
|
||||
[{:keys [size text theme shrinkable?]
|
||||
:or {size 24
|
||||
theme (quo.theme/use-theme)}}
|
||||
logo-component]
|
||||
[rn/view {:style (style/tag-container size)}
|
||||
logo-component
|
||||
[rn/view {:style (style/tag-spacing size)}
|
||||
[rn/view {:style (style/tag-spacing size shrinkable?)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)}
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)
|
||||
:number-of-lines 1
|
||||
:ellipsize-mode :middle}
|
||||
text]]])
|
||||
|
||||
(defn- communities-tag
|
||||
@@ -37,7 +39,7 @@
|
||||
icon-size (if (= size 24) 16 20)]
|
||||
[rn/view {:style (style/tag-container size)}
|
||||
[fast-image/fast-image {:style (style/circle-logo size) :source community-logo}]
|
||||
[rn/view {:style (style/tag-spacing size)}
|
||||
[rn/view {:style (style/tag-spacing size false)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
@@ -148,9 +150,10 @@
|
||||
|
||||
:collectible
|
||||
[tag-skeleton
|
||||
{:theme theme
|
||||
:size size
|
||||
:text (str collectible-name " #" collectible-number)}
|
||||
{:theme theme
|
||||
:size size
|
||||
:text (str collectible-name " #" collectible-number)
|
||||
:shrinkable? true}
|
||||
[rn/image {:style (style/rounded-logo size) :source collectible}]]
|
||||
|
||||
:account
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
(ns quo.components.wallet.swap-input.component-spec
|
||||
(:require [quo.components.wallet.swap-input.view :as swap-input]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Wallet: Swap Input"
|
||||
(h/test "should render correctly with props"
|
||||
(h/render-with-theme-provider
|
||||
[swap-input/view
|
||||
{:type :pay
|
||||
:error? false
|
||||
:token "SNT"
|
||||
:status :default
|
||||
:currency-symbol "€"
|
||||
:value "5"
|
||||
:fiat-value "1.50"
|
||||
:network-tag-props {:title "Max: 200 SNT"}}])
|
||||
(h/is-truthy (h/get-by-label-text :swap-input))
|
||||
(h/is-truthy (h/get-by-text "SNT"))
|
||||
(h/is-truthy (h/get-by-text "€1.50"))
|
||||
(h/is-truthy (h/get-by-text "Max: 200 SNT")))
|
||||
|
||||
(h/test "should render correctly with approval label"
|
||||
(h/render-with-theme-provider
|
||||
[swap-input/view
|
||||
{:type :pay
|
||||
:show-approval-label? true
|
||||
:approval-label-props
|
||||
{:status :approve
|
||||
:token-value "10"
|
||||
:token-symbol "SNT"}}])
|
||||
(h/is-truthy (h/get-by-text "Approve 10 SNT"))))
|
||||
@@ -0,0 +1,74 @@
|
||||
(ns quo.components.wallet.swap-input.style
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[quo.foundations.typography :as typography]))
|
||||
|
||||
(defn- border-color
|
||||
[theme]
|
||||
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))
|
||||
|
||||
(defn- loader-color
|
||||
[theme]
|
||||
(colors/theme-colors colors/neutral-5 colors/neutral-90 theme))
|
||||
|
||||
(defn content
|
||||
[theme]
|
||||
{:border-width 1
|
||||
:border-radius 16
|
||||
:border-color (border-color theme)
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
|
||||
|
||||
(defn row-1
|
||||
[loading?]
|
||||
{:padding 12
|
||||
:gap 8
|
||||
:align-items (if loading? :center :flex-end)
|
||||
:flex-direction :row})
|
||||
|
||||
(defn row-1-loader
|
||||
[theme]
|
||||
{:width 74
|
||||
:height 14
|
||||
:border-radius 6
|
||||
:background-color (loader-color theme)})
|
||||
|
||||
(def input-container
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:gap 5
|
||||
:height 32
|
||||
:align-items :flex-end})
|
||||
|
||||
(defn input
|
||||
[disabled? error? theme]
|
||||
(assoc typography/font-semi-bold
|
||||
:font-size 27
|
||||
:flex-shrink 1
|
||||
:padding 0
|
||||
:color (cond
|
||||
error? (colors/resolve-color :danger theme)
|
||||
disabled? (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:else (colors/theme-colors colors/neutral-100 colors/white theme))
|
||||
:line-height 32))
|
||||
|
||||
(defn token-symbol
|
||||
[theme]
|
||||
{:padding-bottom 3
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
|
||||
|
||||
(defn row-2
|
||||
[align-right?]
|
||||
{:flex-direction :row
|
||||
:justify-content (if align-right? :flex-end :space-between)
|
||||
:align-items :center
|
||||
:padding 12})
|
||||
|
||||
(defn row-2-loader
|
||||
[theme]
|
||||
{:width 80
|
||||
:height 10
|
||||
:margin-vertical 7
|
||||
:border-radius 6
|
||||
:background-color (loader-color theme)})
|
||||
|
||||
(def fiat-amount
|
||||
{:color colors/neutral-50})
|
||||
@@ -0,0 +1,121 @@
|
||||
(ns quo.components.wallet.swap-input.view
|
||||
(:require [oops.core :as oops]
|
||||
[quo.components.avatars.token-avatar.view :as token-avatar]
|
||||
[quo.components.buttons.button.view :as buttons]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.network-tags.view :as network-tag]
|
||||
[quo.components.wallet.approval-label.schema :as approval-label.schema]
|
||||
[quo.components.wallet.approval-label.view :as approval-label]
|
||||
[quo.components.wallet.swap-input.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
quo.theme
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:type {:optional true} [:maybe [:enum :pay :receive]]]
|
||||
[:status {:optional true} [:maybe [:enum :default :disabled :loading]]]
|
||||
[:token {:optional true} [:maybe :string]]
|
||||
[:value {:optional true} [:maybe :string]]
|
||||
[:default-value {:optional true} [:maybe :string]]
|
||||
[:currency-symbol {:optional true} [:maybe :string]]
|
||||
[:fiat-value {:optional true} [:maybe :string]]
|
||||
[:show-approval-label? {:optional true} [:maybe :boolean]]
|
||||
[:error? {:optional true} [:maybe :boolean]]
|
||||
[:show-keyboard? {:optional true} [:maybe :boolean]]
|
||||
[:approval-label-props {:optional true} [:maybe approval-label.schema/?schema]]
|
||||
[:network-tag-props {:optional true} [:maybe :map]]
|
||||
[:on-change-text {:optional true} [:maybe fn?]]
|
||||
[:enable-swap? {:optional true} [:maybe :boolean]]
|
||||
[:on-swap-press {:optional true} [:maybe fn?]]
|
||||
[:on-token-press {:optional true} [:maybe fn?]]
|
||||
[:on-max-press {:optional true} [:maybe fn?]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]]
|
||||
:any])
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [type status token value fiat-value show-approval-label? error? network-tag-props
|
||||
approval-label-props default-value enable-swap?
|
||||
currency-symbol on-change-text show-keyboard?
|
||||
container-style on-swap-press on-token-press on-max-press]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
pay? (= type :pay)
|
||||
disabled? (= status :disabled)
|
||||
loading? (= status :loading)
|
||||
controlled-input? (some? value)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
set-input-ref (rn/use-callback (fn [ref] (reset! input-ref ref)) [])
|
||||
focus-input (rn/use-callback (fn []
|
||||
(some-> @input-ref
|
||||
(oops/ocall "focus")))
|
||||
[input-ref])]
|
||||
[rn/view
|
||||
{:style container-style
|
||||
:accessibility-label :swap-input}
|
||||
[rn/view {:style (style/content theme)}
|
||||
[rn/view
|
||||
{:style (style/row-1 loading?)}
|
||||
[rn/pressable {:on-press on-token-press}
|
||||
[token-avatar/view
|
||||
{:type :asset
|
||||
:token token}]]
|
||||
(if loading?
|
||||
[rn/view {:style (style/row-1-loader theme)}]
|
||||
[:<>
|
||||
[rn/pressable
|
||||
{:style style/input-container
|
||||
:on-press focus-input}
|
||||
[rn/text-input
|
||||
(cond-> {:ref set-input-ref
|
||||
:style (style/input disabled? error? theme)
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40
|
||||
colors/neutral-50
|
||||
theme)
|
||||
:keyboard-type :numeric
|
||||
:auto-focus true
|
||||
:on-change-text on-change-text
|
||||
:show-soft-input-on-focus show-keyboard?
|
||||
:default-value default-value
|
||||
:placeholder "0"}
|
||||
controlled-input? (assoc :value value))]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style (style/token-symbol theme)}
|
||||
token]]
|
||||
(when (and pay? enable-swap?)
|
||||
[buttons/button
|
||||
{:type :outline
|
||||
:size 32
|
||||
:on-press on-swap-press
|
||||
:icon-only? true}
|
||||
:i/reorder])])]
|
||||
[divider-line/view]
|
||||
[rn/view
|
||||
{:style (style/row-2 (or (not pay?) loading?))}
|
||||
(when-not loading?
|
||||
[:<>
|
||||
(when pay?
|
||||
[rn/pressable {:on-press on-max-press}
|
||||
[network-tag/view
|
||||
(assoc network-tag-props
|
||||
:status
|
||||
(if error? :error :default))]])
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style style/fiat-amount
|
||||
:weight :medium}
|
||||
(str currency-symbol fiat-value)]])
|
||||
(when loading?
|
||||
[rn/view {:style (style/row-2-loader theme)}])]]
|
||||
(when (and (not= status :loading) (= type :pay) show-approval-label?)
|
||||
[approval-label/view
|
||||
approval-label-props])]))
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
||||
@@ -51,8 +51,7 @@
|
||||
|
||||
(defn prop-text
|
||||
[theme]
|
||||
{:margin-right 4
|
||||
:color (colors/theme-colors colors/neutral-100 colors/white theme)})
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)})
|
||||
|
||||
(def icon-container
|
||||
{:width 32
|
||||
@@ -61,12 +60,15 @@
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
:flex 1
|
||||
:column-gap 8})
|
||||
|
||||
(def content-line
|
||||
{:flex-direction :row
|
||||
:margin-top 2
|
||||
:align-items :center})
|
||||
{:flex-direction :row
|
||||
:margin-top 2
|
||||
:align-items :center
|
||||
:column-gap 4
|
||||
:justify-content :flex-start})
|
||||
|
||||
(def icon-hole-view
|
||||
{:width 32
|
||||
|
||||
@@ -98,8 +98,11 @@
|
||||
|
||||
(defn prop-tag
|
||||
[props blur?]
|
||||
[rn/view {:style {:margin-right 4}}
|
||||
[context-tag/view (merge props {:size 24 :blur? blur?})]])
|
||||
[context-tag/view
|
||||
(assoc props
|
||||
:size 24
|
||||
:blur? blur?
|
||||
:container-style {:flex-shrink 1})])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [state blur? first-tag second-tag third-tag fourth-tag on-press
|
||||
@@ -121,7 +124,7 @@
|
||||
:on-press-out on-press-out}
|
||||
[rn/view {:style style/container}
|
||||
[transaction-icon-view props theme]
|
||||
[rn/view
|
||||
[rn/view {:style {:flex 1}}
|
||||
[transaction-header props theme]
|
||||
[rn/view {:style style/content-line}
|
||||
(when first-tag [prop-tag first-tag blur?])
|
||||
|
||||
@@ -147,6 +147,7 @@
|
||||
quo.components.settings.settings-item.view
|
||||
quo.components.share.qr-code.view
|
||||
quo.components.share.share-qr-code.view
|
||||
quo.components.slideshow.slider-bar.view
|
||||
quo.components.switchers.group-messaging-card.view
|
||||
quo.components.tabs.account-selector
|
||||
quo.components.tabs.segmented-tab
|
||||
@@ -185,6 +186,7 @@
|
||||
quo.components.wallet.progress-bar.view
|
||||
quo.components.wallet.required-tokens.view
|
||||
quo.components.wallet.summary-info.view
|
||||
quo.components.wallet.swap-input.view
|
||||
quo.components.wallet.token-input.view
|
||||
quo.components.wallet.transaction-progress.view
|
||||
quo.components.wallet.transaction-summary.view
|
||||
@@ -418,6 +420,9 @@
|
||||
(def qr-code quo.components.share.qr-code.view/view)
|
||||
(def share-qr-code quo.components.share.share-qr-code.view/view)
|
||||
|
||||
;;;; Slideshow
|
||||
(def slider-bar quo.components.slideshow.slider-bar.view/view)
|
||||
|
||||
;;;; SWITCHER
|
||||
(def group-messaging-card quo.components.switchers.group-messaging-card.view/view)
|
||||
|
||||
@@ -468,6 +473,7 @@
|
||||
(def progress-bar quo.components.wallet.progress-bar.view/view)
|
||||
(def required-tokens quo.components.wallet.required-tokens.view/view)
|
||||
(def summary-info quo.components.wallet.summary-info.view/view)
|
||||
(def swap-input quo.components.wallet.swap-input.view/view)
|
||||
(def network-link quo.components.wallet.network-link.view/view)
|
||||
(def token-input quo.components.wallet.token-input.view/view)
|
||||
(def wallet-overview quo.components.wallet.wallet-overview.view/view)
|
||||
|
||||
@@ -87,6 +87,7 @@
|
||||
quo.components.settings.reorder-item.component-spec
|
||||
quo.components.settings.settings-item.component-spec
|
||||
quo.components.share.share-qr-code.component-spec
|
||||
quo.components.slideshow.slider-bar.component-spec
|
||||
quo.components.switchers.base-card.component-spec
|
||||
quo.components.switchers.group-messaging-card.component-spec
|
||||
quo.components.tags.collectible-tag.component-spec
|
||||
@@ -111,6 +112,7 @@
|
||||
quo.components.wallet.progress-bar.component-spec
|
||||
quo.components.wallet.required-tokens.component-spec
|
||||
quo.components.wallet.summary-info.component-spec
|
||||
quo.components.wallet.swap-input.component-spec
|
||||
quo.components.wallet.token-input.component-spec
|
||||
quo.components.wallet.transaction-progress.component-spec
|
||||
quo.components.wallet.transaction-summary.component-spec
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
set-animating-true #(reset! animating? true)
|
||||
set-animating-false (fn [ms]
|
||||
(js/setTimeout #(reset! animating? false) ms))]
|
||||
(fn [{:keys [content skip-background?]}]
|
||||
(fn [{:keys [content skip-background? on-dismiss]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
{:keys [top] :as insets} (safe-area/get-insets)
|
||||
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
|
||||
@@ -63,6 +63,10 @@
|
||||
(reanimated/animate opacity 0 300)
|
||||
(rf/dispatch [:navigate-back])
|
||||
true)
|
||||
dismiss (fn []
|
||||
(when on-dismiss
|
||||
(on-dismiss))
|
||||
(close))
|
||||
reset-open-sheet (fn []
|
||||
(reanimated/animate translate-y 0 300)
|
||||
(reanimated/animate opacity 1 300)
|
||||
@@ -83,7 +87,7 @@
|
||||
:opacity opacity
|
||||
:scroll-enabled? scroll-enabled?
|
||||
:curr-scroll curr-scroll
|
||||
:close close
|
||||
:close dismiss
|
||||
:reset-open-sheet reset-open-sheet
|
||||
:set-animating-true set-animating-true})}
|
||||
[reanimated/view {:style (style/main-view translate-y theme)}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.common.floating-button-page.floating-container.style
|
||||
(:require [react-native.safe-area :as safe-area]))
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn content-container
|
||||
[blur? keyboard-shown?]
|
||||
@@ -11,7 +12,12 @@
|
||||
:padding-horizontal 20}
|
||||
blur? (dissoc :padding-vertical :padding-horizontal))))
|
||||
|
||||
(def blur-inner-container
|
||||
{:background-color :transparent ; required, otherwise blur-view will shrink
|
||||
(defn blur-inner-container
|
||||
[theme shell-overlay?]
|
||||
{:background-color (colors/theme-colors colors/white-70-blur
|
||||
(if shell-overlay?
|
||||
colors/neutral-80-opa-80-blur
|
||||
colors/neutral-95-opa-70-blur)
|
||||
theme)
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20})
|
||||
|
||||
@@ -1,27 +1,25 @@
|
||||
(ns status-im.common.floating-button-page.floating-container.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.floating-container.style :as style]))
|
||||
|
||||
(defn- blur-container
|
||||
[child]
|
||||
[child shell-overlay?]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[quo/blur
|
||||
{:blur-amount 52
|
||||
:blur-radius 20
|
||||
:blur-type :transparent
|
||||
:blur-overlay-color (colors/theme-colors colors/white-70-blur colors/neutral-95-opa-70-blur theme)}
|
||||
[rn/view {:style style/blur-inner-container}
|
||||
{:blur-amount 20
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}
|
||||
[rn/view {:style (style/blur-inner-container theme shell-overlay?)}
|
||||
child]]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-layout keyboard-shown? blur?]} child]
|
||||
[{:keys [on-layout keyboard-shown? blur? shell-overlay?]} child]
|
||||
[rn/view
|
||||
{:style (style/content-container blur? keyboard-shown?)
|
||||
:on-layout on-layout}
|
||||
(if blur?
|
||||
[blur-container child]
|
||||
[blur-container child shell-overlay?]
|
||||
child)])
|
||||
|
||||
@@ -58,7 +58,7 @@
|
||||
|
||||
(defn view
|
||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps]
|
||||
content-container-style gradient-cover? keyboard-should-persist-taps shell-overlay?]
|
||||
:or {footer-container-padding (safe-area/get-top)}}
|
||||
& children]
|
||||
(reagent/with-let [scroll-view-ref (atom nil)
|
||||
@@ -121,7 +121,8 @@
|
||||
[floating-container/view
|
||||
{:on-layout set-footer-container-height
|
||||
:keyboard-shown? keyboard-shown?
|
||||
:blur? show-background?}
|
||||
:blur? show-background?
|
||||
:shell-overlay? shell-overlay?}
|
||||
footer]]]])
|
||||
(finally
|
||||
(remove-listeners))))
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns status-im.common.metrics-confirmation-modal.style)
|
||||
|
||||
(def points-wrapper
|
||||
{:margin-top 11
|
||||
:margin-horizontal 20
|
||||
:gap 21
|
||||
:margin-bottom 15})
|
||||
|
||||
(def item-text
|
||||
{:margin-top 10
|
||||
:margin-left -4})
|
||||
|
||||
(def info-text
|
||||
{:margin-top -5})
|
||||
@@ -0,0 +1,79 @@
|
||||
(ns status-im.common.metrics-confirmation-modal.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.metrics-confirmation-modal.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- dismiss-keyboard
|
||||
[]
|
||||
(rf/dispatch [:dismiss-keyboard]))
|
||||
|
||||
(defn- hide-bottom-sheet
|
||||
[]
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
|
||||
(defn- toggle-metrics
|
||||
[enabled?]
|
||||
(rf/dispatch [:centralized-metrics/toggle-centralized-metrics enabled?]))
|
||||
|
||||
(def ^:private will-receive-points
|
||||
[:t/ip-address
|
||||
:t/universally-unique-identifiers-of-device
|
||||
:t/logs-of-actions-withing-the-app])
|
||||
|
||||
(def ^:private not-receive-points
|
||||
[:t/your-profile-information
|
||||
:t/your-addresses
|
||||
:t/information-you-input-and-send])
|
||||
|
||||
(defn- bullet-points
|
||||
[{:keys [title points]}]
|
||||
[rn/view
|
||||
[quo/text {:weight :semi-bold}
|
||||
title]
|
||||
(for [label points]
|
||||
^{:key label}
|
||||
[quo/markdown-list
|
||||
{:description (i18n/label label)
|
||||
:blur? true
|
||||
:container-style style/item-text}])])
|
||||
|
||||
(defn- on-share-usage
|
||||
[]
|
||||
(toggle-metrics true)
|
||||
(hide-bottom-sheet))
|
||||
|
||||
(defn- on-do-not-share
|
||||
[]
|
||||
(toggle-metrics false)
|
||||
(hide-bottom-sheet))
|
||||
|
||||
(defn view
|
||||
[{:keys [settings?]}]
|
||||
(rn/use-mount #(dismiss-keyboard))
|
||||
[:<>
|
||||
[quo/drawer-top
|
||||
{:title (i18n/label :t/help-us-improve-status)
|
||||
:description (i18n/label :t/collecting-usage-data)}]
|
||||
[rn/view {:style style/points-wrapper}
|
||||
[bullet-points
|
||||
{:title (i18n/label :t/what-we-will-receive)
|
||||
:points will-receive-points}]
|
||||
[bullet-points
|
||||
{:title (i18n/label :t/what-we-wont-receive)
|
||||
:points not-receive-points}]
|
||||
(when-not settings?
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:style style/info-text}
|
||||
(i18n/label :t/sharing-usage-data-can-be-turned-off)])]
|
||||
[quo/bottom-actions
|
||||
{:actions :two-actions
|
||||
:blur? true
|
||||
:button-one-label (i18n/label :t/share-usage-data)
|
||||
:button-one-props {:on-press on-share-usage}
|
||||
:button-two-label (i18n/label (if settings? :t/do-not-share :t/not-now))
|
||||
:button-two-props {:type :grey
|
||||
:on-press on-do-not-share}}]])
|
||||
@@ -72,7 +72,7 @@
|
||||
|
||||
;; CONFIG VALUES
|
||||
(def log-level (string/upper-case (get-config :LOG_LEVEL "")))
|
||||
(def fleet (get-config :FLEET "waku.sandbox"))
|
||||
(def fleet (get-config :FLEET ""))
|
||||
(def apn-topic (get-config :APN_TOPIC "im.status.ethereum"))
|
||||
(def default-network (get-config :DEFAULT_NETWORK "goerli_rpc"))
|
||||
(def max-installations 2)
|
||||
|
||||
@@ -45,6 +45,11 @@
|
||||
(def ^:const activity-center-membership-status-accepted 2)
|
||||
(def ^:const activity-center-membership-status-declined 3)
|
||||
|
||||
;; Choose the maximum number of notifications that *usually/safely* fit on
|
||||
;; most screens, so that the UI doesn't have to needlessly render
|
||||
;; notifications.
|
||||
(def ^:const notifications-per-page 7)
|
||||
|
||||
(def ^:const mute-for-15-mins-type 1)
|
||||
(def ^:const mute-for-1-hour-type 2)
|
||||
(def ^:const mute-for-8-hours-type 3)
|
||||
@@ -276,12 +281,14 @@
|
||||
#{wallet-connect-personal-sign-method
|
||||
wallet-connect-eth-sign-method
|
||||
wallet-connect-eth-send-transaction-method
|
||||
wallet-connect-eth-sign-transaction-method
|
||||
;; NOTE: disabled, as we have no clear use cases for it and other wallets don't support it
|
||||
;; 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"})
|
||||
(def ^:const wallet-connect-session-proposal-event "session_proposal")
|
||||
(def ^:const wallet-connect-session-request-event "session_request")
|
||||
(def ^:const wallet-connect-session-delete-event "session_delete")
|
||||
(def ^:const wallet-connect-user-rejected-error-key "USER_REJECTED")
|
||||
|
||||
(def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer")
|
||||
@@ -506,6 +513,9 @@
|
||||
(def ^:const optimism-full-name "Optimism")
|
||||
(def ^:const arbitrum-full-name "Arbitrum")
|
||||
|
||||
(def ^:const sepolia-full-name "Sepolia")
|
||||
(def ^:const goerli-full-name "Goerli")
|
||||
|
||||
(def ^:const mainnet-network-name :mainnet)
|
||||
(def ^:const ethereum-network-name :ethereum)
|
||||
(def ^:const optimism-network-name :optimism)
|
||||
|
||||
@@ -7,10 +7,17 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def ^:const user-confirmed-key :centralized-metrics/user-confirmed?)
|
||||
(def ^:const enabled-key :centralized-metrics/enabled?)
|
||||
|
||||
(defn show-confirmation-modal?
|
||||
[db]
|
||||
(not (user-confirmed-key db)))
|
||||
|
||||
(defn push-event?
|
||||
[db]
|
||||
(or (not (:centralized-metrics/user-confirmed? db))
|
||||
(:centralized-metrics/enabled? db)))
|
||||
(or (not (user-confirmed-key db))
|
||||
(enabled-key db)))
|
||||
|
||||
(defn centralized-metrics-interceptor
|
||||
[context]
|
||||
@@ -29,5 +36,16 @@
|
||||
(fn [{:keys [db]} [enabled?]]
|
||||
{:fx [[:effects.centralized-metrics/toggle-metrics enabled?]]
|
||||
:db (assoc db
|
||||
:centralized-metrics/user-confirmed? true
|
||||
:centralized-metrics/enabled? enabled?)}))
|
||||
user-confirmed-key
|
||||
true
|
||||
enabled-key
|
||||
enabled?)}))
|
||||
|
||||
(rf/reg-event-fx :centralized-metrics/check-modal
|
||||
(fn [{:keys [db]} [modal-view]]
|
||||
(when (show-confirmation-modal? db)
|
||||
{:fx [[:dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [modal-view])
|
||||
:shell? true}]]]})))
|
||||
|
||||
|
||||
@@ -6,6 +6,11 @@
|
||||
[status-im.contexts.centralized-metrics.tracking :as tracking]
|
||||
[test-helpers.unit :as h]))
|
||||
|
||||
(deftest show-confirmation-modal-test
|
||||
(testing "returns true if the user confirmed"
|
||||
(is (false? (events/show-confirmation-modal? {events/user-confirmed-key true})))
|
||||
(is (true? (events/show-confirmation-modal? {})))))
|
||||
|
||||
(deftest push-event-test
|
||||
(testing "returns correct boolean value"
|
||||
(is (true? (events/push-event? {:centralized-metrics/user-confirmed? false})))
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
:on-error #(p-reject (str "failed to sign data\n" %))}))))
|
||||
|
||||
(defn- edit-shared-addresses-for-community
|
||||
[community-id signatures addresses-to-reveal airdrop-address]
|
||||
[community-id signatures addresses-to-reveal airdrop-address _share-future-addresses?]
|
||||
(promesa/create
|
||||
(fn [p-resolve p-reject]
|
||||
(rpc/call
|
||||
@@ -41,15 +41,16 @@
|
||||
:on-error p-reject}))))
|
||||
|
||||
(defn- request-to-join
|
||||
[community-id signatures addresses-to-reveal airdrop-address]
|
||||
[community-id signatures addresses-to-reveal airdrop-address share-future-addresses?]
|
||||
(promesa/create
|
||||
(fn [p-resolve p-reject]
|
||||
(rpc/call
|
||||
{:method :wakuext_requestToJoinCommunity
|
||||
:params [{:communityId community-id
|
||||
:signatures signatures
|
||||
:addressesToReveal addresses-to-reveal
|
||||
:airdropAddress airdrop-address}]
|
||||
:params [{:communityId community-id
|
||||
:signatures signatures
|
||||
:addressesToReveal addresses-to-reveal
|
||||
:airdropAddress airdrop-address
|
||||
:shareFutureAddresses share-future-addresses?}]
|
||||
:js-response true
|
||||
:on-success p-resolve
|
||||
:on-error p-reject}))))
|
||||
@@ -64,15 +65,18 @@
|
||||
|
||||
(defn- sign-and-call-endpoint
|
||||
[{:keys [community-id password pub-key
|
||||
addresses-to-reveal airdrop-address
|
||||
addresses-to-reveal airdrop-address share-future-addresses?
|
||||
on-success on-error
|
||||
callback]}]
|
||||
(-> (promesa/let [sign-params (generate-requests-for-signing pub-key community-id addresses-to-reveal)
|
||||
(-> (promesa/let [sign-params (generate-requests-for-signing pub-key
|
||||
community-id
|
||||
addresses-to-reveal)
|
||||
signatures (sign-data sign-params password)
|
||||
result (callback community-id
|
||||
signatures
|
||||
addresses-to-reveal
|
||||
airdrop-address)]
|
||||
airdrop-address
|
||||
share-future-addresses?)]
|
||||
(run-callback-or-event on-success result))
|
||||
(promesa/catch #(run-callback-or-event on-error %))))
|
||||
|
||||
@@ -87,6 +91,7 @@
|
||||
[:or [:set string?]
|
||||
[:sequential string?]]]
|
||||
[:airdrop-address string?]
|
||||
[:share-future-addresses? boolean?]
|
||||
[:on-success [:or fn? :schema.re-frame/event]]
|
||||
[:on-error [:or fn? :schema.re-frame/event]]
|
||||
[:callback fn?]]]
|
||||
|
||||
@@ -17,13 +17,12 @@
|
||||
(rf/reg-event-fx :communities/initialize-permission-addresses initialize-permission-addresses)
|
||||
|
||||
(defn do-init-permission-addresses
|
||||
[{:keys [db]} [community-id revealed-accounts]]
|
||||
[{:keys [db]} [community-id revealed-accounts share-future-addresses?]]
|
||||
(let [wallet-accounts (utils/sorted-operable-non-watch-only-accounts db)
|
||||
addresses-to-reveal (if (seq revealed-accounts)
|
||||
(set (keys revealed-accounts))
|
||||
;; Reveal all addresses as fallback.
|
||||
(set (map :address wallet-accounts)))
|
||||
|
||||
;; When there are no revealed addresses, such as when joining a
|
||||
;; community, use first address for airdrops.
|
||||
airdrop-address (or (->> revealed-accounts
|
||||
@@ -35,10 +34,7 @@
|
||||
first
|
||||
:address))]
|
||||
{:db (-> db
|
||||
;; Set to false by default while we don't persist the user's choice
|
||||
;; in status-go, otherwise whenever the view is mounted, the choice
|
||||
;; of selected addresses won't be respected.
|
||||
(assoc-in [:communities/selected-share-all-addresses community-id] false)
|
||||
(assoc-in [:communities/selected-share-all-addresses community-id] share-future-addresses?)
|
||||
(assoc-in [:communities/all-addresses-to-reveal community-id] addresses-to-reveal)
|
||||
(assoc-in [:communities/all-airdrop-addresses community-id] airdrop-address))
|
||||
:fx [[:dispatch
|
||||
@@ -60,36 +56,44 @@
|
||||
is selecting an airdrop address, we must submit to status-go the current
|
||||
choice of addresses to share, and vice-versa. If we omit addresses to share,
|
||||
status-go will default to all available."
|
||||
[{:keys [db]} [{:keys [community-id password on-success addresses airdrop-address]}]]
|
||||
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||
wallet-accounts (utils/sorted-operable-non-watch-only-accounts db)
|
||||
addresses-to-reveal (if (seq addresses)
|
||||
(set addresses)
|
||||
(get-in db [:communities/all-addresses-to-reveal community-id]))
|
||||
new-airdrop-address (if (contains? addresses-to-reveal airdrop-address)
|
||||
airdrop-address
|
||||
(->> wallet-accounts
|
||||
(filter #(contains? addresses-to-reveal (:address %)))
|
||||
first
|
||||
:address))]
|
||||
[{:keys [db]}
|
||||
[{:keys [community-id password on-success addresses airdrop-address share-future-addresses?]}]]
|
||||
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||
wallet-accounts (utils/sorted-operable-non-watch-only-accounts db)
|
||||
addresses-to-reveal (if (seq addresses)
|
||||
(set addresses)
|
||||
(get-in db [:communities/all-addresses-to-reveal community-id]))
|
||||
new-airdrop-address (if (contains? addresses-to-reveal airdrop-address)
|
||||
airdrop-address
|
||||
(->> wallet-accounts
|
||||
(filter #(contains? addresses-to-reveal (:address %)))
|
||||
first
|
||||
:address))
|
||||
share-future-addresses? (if (nil? share-future-addresses?)
|
||||
(get-in db [:communities/selected-share-all-addresses community-id])
|
||||
share-future-addresses?)]
|
||||
{:fx [[:effects.community/edit-shared-addresses
|
||||
{:community-id community-id
|
||||
:password password
|
||||
:pub-key pub-key
|
||||
:addresses-to-reveal addresses-to-reveal
|
||||
:airdrop-address new-airdrop-address
|
||||
:on-success (fn []
|
||||
(when (fn? on-success)
|
||||
(on-success addresses-to-reveal new-airdrop-address))
|
||||
(rf/dispatch [:communities/edit-shared-addresses-success
|
||||
community-id addresses-to-reveal airdrop-address]))
|
||||
:on-error [:communities/edit-shared-addresses-failure community-id]}]]}))
|
||||
{:community-id community-id
|
||||
:password password
|
||||
:pub-key pub-key
|
||||
:addresses-to-reveal addresses-to-reveal
|
||||
:share-future-addresses? share-future-addresses?
|
||||
:airdrop-address new-airdrop-address
|
||||
:on-success (fn []
|
||||
(when (fn? on-success)
|
||||
(on-success addresses-to-reveal
|
||||
new-airdrop-address
|
||||
share-future-addresses?))
|
||||
(rf/dispatch [:communities/edit-shared-addresses-success
|
||||
community-id addresses-to-reveal airdrop-address]))
|
||||
:on-error [:communities/edit-shared-addresses-failure community-id]}]]}))
|
||||
|
||||
(rf/reg-event-fx :communities/edit-shared-addresses edit-shared-addresses)
|
||||
|
||||
(rf/reg-event-fx :communities/edit-shared-addresses-success
|
||||
(fn [_ [community-id addresses-to-reveal airdrop-address]]
|
||||
(fn [_ [community-id addresses-to-reveal airdrop-address share-future-addresses?]]
|
||||
{:fx [[:dispatch [:communities/set-airdrop-address community-id airdrop-address]]
|
||||
[:dispatch [:communities/set-share-all-addresses community-id share-future-addresses?]]
|
||||
[:dispatch [:communities/set-addresses-to-reveal community-id addresses-to-reveal]]]}))
|
||||
|
||||
(rf/reg-event-fx :communities/edit-shared-addresses-failure
|
||||
|
||||
@@ -70,7 +70,7 @@
|
||||
(is
|
||||
(match?
|
||||
{:db (-> (:db cofx)
|
||||
(assoc-in [:communities/selected-share-all-addresses community-id] false)
|
||||
(assoc-in [:communities/selected-share-all-addresses community-id] true)
|
||||
(assoc-in [:communities/all-addresses-to-reveal community-id] addresses-to-reveal)
|
||||
(assoc-in [:communities/all-airdrop-addresses community-id] airdrop-address))
|
||||
:fx [[:dispatch
|
||||
@@ -82,7 +82,7 @@
|
||||
[:dispatch
|
||||
[:communities/check-permissions-to-join-during-selection community-id
|
||||
addresses-to-reveal]]]}
|
||||
(sut/do-init-permission-addresses cofx [community-id revealed-accounts])))))
|
||||
(sut/do-init-permission-addresses cofx [community-id revealed-accounts true])))))
|
||||
|
||||
;; Expect to mark all addresses to be revealed and first one to receive
|
||||
;; airdrops when no addresses were previously revealed.
|
||||
@@ -93,7 +93,7 @@
|
||||
(is
|
||||
(match?
|
||||
{:db (-> (:db cofx)
|
||||
(assoc-in [:communities/selected-share-all-addresses community-id] false)
|
||||
(assoc-in [:communities/selected-share-all-addresses community-id] true)
|
||||
(assoc-in [:communities/all-addresses-to-reveal community-id] addresses-to-reveal))
|
||||
:fx [[:dispatch
|
||||
[:communities/check-permissions-to-join-community
|
||||
@@ -101,7 +101,7 @@
|
||||
[:dispatch
|
||||
[:communities/check-permissions-to-join-during-selection community-id
|
||||
addresses-to-reveal]]]}
|
||||
(sut/do-init-permission-addresses cofx [community-id revealed-accounts]))))))
|
||||
(sut/do-init-permission-addresses cofx [community-id revealed-accounts true]))))))
|
||||
|
||||
(deftest edit-shared-addresses-test
|
||||
(testing
|
||||
@@ -109,6 +109,7 @@
|
||||
fallback to all wallet addresses"
|
||||
(let [pub-key "abcdef"
|
||||
revealed-addresses #{"0xB" "0xC"}
|
||||
share-future-addresses? true
|
||||
cofx {:db {:profile/profile {:public-key pub-key}
|
||||
:communities/all-addresses-to-reveal {community-id revealed-addresses}}}
|
||||
airdrop-address "0xB"
|
||||
@@ -116,22 +117,24 @@
|
||||
actual
|
||||
(sut/edit-shared-addresses
|
||||
cofx
|
||||
[{:community-id community-id
|
||||
:password password
|
||||
:airdrop-address airdrop-address
|
||||
:on-success (fn [new-addresses-to-reveal]
|
||||
(is (match? revealed-addresses new-addresses-to-reveal)))}])
|
||||
[{:community-id community-id
|
||||
:password password
|
||||
:airdrop-address airdrop-address
|
||||
:share-future-addresses? share-future-addresses?
|
||||
:on-success (fn [new-addresses-to-reveal]
|
||||
(is (match? revealed-addresses new-addresses-to-reveal)))}])
|
||||
|
||||
on-success-wrapper (-> actual :fx first second :on-success)]
|
||||
(is (match?
|
||||
{:fx [[:effects.community/edit-shared-addresses
|
||||
{:community-id community-id
|
||||
:password password
|
||||
:pub-key pub-key
|
||||
:addresses-to-reveal revealed-addresses
|
||||
:airdrop-address airdrop-address
|
||||
:on-success fn?
|
||||
:on-error [:communities/edit-shared-addresses-failure community-id]}]]}
|
||||
{:community-id community-id
|
||||
:password password
|
||||
:pub-key pub-key
|
||||
:addresses-to-reveal revealed-addresses
|
||||
:share-future-addresses? share-future-addresses?
|
||||
:airdrop-address airdrop-address
|
||||
:on-success fn?
|
||||
:on-error [:communities/edit-shared-addresses-failure community-id]}]]}
|
||||
actual))
|
||||
|
||||
(on-success-wrapper)))
|
||||
|
||||
@@ -203,7 +203,9 @@
|
||||
:addresses-for-permissions])
|
||||
(rf/dispatch [:hide-bottom-sheet]))}]))}])
|
||||
(rf/dispatch [:communities/set-share-all-addresses id flag-share-all-addresses]))
|
||||
(rf/dispatch [:communities/set-addresses-to-reveal id addresses-to-reveal])))
|
||||
(do
|
||||
(rf/dispatch [:communities/set-share-all-addresses id flag-share-all-addresses])
|
||||
(rf/dispatch [:communities/set-addresses-to-reveal id addresses-to-reveal]))))
|
||||
highest-role (rf/sub [:communities/highest-role-for-selection id])
|
||||
[unmodified-role _] (rn/use-state highest-role)]
|
||||
|
||||
@@ -261,6 +263,7 @@
|
||||
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
||||
|
||||
wallet-accounts (rf/sub [:wallet/operable-accounts-without-watched-accounts])
|
||||
joined (rf/sub [:communities/community-joined id])
|
||||
unmodified-addresses-to-reveal (rf/sub [:communities/addresses-to-reveal id])
|
||||
[addresses-to-reveal set-addresses-to-reveal] (rn/use-state unmodified-addresses-to-reveal)
|
||||
|
||||
@@ -285,7 +288,6 @@
|
||||
(set-flag-share-all-addresses new-value)
|
||||
(when new-value
|
||||
(set-addresses-to-reveal (set (map :address wallet-accounts))))))]
|
||||
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(when-not flag-share-all-addresses
|
||||
@@ -310,6 +312,7 @@
|
||||
flag-share-all-addresses]
|
||||
:header [quo/page-setting
|
||||
{:checked? flag-share-all-addresses
|
||||
:disabled? joined
|
||||
:customization-color color
|
||||
:on-change toggle-flag-share-all-addresses
|
||||
:setting-text (i18n/label
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
[status-im.navigation.events :as navigation]
|
||||
[status-im.navigation.transitions :as transitions]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.collection :as collection-utils]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn handle-community
|
||||
@@ -372,15 +373,14 @@
|
||||
(when (and community joined (not fetching-revealed-accounts))
|
||||
{:db (assoc-in db [:communities community-id :fetching-revealed-accounts] true)
|
||||
:json-rpc/call
|
||||
[{:method "wakuext_getRevealedAccounts"
|
||||
:params [community-id (get-in db [:profile/profile :public-key])]
|
||||
:js-response true
|
||||
:on-success [:communities/get-revealed-accounts-success community-id on-success]
|
||||
:on-error (fn [err]
|
||||
(log/error {:message "failed to fetch revealed accounts"
|
||||
:community-id community-id
|
||||
:err err})
|
||||
(rf/dispatch [:communities/get-revealed-accounts-failed community-id]))}]})))
|
||||
[{:method "wakuext_latestRequestToJoinForCommunity"
|
||||
:params [community-id]
|
||||
:on-success [:communities/get-revealed-accounts-success community-id on-success]
|
||||
:on-error (fn [err]
|
||||
(log/error {:message "failed to fetch revealed accounts"
|
||||
:community-id community-id
|
||||
:err err})
|
||||
(rf/dispatch [:communities/get-revealed-accounts-failed community-id]))}]})))
|
||||
|
||||
(rf/reg-event-fx :communities/get-revealed-accounts get-revealed-accounts)
|
||||
|
||||
@@ -399,22 +399,18 @@
|
||||
[:json-rpc/call :schema.common/rpc-call]]]])
|
||||
|
||||
(rf/reg-event-fx :communities/get-revealed-accounts-success
|
||||
(fn [{:keys [db]} [community-id on-success revealed-accounts-js]]
|
||||
(fn [{:keys [db]} [community-id on-success request-to-join]]
|
||||
(when-let [community (get-in db [:communities community-id])]
|
||||
(let [revealed-accounts
|
||||
(reduce
|
||||
(fn [acc {:keys [address] :as revealed-account}]
|
||||
(assoc acc address revealed-account))
|
||||
{}
|
||||
(data-store.communities/<-revealed-accounts-rpc revealed-accounts-js))
|
||||
|
||||
(let [revealed-accounts (collection-utils/index-by :address (:revealedAccounts request-to-join))
|
||||
share-future-addresses? (:shareFutureAddresses request-to-join)
|
||||
community-with-revealed-accounts
|
||||
(-> community
|
||||
(assoc :revealed-accounts revealed-accounts)
|
||||
(assoc :share-future-addresses? share-future-addresses?)
|
||||
(dissoc :fetching-revealed-accounts))]
|
||||
{:db (assoc-in db [:communities community-id] community-with-revealed-accounts)
|
||||
:fx [(when (vector? on-success)
|
||||
[:dispatch (conj on-success revealed-accounts)])]}))))
|
||||
[:dispatch (conj on-success revealed-accounts share-future-addresses?)])]}))))
|
||||
|
||||
(rf/reg-event-fx :communities/get-revealed-accounts-failed
|
||||
(fn [{:keys [db]} [community-id]]
|
||||
|
||||
@@ -146,8 +146,8 @@
|
||||
effects (events/get-revealed-accounts {:db db} [community-id])]
|
||||
(is (match? (assoc-in db [:communities community-id :fetching-revealed-accounts] true)
|
||||
(:db effects)))
|
||||
(is (match? {:method "wakuext_getRevealedAccounts"
|
||||
:params [community-id "profile-public-key"]}
|
||||
(is (match? {:method "wakuext_latestRequestToJoinForCommunity"
|
||||
:params [community-id]}
|
||||
(-> effects :json-rpc/call first (select-keys [:method :params]))))))))
|
||||
|
||||
(deftest handle-community-test
|
||||
|
||||
@@ -117,13 +117,14 @@
|
||||
{:community community-name})}]]]})))
|
||||
|
||||
(defn request-to-join-with-signatures
|
||||
[_ [community-id addresses-to-reveal signatures]]
|
||||
[_ [community-id addresses-to-reveal signatures share-future-addresses?]]
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id
|
||||
:signatures signatures
|
||||
:addressesToReveal addresses-to-reveal
|
||||
:airdropAddress (first addresses-to-reveal)}]
|
||||
:params [{:communityId community-id
|
||||
:signatures signatures
|
||||
:addressesToReveal addresses-to-reveal
|
||||
:shareFutureAddresses share-future-addresses?
|
||||
:airdropAddress (first addresses-to-reveal)}]
|
||||
:js-response true
|
||||
:on-success [:communities/requested-to-join]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]]})
|
||||
@@ -153,16 +154,18 @@
|
||||
(defn request-to-join-with-addresses
|
||||
[{:keys [db]}
|
||||
[{:keys [community-id password]}]]
|
||||
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||
addresses-to-reveal (get-in db [:communities/all-addresses-to-reveal community-id])
|
||||
airdrop-address (get-in db [:communities/all-airdrop-addresses community-id])]
|
||||
(let [pub-key (get-in db [:profile/profile :public-key])
|
||||
addresses-to-reveal (get-in db [:communities/all-addresses-to-reveal community-id])
|
||||
share-future-addresses? (get-in db [:communities/selected-share-all-addresses community-id])
|
||||
airdrop-address (get-in db [:communities/all-airdrop-addresses community-id])]
|
||||
{:fx [[:effects.community/request-to-join
|
||||
{:community-id community-id
|
||||
:password password
|
||||
:pub-key pub-key
|
||||
:addresses-to-reveal addresses-to-reveal
|
||||
:airdrop-address airdrop-address
|
||||
:on-success [:communities/requested-to-join]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]}))
|
||||
{:community-id community-id
|
||||
:password password
|
||||
:pub-key pub-key
|
||||
:addresses-to-reveal addresses-to-reveal
|
||||
:airdrop-address airdrop-address
|
||||
:share-future-addresses? share-future-addresses?
|
||||
:on-success [:communities/requested-to-join]
|
||||
:on-error [:communities/requested-to-join-error community-id]}]]}))
|
||||
|
||||
(rf/reg-event-fx :communities/request-to-join-with-addresses request-to-join-with-addresses)
|
||||
|
||||
@@ -37,19 +37,22 @@
|
||||
(sut/sign-data cofx [community-id password sign-params])))))
|
||||
|
||||
(deftest request-to-join-with-signatures-test
|
||||
(let [cofx {:db {}}
|
||||
addresses-to-reveal [account-pub-key "0x2"]
|
||||
signatures ["11111" "222222"]
|
||||
expected {:fx [[:json-rpc/call
|
||||
[{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id
|
||||
:signatures signatures
|
||||
:addressesToReveal addresses-to-reveal
|
||||
:airdropAddress "0x1"}]
|
||||
:js-response true
|
||||
:on-success [:communities/requested-to-join]
|
||||
:on-error [:communities/requested-to-join-error
|
||||
community-id]}]]]}]
|
||||
(let [cofx {:db {}}
|
||||
addresses-to-reveal [account-pub-key "0x2"]
|
||||
share-future-addresses? true
|
||||
signatures ["11111" "222222"]
|
||||
expected {:fx [[:json-rpc/call
|
||||
[{:method "wakuext_requestToJoinCommunity"
|
||||
:params [{:communityId community-id
|
||||
:signatures signatures
|
||||
:addressesToReveal addresses-to-reveal
|
||||
:shareFutureAddresses share-future-addresses?
|
||||
:airdropAddress "0x1"}]
|
||||
:js-response true
|
||||
:on-success [:communities/requested-to-join]
|
||||
:on-error [:communities/requested-to-join-error
|
||||
community-id]}]]]}]
|
||||
(is (match? expected
|
||||
(sut/request-to-join-with-signatures cofx
|
||||
[community-id addresses-to-reveal signatures])))))
|
||||
[community-id addresses-to-reveal signatures
|
||||
share-future-addresses?])))))
|
||||
|
||||
@@ -5,13 +5,8 @@
|
||||
|
||||
(def background-container
|
||||
{:background-color colors/neutral-100
|
||||
:flex-direction :row
|
||||
:position :absolute
|
||||
:overflow :hidden
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
:flex 1
|
||||
:overflow :hidden})
|
||||
|
||||
(def background-blur-overlay
|
||||
{:position :absolute
|
||||
|
||||
@@ -25,13 +25,12 @@
|
||||
:sub-text (i18n/label :t/explore-the-decentralized-web)}])
|
||||
|
||||
(defn background-image
|
||||
[content-width]
|
||||
[image-view-width]
|
||||
[rn/image
|
||||
{:resize-mode :stretch
|
||||
:resize-method :scale
|
||||
:style {:top 138
|
||||
:width content-width}
|
||||
:source (resources/get-image :onboarding-illustration)}])
|
||||
{:resize-mode :stretch
|
||||
:style {:flex 1
|
||||
:width image-view-width}
|
||||
:source (resources/get-image :onboarding-illustration)}])
|
||||
|
||||
(defonce progress (atom nil))
|
||||
(defonce paused? (atom nil))
|
||||
|
||||
@@ -5,12 +5,9 @@
|
||||
|
||||
(defn header-container
|
||||
[status-bar-height content-width index header-background]
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:left (* content-width index)
|
||||
{:margin-left (* content-width index)
|
||||
:padding-top (+ 30 status-bar-height)
|
||||
:width content-width
|
||||
:height (+ 96 status-bar-height)
|
||||
:flex-direction :row
|
||||
:background-color (when header-background colors/onboarding-header-black)})
|
||||
|
||||
@@ -62,9 +59,9 @@
|
||||
:top (+ 12 status-bar-height)})
|
||||
|
||||
(defn carousel-container
|
||||
[left animate?]
|
||||
(cond->> {:position :absolute
|
||||
:top 0
|
||||
:flex-direction :row
|
||||
:left left}
|
||||
animate? (reanimated/apply-animations-to-style {:left left})))
|
||||
[left animate? width]
|
||||
(cond->> {:flex-direction :row
|
||||
:flex 1
|
||||
:width width
|
||||
:margin-left left}
|
||||
animate? (reanimated/apply-animations-to-style {:margin-left left})))
|
||||
|
||||
@@ -18,19 +18,18 @@
|
||||
:size :heading-2}
|
||||
(get-in header-text [index :text])]
|
||||
[quo/text
|
||||
{:style style/carousel-sub-text
|
||||
:size :paragraph-1}
|
||||
{:style style/carousel-sub-text}
|
||||
(get-in header-text [index :sub-text])]])
|
||||
|
||||
(defn content-view
|
||||
[{:keys [window-width status-bar-height index header-text header-background]} content]
|
||||
(let [content-width (* 4 window-width)]
|
||||
[:<>
|
||||
(when content content)
|
||||
[rn/view {:style {:flex 1}}
|
||||
[rn/view {:style (style/header-container status-bar-height content-width index header-background)}
|
||||
(for [index (range 4)]
|
||||
^{:key index}
|
||||
[header-text-view index window-width header-text])]]))
|
||||
[header-text-view index window-width header-text])]
|
||||
(when content content)]))
|
||||
|
||||
(defn progress-bar
|
||||
[{:keys [static? progress-bar-width]}]
|
||||
@@ -64,10 +63,10 @@
|
||||
:swipeable (animation/composed-gestures progress paused? is-dragging? drag-amount)
|
||||
:tappable (animation/tap-gesture progress paused?)
|
||||
nil)]
|
||||
[:<>
|
||||
[rn/view {:style {:flex 1}}
|
||||
[gesture/gesture-detector {:gesture identified-gesture}
|
||||
[container-view {:style (style/carousel-container carousel-left animate?)}
|
||||
(for [index (range 2)]
|
||||
[container-view {:style (style/carousel-container carousel-left animate? (* 4 window-width))}
|
||||
(for [index (range 1)]
|
||||
^{:key index}
|
||||
[content-view
|
||||
{:window-width window-width
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.check-before-syncing.view :as check-before-syncing]
|
||||
[status-im.common.metrics-confirmation-modal.view :as metrics-modal]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.config :as config]
|
||||
@@ -126,6 +127,7 @@
|
||||
|
||||
(defn- internal-view
|
||||
[sign-in-type]
|
||||
(rn/use-mount #(rf/dispatch [:centralized-metrics/check-modal metrics-modal/view]))
|
||||
(let [{:keys [top]} (safe-area/get-insets)]
|
||||
[rn/view {:style style/content-container}
|
||||
[quo/page-nav
|
||||
|
||||
@@ -4,20 +4,20 @@
|
||||
|
||||
(def title-container
|
||||
{:margin-horizontal 20
|
||||
:padding-vertical 12})
|
||||
:padding-bottom 20
|
||||
:padding-top 12})
|
||||
|
||||
(defn page-container
|
||||
[insets]
|
||||
{:flex 1
|
||||
:justify-content :space-between
|
||||
:padding-top (+ (:top insets) 56)})
|
||||
{:flex 1
|
||||
:padding-top (+ (:top insets) 56)})
|
||||
|
||||
(defn page-illustration
|
||||
[width]
|
||||
{:flex 1
|
||||
:padding-top 12
|
||||
:padding-bottom 10
|
||||
:width width})
|
||||
{:flex 1
|
||||
:margin-top 12
|
||||
:margin-bottom 10
|
||||
:width width})
|
||||
|
||||
(defn buttons
|
||||
[insets]
|
||||
|
||||
@@ -2,11 +2,16 @@
|
||||
|
||||
(defn page-container
|
||||
[insets]
|
||||
{:flex 1
|
||||
:justify-content :space-between
|
||||
:padding-top (:top insets)})
|
||||
{:flex 1
|
||||
:padding-top (:top insets)})
|
||||
|
||||
(defn page-illustration
|
||||
[width]
|
||||
{:flex 1
|
||||
:width width})
|
||||
|
||||
(def title-style
|
||||
{:position :absolute
|
||||
:left 0
|
||||
:right 0
|
||||
:top 0})
|
||||
|
||||
@@ -17,19 +17,22 @@
|
||||
(defn generate-keys-title
|
||||
[]
|
||||
[quo/text-combinations
|
||||
{:container-style {:margin-horizontal 20}
|
||||
{:container-style {:margin-horizontal 20
|
||||
:margin-vertical 12}
|
||||
:title (i18n/label :t/generating-keys)}])
|
||||
|
||||
(defn saving-keys-title
|
||||
[]
|
||||
[quo/text-combinations
|
||||
{:container-style {:margin-horizontal 20}
|
||||
{:container-style {:margin-horizontal 20
|
||||
:margin-vertical 12}
|
||||
:title (i18n/label :t/saving-keys-to-device)}])
|
||||
|
||||
(defn keys-saved-title
|
||||
[]
|
||||
[quo/text-combinations
|
||||
{:container-style {:margin-horizontal 20}
|
||||
{:container-style {:margin-horizontal 20
|
||||
:margin-vertical 12}
|
||||
:title (i18n/label :t/keys-saved)}])
|
||||
|
||||
(defn sequence-animation
|
||||
@@ -61,46 +64,42 @@
|
||||
reanimated/easings))))))
|
||||
|
||||
(defn title
|
||||
[insets]
|
||||
(let [top-insets (+ (if rn/small-screen? 62 112) (:insets insets))
|
||||
generate-keys-opacity (reanimated/use-shared-value 1)
|
||||
[]
|
||||
(let [generate-keys-opacity (reanimated/use-shared-value 1)
|
||||
saving-keys-opacity (reanimated/use-shared-value 0)
|
||||
keys-saved-opacity (reanimated/use-shared-value 0)]
|
||||
(sequence-animation generate-keys-opacity saving-keys-opacity keys-saved-opacity)
|
||||
[rn/view
|
||||
{:position :absolute
|
||||
:top top-insets}
|
||||
{:style {:margin-top 56
|
||||
:height 56}}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity generate-keys-opacity}
|
||||
{:position :absolute})}
|
||||
style/title-style)}
|
||||
[generate-keys-title]]
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity saving-keys-opacity}
|
||||
{:position :absolute})}
|
||||
style/title-style)}
|
||||
[saving-keys-title]]
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity keys-saved-opacity}
|
||||
{:position :absolute})}
|
||||
style/title-style)}
|
||||
[keys-saved-title]]]))
|
||||
|
||||
(defn content
|
||||
[]
|
||||
(let [width (:width (rn/get-window))]
|
||||
[rn/view
|
||||
{:top 156
|
||||
:position :absolute}
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:style (style/page-illustration width)
|
||||
:source (resources/get-image :generate-keys1)}]]))
|
||||
[rn/image
|
||||
{:resize-mode :contain
|
||||
:style (style/page-illustration width)
|
||||
:source (resources/get-image :generate-keys1)}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [insets (safe-area/get-insets)]
|
||||
[rn/view {:style (style/page-container insets)}
|
||||
[:<>
|
||||
[title insets]
|
||||
[title]
|
||||
[content]]]))
|
||||
|
||||
@@ -7,9 +7,8 @@
|
||||
:justify-content :flex-end})
|
||||
|
||||
(def text-container
|
||||
{:flex 1
|
||||
:text-align :center
|
||||
:margin-top 16
|
||||
{:text-align :center
|
||||
:margin-top 4
|
||||
:flex-wrap :wrap})
|
||||
|
||||
(def plain-text
|
||||
@@ -19,9 +18,8 @@
|
||||
{:flex 1
|
||||
:color colors/white})
|
||||
|
||||
(def bottom-actions-container
|
||||
{:position :absolute
|
||||
:background-color colors/onboarding-header-black
|
||||
:left 0
|
||||
:right 0
|
||||
:padding-bottom 40})
|
||||
(defn bottom-actions-container
|
||||
[bottom-insets]
|
||||
{:background-color colors/onboarding-header-black
|
||||
:flex-shrink 1
|
||||
:padding-bottom (+ 20 bottom-insets)})
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[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]
|
||||
@@ -14,7 +15,7 @@
|
||||
[rn/view {:style style/page-container}
|
||||
[background/view false]
|
||||
[quo/bottom-actions
|
||||
{:container-style style/bottom-actions-container
|
||||
{:container-style (style/bottom-actions-container (safe-area/get-bottom))
|
||||
:actions :two-vertical-actions
|
||||
:description :bottom
|
||||
:description-text [quo/text
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
[status-im.contexts.preview.quo.settings.settings-item :as settings-item]
|
||||
[status-im.contexts.preview.quo.share.qr-code :as qr-code]
|
||||
[status-im.contexts.preview.quo.share.share-qr-code :as share-qr-code]
|
||||
[status-im.contexts.preview.quo.slideshow.slider-bar :as slider-bar]
|
||||
[status-im.contexts.preview.quo.style :as style]
|
||||
[status-im.contexts.preview.quo.switcher.group-messaging-card :as
|
||||
group-messaging-card]
|
||||
@@ -211,6 +212,7 @@
|
||||
[status-im.contexts.preview.quo.wallet.progress-bar :as progress-bar]
|
||||
[status-im.contexts.preview.quo.wallet.required-tokens :as required-tokens]
|
||||
[status-im.contexts.preview.quo.wallet.summary-info :as summary-info]
|
||||
[status-im.contexts.preview.quo.wallet.swap-input :as swap-input]
|
||||
[status-im.contexts.preview.quo.wallet.token-input :as token-input]
|
||||
[status-im.contexts.preview.quo.wallet.transaction-progress :as transaction-progress]
|
||||
[status-im.contexts.preview.quo.wallet.transaction-summary :as
|
||||
@@ -502,6 +504,8 @@
|
||||
:component qr-code/view}
|
||||
{:name :share-qr-code
|
||||
:component share-qr-code/view}]
|
||||
:slideshow [{:name :slider-bar
|
||||
:component slider-bar/view}]
|
||||
:switchers [{:name :group-messaging-card
|
||||
:component group-messaging-card/view}
|
||||
{:name :switcher-cards
|
||||
@@ -567,6 +571,7 @@
|
||||
{:name :required-tokens
|
||||
:component required-tokens/view}
|
||||
{:name :summary-info :component summary-info/view}
|
||||
{:name :swap-input :component swap-input/view}
|
||||
{:name :token-input :component token-input/view}
|
||||
{:name :wallet-activity :component wallet-activity/view}
|
||||
{:name :transaction-progress :component transaction-progress/view}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
(ns status-im.contexts.preview.quo.slideshow.slider-bar
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:key :total-amount
|
||||
:type :number}
|
||||
{:label "Blur (dark only)?"
|
||||
:key :blur?
|
||||
:type :boolean}
|
||||
(preview/customization-color-option)])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [[state set-state] (rn/use-state {:total-amount 10
|
||||
:active-index 0
|
||||
:blur? false
|
||||
:customization-color :blue})]
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:set-state set-state
|
||||
:descriptor descriptor
|
||||
:blur? (:blur? state)
|
||||
:show-blur-background? true
|
||||
:blur-dark-only? true}
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:justify-content :center
|
||||
:gap 10
|
||||
:padding 10}}
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:style {:disabled true}
|
||||
:disabled? (zero? (:active-index state))
|
||||
:icon-only? true
|
||||
:on-press (fn []
|
||||
(set-state (update state :active-index dec)))}
|
||||
:i/chevron-left]
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:disabled? (= (:active-index state)
|
||||
(dec (:total-amount state)))
|
||||
:icon-only? true
|
||||
:on-press (fn []
|
||||
(set-state (update state :active-index inc)))}
|
||||
:i/chevron-right]]
|
||||
[quo/slider-bar state]]))
|
||||
@@ -0,0 +1,68 @@
|
||||
(ns status-im.contexts.preview.quo.wallet.swap-input
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.resources :as resources]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:type :select
|
||||
:key :type
|
||||
:options [{:key :pay}
|
||||
{:key :receive}]}
|
||||
{:type :select
|
||||
:key :status
|
||||
:options [{:key :default}
|
||||
{:key :disabled}
|
||||
{:key :loading}]}
|
||||
{:type :select
|
||||
:key :value
|
||||
:options [{:key :token}
|
||||
{:key :fiat}]}
|
||||
{:type :boolean
|
||||
:key :error?}
|
||||
{:type :boolean
|
||||
:key :enable-swap?}
|
||||
{:type :boolean
|
||||
:key :show-approval-label?}
|
||||
(preview/customization-color-option)])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [[state set-state] (rn/use-state {:type :pay
|
||||
:error? false
|
||||
:token "SNT"
|
||||
:customization-color :blue
|
||||
:show-approval-label? false
|
||||
:enable-swap? true
|
||||
:status :default
|
||||
:currency-symbol "€"})
|
||||
[value set-value] (rn/use-state "")
|
||||
on-press (fn [v] (set-value (str value v)))
|
||||
delete (fn [] (set-value #(subs % 0 (dec (count %)))))]
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:set-state set-state
|
||||
:descriptor descriptor}
|
||||
[quo/swap-input
|
||||
(assoc state
|
||||
:on-swap-press #(js/alert "Swap Pressed")
|
||||
:on-token-press #(js/alert "Token Pressed")
|
||||
:on-max-press #(js/alert "Max Pressed")
|
||||
:value value
|
||||
:fiat-value (str (.toFixed (* value 0.3) 2))
|
||||
:container-style {:margin-bottom 20}
|
||||
:network-tag-props {:title "Max: 200 SNT"
|
||||
:networks [{:source (resources/get-network :ethereum)}]}
|
||||
:approval-label-props
|
||||
{:status :approve
|
||||
:token-value "10"
|
||||
:button-props {:on-press
|
||||
#(js/alert "Approve Pressed")}
|
||||
:customization-color (:customization-color state)
|
||||
:token-symbol "SNT"})]
|
||||
[quo/numbered-keyboard
|
||||
{:left-action :dot
|
||||
:delete-key? true
|
||||
:on-press on-press
|
||||
:on-delete delete}]]))
|
||||
@@ -29,19 +29,21 @@
|
||||
[]
|
||||
(let [log-enabled? (boolean (not-empty config/log-level))]
|
||||
(assoc (login)
|
||||
:deviceName (native-module/get-installation-name)
|
||||
:rootDataDir (native-module/backup-disabled-data-dir)
|
||||
:rootKeystoreDir (native-module/keystore-dir)
|
||||
:logLevel (when log-enabled? config/log-level)
|
||||
:logEnabled log-enabled?
|
||||
:logFilePath (native-module/log-file-directory)
|
||||
:verifyTransactionURL config/verify-transaction-url
|
||||
:verifyENSURL config/verify-ens-url
|
||||
:verifyENSContractAddress config/verify-ens-contract-address
|
||||
:verifyTransactionChainID config/verify-transaction-chain-id
|
||||
:wakuV2LightClient true
|
||||
:previewPrivacy config/blank-preview?
|
||||
:testNetworksEnabled config/test-networks-enabled?)))
|
||||
:deviceName (native-module/get-installation-name)
|
||||
:rootDataDir (native-module/backup-disabled-data-dir)
|
||||
:rootKeystoreDir (native-module/keystore-dir)
|
||||
:logLevel (when log-enabled? config/log-level)
|
||||
:logEnabled log-enabled?
|
||||
:logFilePath (native-module/log-file-directory)
|
||||
:verifyTransactionURL config/verify-transaction-url
|
||||
:verifyENSURL config/verify-ens-url
|
||||
:verifyENSContractAddress config/verify-ens-contract-address
|
||||
:verifyTransactionChainID config/verify-transaction-chain-id
|
||||
:wakuV2LightClient true
|
||||
:wakuV2Fleet config/fleet
|
||||
:wakuV2EnableStoreConfirmationForMessagesSent false
|
||||
:previewPrivacy config/blank-preview?
|
||||
:testNetworksEnabled config/test-networks-enabled?)))
|
||||
|
||||
(defn strip-file-prefix
|
||||
[path]
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.check-before-syncing.view :as check-before-syncing]
|
||||
[status-im.common.confirmation-drawer.view :as confirmation-drawer]
|
||||
[status-im.common.metrics-confirmation-modal.view :as metrics-modal]
|
||||
[status-im.common.standard-authentication.core :as standard-authentication]
|
||||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
@@ -254,6 +255,7 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(rn/use-mount #(rf/dispatch [:centralized-metrics/check-modal metrics-modal/view]))
|
||||
(let [[show-profiles? set-show-profiles] (rn/use-state false)
|
||||
show-profiles (rn/use-callback #(set-show-profiles true))
|
||||
hide-profiles (rn/use-callback #(set-show-profiles false))]
|
||||
|
||||
+8
-6
@@ -113,7 +113,8 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [profile-color (rf/sub [:profile/customization-color])
|
||||
(let [view-id (rf/sub [:view-id])
|
||||
profile-color (rf/sub [:profile/customization-color])
|
||||
accounts-addresses (rf/sub [:wallet/addresses])
|
||||
saved-addresses-addresses (rf/sub [:wallet/saved-addresses-addresses])
|
||||
[address-or-ens set-address-or-ens] (rn/use-state "")
|
||||
@@ -175,11 +176,12 @@
|
||||
:on-press navigate-back
|
||||
:margin-top (safe-area/get-top)
|
||||
:accessibility-label :add-address-to-save-page-nav}]
|
||||
:footer [quo/button
|
||||
{:customization-color profile-color
|
||||
:disabled? button-disabled?
|
||||
:on-press on-press-continue}
|
||||
(i18n/label :t/continue)]}
|
||||
:footer (when (= view-id :screen/settings.add-address-to-save)
|
||||
[quo/button
|
||||
{:customization-color profile-color
|
||||
:disabled? button-disabled?
|
||||
:on-press on-press-continue}
|
||||
(i18n/label :t/continue)])}
|
||||
[quo/page-top
|
||||
{:container-style style/header-container
|
||||
:blur? true
|
||||
|
||||
@@ -121,7 +121,8 @@
|
||||
:on-press on-press-save}
|
||||
(i18n/label :t/save-address)]
|
||||
:customization-color address-color
|
||||
:gradient-cover? true}
|
||||
:gradient-cover? true
|
||||
:shell-overlay? true}
|
||||
[quo/wallet-user-avatar
|
||||
{:full-name (if (string/blank? address-label)
|
||||
placeholder
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
(ns status-im.contexts.shell.activity-center.context
|
||||
(:require
|
||||
["react" :as react]
|
||||
[oops.core :as oops]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defonce ^:private context
|
||||
(react/createContext {}))
|
||||
|
||||
(defn provider
|
||||
[state & children]
|
||||
(into [:> (oops/oget context :Provider) {:value state}]
|
||||
children))
|
||||
|
||||
(defn use-context
|
||||
[]
|
||||
(let [ctx (rn/use-context context)]
|
||||
{:active-swipeable (oops/oget ctx :activeSwipeable)}))
|
||||
@@ -15,10 +15,7 @@
|
||||
(def defaults
|
||||
{:filter-status :unread
|
||||
:filter-type types/no-type
|
||||
;; Choose the maximum number of notifications that *usually/safely* fit on
|
||||
;; most screens, so that the UI doesn't have to needlessly render
|
||||
;; notifications.
|
||||
:notifications-per-page 8})
|
||||
:notifications-per-page constants/notifications-per-page})
|
||||
|
||||
;;;; Navigation
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im.contexts.shell.activity-center.notification.admin.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.shell.activity-center.notification.common.style :as common-style]
|
||||
[status-im.contexts.shell.activity-center.notification.common.view :as common]
|
||||
@@ -23,42 +24,50 @@
|
||||
:text (i18n/label :t/decline)}])
|
||||
|
||||
(defn- swipeable
|
||||
[{:keys [active-swipeable notification extra-fn]} child]
|
||||
(let [{:keys [community-id id membership-status]} notification]
|
||||
[{:keys [notification extra-fn]} child]
|
||||
(let [{:keys [community-id id
|
||||
membership-status]} notification
|
||||
accept (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:communities/accept-request-to-join-pressed
|
||||
community-id id]))
|
||||
[community-id id])
|
||||
decline (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:communities/decline-request-to-join-pressed
|
||||
community-id id]))
|
||||
[community-id id])]
|
||||
(cond
|
||||
(#{constants/activity-center-membership-status-accepted
|
||||
constants/activity-center-membership-status-declined}
|
||||
membership-status)
|
||||
[common/swipeable
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:extra-fn extra-fn}
|
||||
child]
|
||||
|
||||
(= membership-status constants/activity-center-membership-status-pending)
|
||||
[common/swipeable
|
||||
{:left-button swipe-button-accept
|
||||
:left-on-press #(rf/dispatch [:communities/accept-request-to-join-pressed community-id id])
|
||||
:right-button swipe-button-decline
|
||||
:right-on-press #(rf/dispatch [:communities/decline-request-to-join-pressed community-id
|
||||
id])
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button swipe-button-accept
|
||||
:left-on-press accept
|
||||
:right-button swipe-button-decline
|
||||
:right-on-press decline
|
||||
:extra-fn extra-fn}
|
||||
child]
|
||||
|
||||
:else
|
||||
child)))
|
||||
|
||||
(defn view
|
||||
[{:keys [notification set-swipeable-height customization-color] :as props}]
|
||||
[{:keys [notification] :as props}]
|
||||
(let [{:keys [author community-id id membership-status
|
||||
read timestamp]} notification
|
||||
community (rf/sub [:communities/community community-id])
|
||||
community-name (:name community)
|
||||
community-image (get-in community [:images :thumbnail :uri])]
|
||||
community-name (rf/sub [:communities/name community-id])
|
||||
community-logo (rf/sub [:communities/logo community-id])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[swipeable props
|
||||
[quo/activity-log
|
||||
{:title (i18n/label :t/join-request)
|
||||
@@ -66,14 +75,13 @@
|
||||
:icon :i/add-user
|
||||
:timestamp (datetime/timestamp->relative timestamp)
|
||||
:unread? (not read)
|
||||
:on-layout set-swipeable-height
|
||||
:context [[common/user-avatar-tag author]
|
||||
(i18n/label :t/wants-to-join)
|
||||
[quo/context-tag
|
||||
{:type :community
|
||||
:size 24
|
||||
:blur? true
|
||||
:community-logo community-image
|
||||
:community-logo community-logo
|
||||
:community-name community-name}]]
|
||||
:items (condp = membership-status
|
||||
constants/activity-center-membership-status-accepted
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
(def swipe-action-width 80)
|
||||
(def swipe-button-border-radius 16)
|
||||
(def swipe-button-margin 8)
|
||||
|
||||
(def user-avatar-tag
|
||||
{:background-color colors/white-opa-10})
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
(ns status-im.contexts.shell.activity-center.notification.common.view
|
||||
(:require
|
||||
[oops.core :as oops]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[status-im.contexts.shell.activity-center.context :as ac.context]
|
||||
[status-im.contexts.shell.activity-center.notification.common.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -14,7 +16,7 @@
|
||||
(let [profile (rf/sub [:contacts/contact-by-identity user-id])]
|
||||
[rn/view
|
||||
{:on-start-should-set-responder
|
||||
(fn [_event]
|
||||
(fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:chat.ui/show-profile user-id])
|
||||
true)}
|
||||
@@ -33,35 +35,27 @@
|
||||
swipe-button
|
||||
swipeable-ref
|
||||
style]}]
|
||||
(fn [_ ^js drag-x]
|
||||
(let [{:keys [height] :as extra} (extra-fn)
|
||||
opacity (.interpolate drag-x interpolation-opacity)
|
||||
translate-x (.interpolate drag-x interpolation-translate-x)]
|
||||
(fn [_ drag-x]
|
||||
(let [extra (extra-fn)
|
||||
opacity (oops/ocall drag-x :interpolate interpolation-opacity)
|
||||
translate-x (oops/ocall drag-x :interpolate interpolation-translate-x)]
|
||||
[gesture/rect-button
|
||||
{:style (merge {:border-radius style/swipe-button-border-radius} style)
|
||||
:accessibility-label :notification-swipe-action-button
|
||||
:on-press (fn []
|
||||
(when @swipeable-ref
|
||||
(.close ^js @swipeable-ref)
|
||||
(oops/ocall @swipeable-ref :close)
|
||||
(reset! active-swipeable nil))
|
||||
(on-press extra))}
|
||||
[swipe-button
|
||||
{:style {:opacity opacity
|
||||
:transform [{:translateX translate-x}]
|
||||
:height height
|
||||
:flex 1
|
||||
:width style/swipe-action-width}}
|
||||
extra]])))
|
||||
|
||||
(defn- close-active-swipeable
|
||||
[active-swipeable swipeable]
|
||||
(fn [_]
|
||||
(when (and @active-swipeable
|
||||
(not= @active-swipeable @swipeable))
|
||||
(.close ^js @active-swipeable))
|
||||
(reset! active-swipeable @swipeable)))
|
||||
|
||||
(defn swipe-button-container
|
||||
[{:keys [style icon text]} _]
|
||||
[{:keys [style icon text]}]
|
||||
[rn/animated-view
|
||||
{:accessibility-label :notification-swipe
|
||||
:style style}
|
||||
@@ -103,47 +97,54 @@
|
||||
(rf/dispatch [:activity-center.notifications/delete (:id notification)]))
|
||||
|
||||
(defn swipeable
|
||||
[_]
|
||||
(let [swipeable-ref (atom nil)]
|
||||
(fn [{:keys [active-swipeable
|
||||
extra-fn
|
||||
left-button
|
||||
left-on-press
|
||||
right-button
|
||||
right-on-press]}
|
||||
& children]
|
||||
(into
|
||||
[gesture/swipeable
|
||||
(merge
|
||||
{:ref #(reset! swipeable-ref %)
|
||||
:accessibility-label :notification-swipeable
|
||||
:friction 2
|
||||
:on-swipeable-will-open (close-active-swipeable active-swipeable swipeable-ref)
|
||||
:children-container-style {:padding-horizontal 20}}
|
||||
(when left-button
|
||||
{:overshoot-left false
|
||||
:left-threshold style/swipe-action-width
|
||||
:render-left-actions (render-swipe-action
|
||||
{:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn
|
||||
:interpolation-opacity style/left-swipe-opacity-interpolation-js
|
||||
:interpolation-translate-x
|
||||
style/left-swipe-translate-x-interpolation-js
|
||||
:on-press left-on-press
|
||||
:swipe-button left-button
|
||||
:swipeable-ref swipeable-ref
|
||||
:style {:left 8}})})
|
||||
(when right-button
|
||||
{:overshoot-right false
|
||||
:right-threshold style/swipe-action-width
|
||||
:render-right-actions (render-swipe-action
|
||||
{:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn
|
||||
:interpolation-opacity style/right-swipe-opacity-interpolation-js
|
||||
:interpolation-translate-x
|
||||
style/right-swipe-translate-x-interpolation-js
|
||||
:on-press right-on-press
|
||||
:swipe-button right-button
|
||||
:swipeable-ref swipeable-ref
|
||||
:style {:right -8}})}))]
|
||||
children))))
|
||||
[{:keys [extra-fn
|
||||
left-button
|
||||
left-on-press
|
||||
right-button
|
||||
right-on-press]}
|
||||
child]
|
||||
(let [{:keys [active-swipeable]} (ac.context/use-context)
|
||||
this-swipeable (rn/use-ref-atom nil)
|
||||
set-this-swipeable (rn/use-callback #(reset! this-swipeable %)
|
||||
[this-swipeable])
|
||||
on-swipeable-will-open (rn/use-callback
|
||||
(fn []
|
||||
(when (and @active-swipeable
|
||||
(not= @active-swipeable @this-swipeable))
|
||||
(oops/ocall @active-swipeable :close))
|
||||
(reset! active-swipeable @this-swipeable))
|
||||
[@active-swipeable @this-swipeable])]
|
||||
[gesture/swipeable
|
||||
(cond-> {:ref set-this-swipeable
|
||||
:accessibility-label :notification-swipeable
|
||||
:friction 2
|
||||
:on-swipeable-will-open on-swipeable-will-open
|
||||
:children-container-style {:padding-horizontal 20}}
|
||||
left-button
|
||||
(assoc :overshoot-left false
|
||||
:left-threshold style/swipe-action-width
|
||||
:render-left-actions (render-swipe-action
|
||||
{:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn
|
||||
:interpolation-opacity style/left-swipe-opacity-interpolation-js
|
||||
:interpolation-translate-x
|
||||
style/left-swipe-translate-x-interpolation-js
|
||||
:on-press left-on-press
|
||||
:swipe-button left-button
|
||||
:swipeable-ref this-swipeable
|
||||
:style {:left style/swipe-button-margin}}))
|
||||
|
||||
right-button
|
||||
(assoc :overshoot-right false
|
||||
:right-threshold style/swipe-action-width
|
||||
:render-right-actions (render-swipe-action
|
||||
{:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn
|
||||
:interpolation-opacity style/right-swipe-opacity-interpolation-js
|
||||
:interpolation-translate-x
|
||||
style/right-swipe-translate-x-interpolation-js
|
||||
:on-press right-on-press
|
||||
:swipe-button right-button
|
||||
:swipeable-ref this-swipeable
|
||||
:style {:right (- style/swipe-button-margin)}})))
|
||||
child]))
|
||||
|
||||
+18
-16
@@ -1,6 +1,7 @@
|
||||
(ns status-im.contexts.shell.activity-center.notification.community-kicked.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.contexts.shell.activity-center.notification.common.style :as common-style]
|
||||
[status-im.contexts.shell.activity-center.notification.common.view :as common]
|
||||
@@ -9,33 +10,34 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- swipeable
|
||||
[{:keys [active-swipeable extra-fn]} child]
|
||||
[{:keys [extra-fn]} child]
|
||||
[common/swipeable
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:extra-fn extra-fn}
|
||||
child])
|
||||
|
||||
(defn view
|
||||
[{:keys [notification set-swipeable-height customization-color] :as props}]
|
||||
(let [{:keys [community-id read
|
||||
[{:keys [notification extra-fn]}]
|
||||
(let [{:keys [id community-id read
|
||||
timestamp]} notification
|
||||
community (rf/sub [:communities/community community-id])
|
||||
community-name (:name community)
|
||||
community-image (get-in community [:images :thumbnail :uri])]
|
||||
[swipeable props
|
||||
[gesture/touchable-without-feedback
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read (:id notification)]))}
|
||||
community-image (get-in community [:images :thumbnail :uri])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
on-press (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read id]))
|
||||
[id])]
|
||||
[swipeable {:extra-fn extra-fn}
|
||||
[gesture/touchable-without-feedback {:on-press on-press}
|
||||
[quo/activity-log
|
||||
{:title (i18n/label :t/community-kicked-heading)
|
||||
:customization-color customization-color
|
||||
:icon :i/placeholder
|
||||
:on-layout set-swipeable-height
|
||||
:timestamp (datetime/timestamp->relative timestamp)
|
||||
:unread? (not read)
|
||||
:context [[quo/text {:style common-style/user-avatar-tag-text}
|
||||
|
||||
+30
-27
@@ -1,6 +1,7 @@
|
||||
(ns status-im.contexts.shell.activity-center.notification.community-request.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.shell.activity-center.notification.common.style :as common-style]
|
||||
@@ -10,27 +11,23 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- swipeable
|
||||
[{:keys [active-swipeable extra-fn]} child]
|
||||
[{:keys [extra-fn]} child]
|
||||
[common/swipeable
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:extra-fn extra-fn}
|
||||
child])
|
||||
|
||||
(defn- get-header-text-and-context
|
||||
[community membership-status]
|
||||
(let [community-name (:name community)
|
||||
permissions (:permissions community)
|
||||
open? (not= 3 (:access permissions))
|
||||
community-image (get-in community [:images :thumbnail :uri])
|
||||
[community-logo community-name community-permissions membership-status]
|
||||
(let [open? (not= 3 (:access community-permissions))
|
||||
community-context-tag [quo/context-tag
|
||||
{:type :community
|
||||
:size 24
|
||||
:blur? true
|
||||
:community-logo community-image
|
||||
:community-logo community-logo
|
||||
:community-name community-name}]]
|
||||
(cond
|
||||
(= membership-status constants/activity-center-membership-status-idle)
|
||||
@@ -56,27 +53,33 @@
|
||||
:t/joined-community
|
||||
:t/community-request-accepted-body-text)
|
||||
(when open? {:community community-name}))]
|
||||
community-context-tag]}
|
||||
|
||||
:else nil)))
|
||||
community-context-tag]})))
|
||||
|
||||
(defn view
|
||||
[{:keys [notification set-swipeable-height customization-color] :as props}]
|
||||
[{:keys [notification extra-fn]}]
|
||||
(let [{:keys [community-id membership-status read
|
||||
timestamp]} notification
|
||||
community (rf/sub [:communities/community community-id])
|
||||
{:keys [header-text context]} (get-header-text-and-context community
|
||||
membership-status)]
|
||||
[swipeable props
|
||||
[gesture/touchable-without-feedback
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:communities/navigate-to-community-overview community-id]))}
|
||||
timestamp]} notification
|
||||
community-name (rf/sub [:communities/name community-id])
|
||||
community-logo (rf/sub [:communities/logo community-id])
|
||||
community-permissions (rf/sub [:communities/permissions community-id])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
{:keys [header-text
|
||||
context]} (get-header-text-and-context community-logo
|
||||
community-name
|
||||
community-permissions
|
||||
membership-status)
|
||||
on-press (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:communities/navigate-to-community-overview
|
||||
community-id]))
|
||||
[community-id])]
|
||||
[swipeable {:extra-fn extra-fn}
|
||||
[gesture/touchable-without-feedback {:on-press on-press}
|
||||
[quo/activity-log
|
||||
{:title header-text
|
||||
:customization-color customization-color
|
||||
:icon :i/communities
|
||||
:on-layout set-swipeable-height
|
||||
:timestamp (datetime/timestamp->relative timestamp)
|
||||
:unread? (not read)
|
||||
:context context}]]]))
|
||||
|
||||
+41
-28
@@ -1,6 +1,7 @@
|
||||
(ns status-im.contexts.shell.activity-center.notification.contact-requests.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
quo.theme
|
||||
[react-native.core :as rn]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.shell.activity-center.notification.common.style :as common-style]
|
||||
@@ -24,48 +25,52 @@
|
||||
:text (i18n/label :t/decline)}])
|
||||
|
||||
(defn- swipeable
|
||||
[{:keys [active-swipeable extra-fn notification]} child]
|
||||
[{:keys [extra-fn notification]} child]
|
||||
(let [{:keys [id author message]} notification
|
||||
{:keys [contact-request-state]} message
|
||||
{:keys [public-key]} (rf/sub [:multiaccount/contact])
|
||||
outgoing? (= public-key author)]
|
||||
outgoing? (= public-key author)
|
||||
accept (rn/use-callback
|
||||
#(rf/dispatch [:activity-center.contact-requests/accept id])
|
||||
[id])
|
||||
decline (rn/use-callback
|
||||
#(rf/dispatch [:activity-center.contact-requests/decline id])
|
||||
[id])]
|
||||
(cond
|
||||
(or (#{constants/contact-request-message-state-accepted
|
||||
constants/contact-request-message-state-declined}
|
||||
contact-request-state)
|
||||
(and outgoing? (= contact-request-state constants/contact-request-message-state-pending)))
|
||||
[common/swipeable
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:extra-fn extra-fn}
|
||||
child]
|
||||
|
||||
(and (= contact-request-state constants/contact-request-message-state-pending)
|
||||
(not outgoing?))
|
||||
[common/swipeable
|
||||
{:left-button swipe-button-accept
|
||||
:left-on-press #(rf/dispatch [:activity-center.contact-requests/accept id])
|
||||
:right-button swipe-button-decline
|
||||
:right-on-press #(rf/dispatch [:activity-center.contact-requests/decline id])
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button swipe-button-accept
|
||||
:left-on-press accept
|
||||
:right-button swipe-button-decline
|
||||
:right-on-press decline
|
||||
:extra-fn extra-fn}
|
||||
child]
|
||||
|
||||
:else
|
||||
child)))
|
||||
|
||||
(defn- outgoing-contact-request-view
|
||||
[{:keys [notification set-swipeable-height customization-color]} theme]
|
||||
[{:keys [notification]} theme]
|
||||
(let [{:keys [chat-id message last-message accepted]} notification
|
||||
{:keys [contact-request-state] :as message} (or message last-message)]
|
||||
{:keys [contact-request-state] :as message} (or message last-message)
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
(if accepted
|
||||
[quo/activity-log
|
||||
{:title (i18n/label :t/contact-request-was-accepted)
|
||||
:customization-color customization-color
|
||||
:on-layout set-swipeable-height
|
||||
:icon :i/add-user
|
||||
:timestamp (datetime/timestamp->relative (:timestamp notification))
|
||||
:unread? (not (:read notification))
|
||||
@@ -76,7 +81,6 @@
|
||||
[quo/activity-log
|
||||
{:title (i18n/label :t/contact-request)
|
||||
:customization-color customization-color
|
||||
:on-layout set-swipeable-height
|
||||
:icon :i/add-user
|
||||
:timestamp (datetime/timestamp->relative (:timestamp notification))
|
||||
:unread? (not (:read notification))
|
||||
@@ -102,13 +106,22 @@
|
||||
nil)}])))
|
||||
|
||||
(defn- incoming-contact-request-view
|
||||
[{:keys [notification set-swipeable-height customization-color]} theme]
|
||||
(let [{:keys [id author message last-message]} notification
|
||||
message (or message last-message)]
|
||||
[{:keys [notification]} theme]
|
||||
(let [{:keys [id author message
|
||||
last-message]} notification
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
message (or message last-message)
|
||||
accept (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:activity-center.contact-requests/accept id]))
|
||||
[id])
|
||||
decline (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:activity-center.contact-requests/decline id]))
|
||||
[id])]
|
||||
[quo/activity-log
|
||||
{:title (i18n/label :t/contact-request)
|
||||
:customization-color customization-color
|
||||
:on-layout set-swipeable-height
|
||||
:icon :i/add-user
|
||||
:timestamp (datetime/timestamp->relative (:timestamp notification))
|
||||
:unread? (not (:read notification))
|
||||
@@ -140,13 +153,13 @@
|
||||
:key :button-decline
|
||||
:label (i18n/label :t/decline)
|
||||
:accessibility-label :decline-contact-request
|
||||
:on-press #(rf/dispatch [:activity-center.contact-requests/decline id])}
|
||||
:on-press decline}
|
||||
{:type :button
|
||||
:subtype :positive
|
||||
:key :button-accept
|
||||
:label (i18n/label :t/accept)
|
||||
:accessibility-label :accept-contact-request
|
||||
:on-press #(rf/dispatch [:activity-center.contact-requests/accept id])}]
|
||||
:on-press accept}]
|
||||
|
||||
nil)}]))
|
||||
|
||||
@@ -155,16 +168,16 @@
|
||||
(let [{:keys [author message last-message]} notification
|
||||
{:keys [public-key]} (rf/sub [:multiaccount/contact])
|
||||
{:keys [contact-request-state]} (or message last-message)
|
||||
app-theme (rf/sub [:theme])]
|
||||
theme (quo.theme/use-theme)]
|
||||
[swipeable props
|
||||
(cond
|
||||
(= public-key author)
|
||||
[outgoing-contact-request-view props app-theme]
|
||||
[outgoing-contact-request-view props theme]
|
||||
|
||||
(= contact-request-state constants/contact-request-message-state-accepted)
|
||||
[rn/pressable
|
||||
{:on-press #(rf/dispatch [:chat.ui/start-chat author])}
|
||||
[incoming-contact-request-view props app-theme]]
|
||||
[incoming-contact-request-view props theme]]
|
||||
|
||||
:else
|
||||
[incoming-contact-request-view props app-theme])]))
|
||||
[incoming-contact-request-view props theme])]))
|
||||
|
||||
+95
-99
@@ -105,7 +105,7 @@
|
||||
(rf/dispatch [:activity-center.notifications/mark-as-read id]))
|
||||
|
||||
(defn- swipeable
|
||||
[{:keys [active-swipeable extra-fn notification replying?] :as props} child]
|
||||
[{:keys [extra-fn notification replying?] :as props} child]
|
||||
(let [{:keys [id message
|
||||
contact-verification-status]} notification
|
||||
challenger? (:outgoing message)]
|
||||
@@ -116,23 +116,21 @@
|
||||
(and (not challenger?)
|
||||
(= contact-verification-status constants/contact-verification-status-pending))
|
||||
[common/swipeable
|
||||
{:left-button swipe-button-reply
|
||||
:left-on-press #(prepare-challenge-reply props)
|
||||
:right-button swipe-button-decline
|
||||
:right-on-press #(decline-challenge id)
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button swipe-button-reply
|
||||
:left-on-press #(prepare-challenge-reply props)
|
||||
:right-button swipe-button-decline
|
||||
:right-on-press #(decline-challenge id)
|
||||
:extra-fn extra-fn}
|
||||
child]
|
||||
|
||||
(and challenger?
|
||||
(= contact-verification-status constants/contact-verification-status-accepted))
|
||||
[common/swipeable
|
||||
{:left-button swipe-button-trust
|
||||
:left-on-press #(mark-challenge-trusted id)
|
||||
:right-button swipe-button-untrustworthy
|
||||
:right-on-press #(mark-challenge-untrustworthy id)
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button swipe-button-trust
|
||||
:left-on-press #(mark-challenge-trusted id)
|
||||
:right-button swipe-button-untrustworthy
|
||||
:right-on-press #(mark-challenge-untrustworthy id)
|
||||
:extra-fn extra-fn}
|
||||
child]
|
||||
|
||||
(#{constants/contact-verification-status-accepted
|
||||
@@ -140,12 +138,11 @@
|
||||
constants/contact-verification-status-trusted}
|
||||
contact-verification-status)
|
||||
[common/swipeable
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:extra-fn extra-fn}
|
||||
child]
|
||||
|
||||
:else
|
||||
@@ -154,8 +151,9 @@
|
||||
(defn view
|
||||
[_]
|
||||
(let [reply (atom "")]
|
||||
(fn [{:keys [notification set-swipeable-height replying? customization-color] :as props}]
|
||||
(let [{:keys [id message
|
||||
(fn [{:keys [notification replying?] :as props}]
|
||||
(let [customization-color (rf/sub [:profile/customization-color])
|
||||
{:keys [id message
|
||||
contact-verification-status]} notification
|
||||
challenger? (:outgoing message)]
|
||||
;; TODO(@ilmotta): Declined challenges should only be displayed for the challengee, not the
|
||||
@@ -165,86 +163,84 @@
|
||||
(= contact-verification-status constants/contact-verification-status-declined))
|
||||
[swipeable props
|
||||
[quo/activity-log
|
||||
(merge
|
||||
(when-not replying?
|
||||
{:on-layout set-swipeable-height})
|
||||
{:title (i18n/label :t/identity-verification-request)
|
||||
:customization-color customization-color
|
||||
:icon :i/friend
|
||||
:timestamp (datetime/timestamp->relative (:timestamp notification))
|
||||
:unread? (not (:read notification))
|
||||
:on-update-reply #(reset! reply %)
|
||||
:replying? replying?
|
||||
:max-reply-length max-reply-length
|
||||
:valid-reply? valid-reply?
|
||||
:context (context-tags challenger? notification)
|
||||
:message (activity-message challenger? notification)
|
||||
:items
|
||||
(cond-> []
|
||||
(and challenger?
|
||||
(= contact-verification-status constants/contact-verification-status-accepted))
|
||||
(concat
|
||||
[{:type :button
|
||||
:subtype :danger
|
||||
:key :button-mark-as-untrustworthy
|
||||
:label (i18n/label :t/untrustworthy)
|
||||
:accessibility-label :mark-contact-verification-as-untrustworthy
|
||||
:on-press #(mark-challenge-untrustworthy id)}
|
||||
{:type :button
|
||||
:subtype :positive
|
||||
:key :button-accept
|
||||
:label (i18n/label :t/accept)
|
||||
:accessibility-label :mark-contact-verification-as-trusted
|
||||
:on-press #(mark-challenge-trusted id)}])
|
||||
{:title (i18n/label :t/identity-verification-request)
|
||||
:customization-color customization-color
|
||||
:icon :i/friend
|
||||
:timestamp (datetime/timestamp->relative (:timestamp notification))
|
||||
:unread? (not (:read notification))
|
||||
:on-update-reply #(reset! reply %)
|
||||
:replying? replying?
|
||||
:max-reply-length max-reply-length
|
||||
:valid-reply? valid-reply?
|
||||
:context (context-tags challenger? notification)
|
||||
:message (activity-message challenger? notification)
|
||||
:items
|
||||
(cond-> []
|
||||
(and challenger?
|
||||
(= contact-verification-status constants/contact-verification-status-accepted))
|
||||
(concat
|
||||
[{:type :button
|
||||
:subtype :danger
|
||||
:key :button-mark-as-untrustworthy
|
||||
:label (i18n/label :t/untrustworthy)
|
||||
:accessibility-label :mark-contact-verification-as-untrustworthy
|
||||
:on-press #(mark-challenge-untrustworthy id)}
|
||||
{:type :button
|
||||
:subtype :positive
|
||||
:key :button-accept
|
||||
:label (i18n/label :t/accept)
|
||||
:accessibility-label :mark-contact-verification-as-trusted
|
||||
:on-press #(mark-challenge-trusted id)}])
|
||||
|
||||
(and challenger?
|
||||
(= contact-verification-status constants/contact-verification-status-trusted))
|
||||
(concat [{:type :status
|
||||
:subtype :positive
|
||||
:key :status-trusted
|
||||
:label (i18n/label :t/status-confirmed)}])
|
||||
(and challenger?
|
||||
(= contact-verification-status constants/contact-verification-status-trusted))
|
||||
(concat [{:type :status
|
||||
:subtype :positive
|
||||
:key :status-trusted
|
||||
:label (i18n/label :t/status-confirmed)}])
|
||||
|
||||
(and challenger?
|
||||
(= contact-verification-status constants/contact-verification-status-untrustworthy))
|
||||
(concat [{:type :status
|
||||
:subtype :negative
|
||||
:key :status-untrustworthy
|
||||
:label (i18n/label :t/untrustworthy)}])
|
||||
(and challenger?
|
||||
(= contact-verification-status
|
||||
constants/contact-verification-status-untrustworthy))
|
||||
(concat [{:type :status
|
||||
:subtype :negative
|
||||
:key :status-untrustworthy
|
||||
:label (i18n/label :t/untrustworthy)}])
|
||||
|
||||
(and (not challenger?)
|
||||
(= contact-verification-status constants/contact-verification-status-accepted))
|
||||
(concat [{:type :status
|
||||
:subtype :positive
|
||||
:key :status-accepted
|
||||
:label (i18n/label :t/replied)}])
|
||||
(and (not challenger?)
|
||||
(= contact-verification-status constants/contact-verification-status-accepted))
|
||||
(concat [{:type :status
|
||||
:subtype :positive
|
||||
:key :status-accepted
|
||||
:label (i18n/label :t/replied)}])
|
||||
|
||||
(and (not challenger?)
|
||||
(= contact-verification-status constants/contact-verification-status-declined))
|
||||
(concat [{:type :status
|
||||
:subtype :negative
|
||||
:key :status-declined
|
||||
:label (i18n/label :t/declined)}])
|
||||
(and (not challenger?)
|
||||
(= contact-verification-status constants/contact-verification-status-declined))
|
||||
(concat [{:type :status
|
||||
:subtype :negative
|
||||
:key :status-declined
|
||||
:label (i18n/label :t/declined)}])
|
||||
|
||||
(and (not challenger?)
|
||||
(= contact-verification-status constants/contact-verification-status-pending))
|
||||
(concat
|
||||
[{:type :button
|
||||
:subtype :danger
|
||||
:key :button-decline
|
||||
:label (i18n/label :t/decline)
|
||||
:accessibility-label :decline-contact-verification
|
||||
:on-press #(decline-challenge id)}
|
||||
(if replying?
|
||||
{:type :button
|
||||
:subtype :primary
|
||||
:key :button-reply
|
||||
:label (i18n/label :t/send-reply)
|
||||
:accessibility-label :reply-to-contact-verification
|
||||
:disable-when invalid-reply?
|
||||
:on-press #(send-challenge-reply id @reply)}
|
||||
{:type :button
|
||||
:subtype :primary
|
||||
:key :button-send-reply
|
||||
:label (i18n/label :t/message-reply)
|
||||
:accessibility-label :send-reply-to-contact-verification
|
||||
:on-press #(prepare-challenge-reply props)})]))})]])))))
|
||||
(and (not challenger?)
|
||||
(= contact-verification-status constants/contact-verification-status-pending))
|
||||
(concat
|
||||
[{:type :button
|
||||
:subtype :danger
|
||||
:key :button-decline
|
||||
:label (i18n/label :t/decline)
|
||||
:accessibility-label :decline-contact-verification
|
||||
:on-press #(decline-challenge id)}
|
||||
(if replying?
|
||||
{:type :button
|
||||
:subtype :primary
|
||||
:key :button-reply
|
||||
:label (i18n/label :t/send-reply)
|
||||
:accessibility-label :reply-to-contact-verification
|
||||
:disable-when invalid-reply?
|
||||
:on-press #(send-challenge-reply id @reply)}
|
||||
{:type :button
|
||||
:subtype :primary
|
||||
:key :button-send-reply
|
||||
:label (i18n/label :t/message-reply)
|
||||
:accessibility-label :send-reply-to-contact-verification
|
||||
:on-press #(prepare-challenge-reply props)})]))}]])))))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im.contexts.shell.activity-center.notification.membership.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.contexts.shell.activity-center.notification.common.style :as common-style]
|
||||
[status-im.contexts.shell.activity-center.notification.common.view :as common]
|
||||
@@ -33,35 +34,50 @@
|
||||
:text (i18n/label :t/decline)}])
|
||||
|
||||
(defn- swipeable
|
||||
[{:keys [active-swipeable notification extra-fn]} child]
|
||||
(let [{:keys [accepted dismissed id]} notification]
|
||||
[{:keys [notification extra-fn]} child]
|
||||
(let [{:keys [accepted dismissed
|
||||
id]} notification
|
||||
accept (rn/use-callback
|
||||
(fn [] (rf/dispatch [:activity-center.notifications/accept id]))
|
||||
[id])
|
||||
dismiss (rn/use-callback
|
||||
(fn [] (rf/dispatch [:activity-center.notifications/dismiss id]))
|
||||
[id])]
|
||||
(if (or accepted dismissed)
|
||||
[common/swipeable
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:extra-fn extra-fn}
|
||||
child]
|
||||
[common/swipeable
|
||||
{:left-button swipe-button-accept
|
||||
:left-on-press #(rf/dispatch [:activity-center.notifications/accept id])
|
||||
:right-button swipe-button-decline
|
||||
:right-on-press #(rf/dispatch [:activity-center.notifications/dismiss id])
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button swipe-button-accept
|
||||
:left-on-press accept
|
||||
:right-button swipe-button-decline
|
||||
:right-on-press dismiss
|
||||
:extra-fn extra-fn}
|
||||
child])))
|
||||
|
||||
(defn view
|
||||
[{:keys [notification set-swipeable-height customization-color] :as props}]
|
||||
(let [{:keys [id accepted dismissed author read timestamp chat-name chat-id]} notification]
|
||||
[{:keys [notification] :as props}]
|
||||
(let [{:keys [id accepted dismissed author read
|
||||
timestamp chat-name
|
||||
chat-id]} notification
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
accept (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:activity-center.notifications/accept id]))
|
||||
[id])
|
||||
dismiss (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:activity-center.notifications/dismiss id]))
|
||||
[id])]
|
||||
[swipeable props
|
||||
[pressable {:accepted accepted :chat-id chat-id}
|
||||
[quo/activity-log
|
||||
{:title (i18n/label :t/added-to-group-chat)
|
||||
:customization-color customization-color
|
||||
:on-layout set-swipeable-height
|
||||
:icon :i/add-user
|
||||
:timestamp (datetime/timestamp->relative timestamp)
|
||||
:unread? (not read)
|
||||
@@ -78,13 +94,10 @@
|
||||
:key :button-accept
|
||||
:label (i18n/label :t/accept)
|
||||
:accessibility-label :accept-group-chat-invitation
|
||||
:on-press #(rf/dispatch
|
||||
[:activity-center.notifications/accept id])}
|
||||
:on-press accept}
|
||||
{:type :button
|
||||
:subtype :danger
|
||||
:key :button-decline
|
||||
:label (i18n/label :t/decline)
|
||||
:accessibility-label :decline-group-chat-invitation
|
||||
:on-press #(rf/dispatch
|
||||
[:activity-center.notifications/dismiss
|
||||
id])}])}]]]))
|
||||
:on-press dismiss}])}]]]))
|
||||
|
||||
@@ -30,25 +30,24 @@
|
||||
parsed-text-children))))
|
||||
|
||||
(defn- swipeable
|
||||
[{:keys [active-swipeable extra-fn]} child]
|
||||
[{:keys [extra-fn]} child]
|
||||
[common/swipeable
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:extra-fn extra-fn}
|
||||
child])
|
||||
|
||||
(defn view
|
||||
[{:keys [notification set-swipeable-height customization-color] :as props}]
|
||||
[{:keys [notification extra-fn]}]
|
||||
(let [{:keys [author chat-name community-id chat-id
|
||||
message read timestamp]} notification
|
||||
community-chat? (not (string/blank? community-id))
|
||||
community (rf/sub [:communities/community community-id])
|
||||
community-name (:name community)
|
||||
community-image (get-in community [:images :thumbnail :uri])]
|
||||
[swipeable props
|
||||
community-name (rf/sub [:communities/name community-id])
|
||||
community-logo (rf/sub [:communities/logo community-id])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[swipeable {:extra-fn extra-fn}
|
||||
[gesture/touchable-without-feedback
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:hide-popover])
|
||||
@@ -56,7 +55,6 @@
|
||||
[quo/activity-log
|
||||
{:title (i18n/label :t/mention)
|
||||
:customization-color customization-color
|
||||
:on-layout set-swipeable-height
|
||||
:icon :i/mention
|
||||
:timestamp (datetime/timestamp->relative timestamp)
|
||||
:unread? (not read)
|
||||
@@ -68,7 +66,7 @@
|
||||
{:type :channel
|
||||
:blur? true
|
||||
:size 24
|
||||
:community-logo community-image
|
||||
:community-logo community-logo
|
||||
:community-name community-name
|
||||
:channel-name chat-name}]
|
||||
[quo/context-tag
|
||||
|
||||
@@ -51,26 +51,26 @@
|
||||
nil))
|
||||
|
||||
(defn- swipeable
|
||||
[{:keys [active-swipeable extra-fn]} child]
|
||||
[{:keys [extra-fn]} child]
|
||||
[common/swipeable
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:active-swipeable active-swipeable
|
||||
:extra-fn extra-fn}
|
||||
{:left-button common/swipe-button-read-or-unread
|
||||
:left-on-press common/swipe-on-press-toggle-read
|
||||
:right-button common/swipe-button-delete
|
||||
:right-on-press common/swipe-on-press-delete
|
||||
:extra-fn extra-fn}
|
||||
child])
|
||||
|
||||
(defn view
|
||||
[{:keys [notification set-swipeable-height customization-color] :as props}]
|
||||
[{:keys [notification extra-fn]}]
|
||||
(let [{:keys [author chat-name community-id chat-id
|
||||
message read timestamp album-messages]} notification
|
||||
community-chat? (not (string/blank? community-id))
|
||||
community (rf/sub [:communities/community community-id])
|
||||
community-name (:name community)
|
||||
community-image (get-in community [:images :thumbnail :uri])
|
||||
media-server-port (rf/sub [:mediaserver/port])]
|
||||
[swipeable props
|
||||
message read timestamp
|
||||
album-messages]} notification
|
||||
community-chat? (not (string/blank? community-id))
|
||||
community-name (rf/sub [:communities/name community-id])
|
||||
community-logo (rf/sub [:communities/logo community-id])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
media-server-port (rf/sub [:mediaserver/port])]
|
||||
[swipeable {:extra-fn extra-fn}
|
||||
[gesture/touchable-without-feedback
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:hide-popover])
|
||||
@@ -78,7 +78,6 @@
|
||||
[quo/activity-log
|
||||
{:title (i18n/label :t/message-reply)
|
||||
:customization-color customization-color
|
||||
:on-layout set-swipeable-height
|
||||
:icon :i/reply
|
||||
:timestamp (datetime/timestamp->relative timestamp)
|
||||
:unread? (not read)
|
||||
@@ -89,7 +88,7 @@
|
||||
{:type :channel
|
||||
:blur? true
|
||||
:size 24
|
||||
:community-logo community-image
|
||||
:community-logo community-logo
|
||||
:community-name community-name
|
||||
:channel-name chat-name}]
|
||||
[quo/context-tag
|
||||
@@ -113,10 +112,7 @@
|
||||
|
||||
(= (:content-type message)
|
||||
constants/content-type-gif)
|
||||
:gif
|
||||
|
||||
:else
|
||||
nil)
|
||||
:gif)
|
||||
:body (get-message-content message
|
||||
album-messages
|
||||
media-server-port)}}]]]))
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
(ns status-im.contexts.shell.activity-center.view
|
||||
(:require
|
||||
[oops.core :as oops]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.navigation :as navigation]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.shell.activity-center.context :as ac.context]
|
||||
[status-im.contexts.shell.activity-center.header.view :as header]
|
||||
[status-im.contexts.shell.activity-center.notification-types :as types]
|
||||
[status-im.contexts.shell.activity-center.notification.admin.view :as admin]
|
||||
@@ -23,61 +24,68 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn notification-component
|
||||
[{:keys [type] :as notification} index]
|
||||
(let [extra-fn (rn/use-callback
|
||||
(fn []
|
||||
{:notification notification})
|
||||
[notification])
|
||||
props {:notification notification
|
||||
:extra-fn extra-fn}]
|
||||
;; Notifications are expensive to render. Without `delay-render` the opening
|
||||
;; animation of the Activity Center can be clunky and the time to open the
|
||||
;; AC after pressing the bell icon can be high.
|
||||
[rn/view {:style (style/notification-container index)}
|
||||
(cond
|
||||
(= type types/contact-verification)
|
||||
[contact-verification/view props]
|
||||
|
||||
(= type types/contact-request)
|
||||
[contact-requests/view props]
|
||||
|
||||
(= type types/mention)
|
||||
[mentions/view props]
|
||||
|
||||
(= type types/reply)
|
||||
[reply/view props]
|
||||
|
||||
(= type types/admin)
|
||||
[admin/view props]
|
||||
|
||||
(some types/membership [type])
|
||||
(condp = type
|
||||
types/private-group-chat [membership/view props]
|
||||
types/community-request [community-request/view props]
|
||||
types/community-kicked [community-kicked/view props]
|
||||
nil))]))
|
||||
|
||||
(defn- fetch-next-page
|
||||
[]
|
||||
(let [height (atom 0)
|
||||
set-swipeable-height #(reset! height (oops/oget % "nativeEvent.layout.height"))]
|
||||
(fn [{:keys [type] :as notification} index _ {:keys [active-swipeable customization-color]}]
|
||||
(let [props {:height height
|
||||
:customization-color customization-color
|
||||
:active-swipeable active-swipeable
|
||||
:set-swipeable-height set-swipeable-height
|
||||
:notification notification
|
||||
:extra-fn (fn [] {:height @height :notification notification})}]
|
||||
[rn/view {:style (style/notification-container index)}
|
||||
(cond
|
||||
(= type types/contact-verification)
|
||||
[contact-verification/view props]
|
||||
|
||||
(= type types/contact-request)
|
||||
[contact-requests/view props]
|
||||
|
||||
(= type types/mention)
|
||||
[mentions/view props]
|
||||
|
||||
(= type types/reply)
|
||||
[reply/view props]
|
||||
|
||||
(= type types/admin)
|
||||
[admin/view props]
|
||||
|
||||
(some types/membership [type])
|
||||
(condp = type
|
||||
types/private-group-chat [membership/view props]
|
||||
types/community-request [community-request/view props]
|
||||
types/community-kicked [community-kicked/view props]
|
||||
nil)
|
||||
|
||||
:else
|
||||
nil)]))))
|
||||
(rf/dispatch [:activity-center.notifications/fetch-next-page]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [active-swipeable (atom nil)]
|
||||
(rf/dispatch [:activity-center.notifications/fetch-first-page])
|
||||
(fn []
|
||||
(let [notifications (rf/sub [:activity-center/notifications])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[quo/overlay {:type :shell}
|
||||
[rn/view {:flex 1 :padding-top (navigation/status-bar-height)}
|
||||
[header/header]
|
||||
[rn/flat-list
|
||||
{:data notifications
|
||||
:render-data {:active-swipeable active-swipeable
|
||||
:customization-color customization-color}
|
||||
:content-container-style {:flex-grow 1}
|
||||
:empty-component [empty-tab/empty-tab]
|
||||
:key-fn :id
|
||||
:on-scroll-to-index-failed identity
|
||||
:on-end-reached #(rf/dispatch [:activity-center.notifications/fetch-next-page])
|
||||
:render-fn notification-component}]]
|
||||
]))))
|
||||
(let [notifications (rf/sub [:activity-center/notifications])
|
||||
|
||||
;; We globally control the active swipeable for all notifications
|
||||
;; because when a swipe left/right gesture initiates, the previously
|
||||
;; active swiped notification (if any) must be removed & closed with
|
||||
;; animation.
|
||||
active-swipeable (rn/use-ref-atom nil)]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(rf/dispatch [:activity-center.notifications/fetch-first-page])))
|
||||
|
||||
[ac.context/provider {:active-swipeable active-swipeable}
|
||||
[quo/overlay {:type :shell}
|
||||
[rn/view {:style {:flex 1 :padding-top (navigation/status-bar-height)}}
|
||||
[header/header]
|
||||
(rn/delay-render
|
||||
[rn/flat-list
|
||||
{:data notifications
|
||||
:initial-num-to-render constants/notifications-per-page
|
||||
:content-container-style {:flex-grow 1}
|
||||
:empty-component [empty-tab/empty-tab]
|
||||
:key-fn :id
|
||||
:on-scroll-to-index-failed identity
|
||||
:on-end-reached fetch-next-page
|
||||
:render-fn notification-component}])]]]))
|
||||
|
||||
@@ -117,13 +117,14 @@
|
||||
(defn- f-internal-view
|
||||
[]
|
||||
(let [{:keys [keyboard-shown]} (hooks/use-keyboard)]
|
||||
[:<>
|
||||
(when keyboard-shown
|
||||
(rn/dismiss-keyboard!))
|
||||
[scan-qr-code/view
|
||||
{:title (i18n/label :t/scan-qr)
|
||||
:share-button? true
|
||||
:on-success-scan on-qr-code-scanned}]]))
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(when keyboard-shown
|
||||
(rn/dismiss-keyboard!))))
|
||||
[scan-qr-code/view
|
||||
{:title (i18n/label :t/scan-qr)
|
||||
:share-button? true
|
||||
:on-success-scan on-qr-code-scanned}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
(ns status-im.contexts.shell.share.wallet.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn indicator-wrapper-style
|
||||
[active?]
|
||||
{:width 8
|
||||
:height 8
|
||||
:border-radius 4
|
||||
:background-color colors/white
|
||||
:opacity (if active? 1.0 0.5)})
|
||||
|
||||
(def indicator-list-style
|
||||
{:display :flex
|
||||
:flex-direction :row
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:gap 8})
|
||||
@@ -6,7 +6,6 @@
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.shell.share.style :as style]
|
||||
[status-im.contexts.shell.share.wallet.style :as wallet-style]
|
||||
[status-im.contexts.wallet.common.utils :as utils]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
@@ -85,16 +84,6 @@
|
||||
:on-legacy-press on-legacy-press
|
||||
:on-settings-press on-settings-press}]]]))))
|
||||
|
||||
(defn- indicator
|
||||
[active?]
|
||||
[rn/view {:style (wallet-style/indicator-wrapper-style active?)}])
|
||||
|
||||
(defn- indicator-list
|
||||
[num-indicators current-index]
|
||||
[rn/view {:style wallet-style/indicator-list-style}
|
||||
(for [i (range num-indicators)]
|
||||
^{:key i} [indicator (= current-index i)])])
|
||||
|
||||
(defn render-item
|
||||
[{:keys [address] :as account}]
|
||||
[wallet-qr-code-item
|
||||
@@ -136,4 +125,7 @@
|
||||
:render-fn render-item}]
|
||||
(when (> num-accounts 1)
|
||||
[rn/view {:style {:margin-top 20}}
|
||||
[indicator-list num-accounts @current-index]])]))))
|
||||
[quo/slider-bar
|
||||
{:total-amount num-accounts
|
||||
:active-index @current-index
|
||||
:blur? true}]])]))))
|
||||
|
||||
@@ -185,7 +185,7 @@
|
||||
;; We delay the navigation because we need re-frame to update the DB on time.
|
||||
;; By doing it, we skip a blink while visiting the collectible detail page.
|
||||
[:dispatch-later
|
||||
{:ms 1
|
||||
{:ms 17
|
||||
:dispatch [:navigate-to :screen/wallet.collectible]}]]})))
|
||||
|
||||
(defn- keep-not-empty-value
|
||||
|
||||
@@ -79,12 +79,20 @@
|
||||
(rf/dispatch [:wallet/clear-collectible-details]))
|
||||
|
||||
(defn animated-header
|
||||
[{: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
|
||||
(colors/theme-colors colors/white-opa-0 colors/neutral-95-opa-0 theme)
|
||||
(colors/theme-colors colors/white-opa-50 colors/neutral-95-opa-70-blur theme))]
|
||||
[{:keys [scroll-amount title-opacity page-nav-type theme]}]
|
||||
(let [blur-amount (header-animations/use-blur-amount scroll-amount)
|
||||
layer-opacity (header-animations/use-layer-opacity
|
||||
scroll-amount
|
||||
(colors/theme-colors colors/white-opa-0
|
||||
colors/neutral-95-opa-0
|
||||
theme)
|
||||
(colors/theme-colors colors/white-opa-50
|
||||
colors/neutral-95-opa-70-blur
|
||||
theme))
|
||||
{{preview-uri :uri} :preview-url
|
||||
{title :name} :collectible-data
|
||||
{description :name} :collection-data
|
||||
id :id} (rf/sub [:wallet/collectible-details])]
|
||||
[rn/view {:style (style/animated-header)}
|
||||
[reanimated/blur-view
|
||||
{:style {:flex 1
|
||||
@@ -97,7 +105,7 @@
|
||||
[reanimated/view {:style layer-opacity}
|
||||
[quo/page-nav
|
||||
{:type page-nav-type
|
||||
:picture picture
|
||||
:picture preview-uri
|
||||
:title title
|
||||
:description description
|
||||
:background :blur
|
||||
@@ -110,7 +118,7 @@
|
||||
{:content (fn []
|
||||
[options-drawer/view
|
||||
{:name title
|
||||
:image picture
|
||||
:image preview-uri
|
||||
:id id}])
|
||||
:theme theme}])}]
|
||||
:center-opacity title-opacity}]]]]))
|
||||
@@ -144,10 +152,11 @@
|
||||
[_]
|
||||
(let [selected-tab (reagent/atom :overview)
|
||||
on-tab-change #(reset! selected-tab %)]
|
||||
(fn [{:keys [collectible set-title-bottom theme]}]
|
||||
(fn [{:keys [set-title-bottom theme]}]
|
||||
(let [title-ref (rn/use-ref-atom nil)
|
||||
set-title-ref (rn/use-callback #(reset! title-ref %))
|
||||
animation-shared-element-id (rf/sub [:animation-shared-element-id])
|
||||
collectible (rf/sub [:wallet/collectible-details])
|
||||
collectible-owner (rf/sub [:wallet/collectible-details-owner collectible])
|
||||
aspect-ratio (rf/sub [:wallet/collectible-aspect-ratio])
|
||||
gradient-color (rf/sub [:wallet/collectible-gradient-color])
|
||||
@@ -196,14 +205,14 @@
|
||||
token-id
|
||||
{:images [collectible-image]
|
||||
:index 0
|
||||
:on-options-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[options-drawer/view
|
||||
{:name collectible-name
|
||||
:image
|
||||
preview-uri
|
||||
:id id}])}])}])))
|
||||
:on-options-press #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content
|
||||
(fn []
|
||||
[options-drawer/view
|
||||
{:name collectible-name
|
||||
:image preview-uri
|
||||
:id id}])}])}])))
|
||||
:on-collectible-load (fn []
|
||||
;; We need to delay the measurement because the
|
||||
;; navigation has an animation
|
||||
@@ -241,33 +250,24 @@
|
||||
|
||||
(defn view
|
||||
[_]
|
||||
(let [{:keys [top]} (safe-area/get-insets)
|
||||
theme (quo.theme/use-theme)
|
||||
title-bottom-coord (rn/use-ref-atom 0)
|
||||
set-title-bottom (rn/use-callback
|
||||
(fn [_ y _ height]
|
||||
(reset! title-bottom-coord
|
||||
(get-title-bottom-y-position y height))))
|
||||
scroll-amount (reanimated/use-shared-value 0)
|
||||
title-opacity (reanimated/use-shared-value 0)
|
||||
{:keys [collection-data
|
||||
collectible-data
|
||||
preview-url]
|
||||
:as collectible} (rf/sub [:wallet/collectible-details])]
|
||||
(let [{:keys [top]} (safe-area/get-insets)
|
||||
theme (quo.theme/use-theme)
|
||||
title-bottom-coord (rn/use-ref-atom 0)
|
||||
set-title-bottom (rn/use-callback
|
||||
(fn [_ y _ height]
|
||||
(reset! title-bottom-coord
|
||||
(get-title-bottom-y-position y height))))
|
||||
scroll-amount (reanimated/use-shared-value 0)
|
||||
title-opacity (reanimated/use-shared-value 0)]
|
||||
[rn/view {:style (style/background-color theme)}
|
||||
[animated-header
|
||||
{:id (:id collectible)
|
||||
:scroll-amount scroll-amount
|
||||
{:scroll-amount scroll-amount
|
||||
:title-opacity title-opacity
|
||||
:page-nav-type :title-description
|
||||
:picture (:uri preview-url)
|
||||
:title (:name collectible-data)
|
||||
:description (:name collection-data)
|
||||
:theme theme}]
|
||||
[reanimated/scroll-view
|
||||
{:style (style/scroll-view top)
|
||||
:on-scroll #(on-scroll % scroll-amount title-opacity title-bottom-coord)}
|
||||
[collectible-details
|
||||
{:collectible collectible
|
||||
:set-title-bottom set-title-bottom
|
||||
{:set-title-bottom set-title-bottom
|
||||
:theme theme}]]]))
|
||||
|
||||
@@ -4,12 +4,19 @@
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(defonce ^:private request-id-atom (atom 0))
|
||||
|
||||
(defn- get-unique-request-id
|
||||
[]
|
||||
(swap! request-id-atom inc)
|
||||
@request-id-atom)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/fetch-activities-for-current-account
|
||||
(fn [{:keys [db]}]
|
||||
(let [address (-> db :wallet :current-viewing-account-address)
|
||||
chain-ids (chain/chain-ids db)
|
||||
request-id 0
|
||||
request-id (get-unique-request-id)
|
||||
filters {:period {:startTimestamp 0
|
||||
:endTimestamp 0}
|
||||
:types []
|
||||
@@ -20,9 +27,10 @@
|
||||
:filterOutAssets false
|
||||
:filterOutCollectibles false}
|
||||
offset 0
|
||||
limit 35
|
||||
limit 50
|
||||
request-params [request-id [address] chain-ids filters offset limit]]
|
||||
{:fx [[:json-rpc/call
|
||||
{:db (assoc-in db [:wallet :ui :activity-tab :request request-id] address)
|
||||
:fx [[:json-rpc/call
|
||||
[{;; This method is deprecated and will be replaced by
|
||||
;; "wallet_startActivityFilterSession"
|
||||
;; https://github.com/status-im/status-mobile/issues/19864
|
||||
@@ -32,13 +40,31 @@
|
||||
{:event :wallet/fetch-activities-for-current-account
|
||||
:params request-params}]}]]]})))
|
||||
|
||||
(def ^:private activity-transaction-id (comp hash :transaction))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/activity-filtering-for-current-account-done
|
||||
(fn [{:keys [db]} [{:keys [message]}]]
|
||||
(let [address (-> db :wallet :current-viewing-account-address)
|
||||
activities (->> message
|
||||
(transforms/json->clj)
|
||||
(:activities)
|
||||
(cske/transform-keys transforms/->kebab-case-keyword))
|
||||
sorted-activities (sort :timestamp activities)]
|
||||
{:db (assoc-in db [:wallet :activities address] sorted-activities)})))
|
||||
(fn [{:keys [db]} [{:keys [message requestId]}]]
|
||||
(let [address (get-in db [:wallet :ui :activity-tab :request requestId])
|
||||
activities (->> message
|
||||
(transforms/json->clj)
|
||||
(:activities)
|
||||
(cske/transform-keys transforms/->kebab-case-keyword))
|
||||
activities-indexed (zipmap (map activity-transaction-id activities)
|
||||
activities)]
|
||||
{:db (assoc-in db [:wallet :activities address] activities-indexed)})))
|
||||
|
||||
(def ^:private nested-merge (partial merge-with merge))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/activities-filtering-entries-updated
|
||||
(fn [{:keys [db]} [{:keys [message requestId]}]]
|
||||
(let [address (get-in db [:wallet :ui :activity-tab :request requestId])
|
||||
activities (->> message
|
||||
(transforms/json->clj)
|
||||
(cske/transform-keys transforms/->kebab-case-keyword))
|
||||
activities-indexed (zipmap (map activity-transaction-id activities)
|
||||
activities)]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :ui :activity-tab :request] dissoc requestId)
|
||||
(update-in [:wallet :activities address] nested-merge activities-indexed))})))
|
||||
|
||||
@@ -11,31 +11,81 @@
|
||||
|
||||
(defn send-and-receive-activity
|
||||
[{:keys [transaction relative-date status sender recipient token amount network-name
|
||||
network-logo]}]
|
||||
[quo/wallet-activity
|
||||
{:transaction transaction
|
||||
:timestamp relative-date
|
||||
:status status
|
||||
:counter 1
|
||||
:first-tag {:size 24
|
||||
:type :token
|
||||
:token token
|
||||
:amount amount}
|
||||
:second-tag-prefix :t/from
|
||||
:second-tag {:type :address :address sender}
|
||||
:third-tag-prefix :t/to
|
||||
:third-tag {:type :address :address recipient}
|
||||
:fourth-tag-prefix :t/via
|
||||
:fourth-tag {:size 24
|
||||
:type :network
|
||||
:network-name network-name
|
||||
:network-logo network-logo}
|
||||
:blur? false}])
|
||||
network-logo token-id nft-url nft-name]}]
|
||||
(if token-id
|
||||
[quo/wallet-activity
|
||||
{:transaction transaction
|
||||
:timestamp relative-date
|
||||
:status status
|
||||
:counter 1
|
||||
:first-tag {:size 24
|
||||
:type :collectible
|
||||
:collectible nft-url
|
||||
:collectible-name (if (> amount 1)
|
||||
(str amount " " nft-name)
|
||||
nft-name)
|
||||
:collectible-number token-id}
|
||||
:second-tag-prefix :t/from
|
||||
:second-tag {:type :address :address sender}
|
||||
:third-tag-prefix :t/to
|
||||
:third-tag {:type :address :address recipient}
|
||||
:fourth-tag-prefix :t/via
|
||||
:fourth-tag {:size 24
|
||||
:type :network
|
||||
:network-name network-name
|
||||
:network-logo network-logo}
|
||||
:blur? false}]
|
||||
[quo/wallet-activity
|
||||
{:transaction transaction
|
||||
:timestamp relative-date
|
||||
:status status
|
||||
:counter 1
|
||||
:first-tag {:size 24
|
||||
:type :token
|
||||
:token token
|
||||
:amount amount}
|
||||
:second-tag-prefix :t/from
|
||||
:second-tag {:type :address :address sender}
|
||||
:third-tag-prefix :t/to
|
||||
:third-tag {:type :address :address recipient}
|
||||
:fourth-tag-prefix :t/via
|
||||
:fourth-tag {:size 24
|
||||
:type :network
|
||||
:network-name network-name
|
||||
:network-logo network-logo}
|
||||
:blur? false}]))
|
||||
|
||||
;; WIP to add the mint activity.
|
||||
;(defn mint-activity
|
||||
; [{:keys [transaction relative-date status recipient network-name
|
||||
; network-logo nft-name nft-url token-id]}]
|
||||
; [quo/wallet-activity
|
||||
; {:transaction transaction
|
||||
; :timestamp relative-date
|
||||
; :status status
|
||||
; :counter 1
|
||||
; :first-tag {:size 24
|
||||
; :type :collectible
|
||||
; :collectible nft-url
|
||||
; :collectible-name nft-name
|
||||
; :collectible-number token-id}
|
||||
; :second-tag-prefix :t/at
|
||||
; :second-tag {:type :address :address recipient}
|
||||
; :third-tag-prefix :t/to
|
||||
; :third-tag {:type :address :address recipient}
|
||||
; :fourth-tag-prefix :t/via
|
||||
; :fourth-tag {:size 24
|
||||
; :type :network
|
||||
; :network-name network-name
|
||||
; :network-logo network-logo}
|
||||
; :blur? false}])
|
||||
|
||||
(defn activity-item
|
||||
[{:keys [transaction] :as activity}]
|
||||
(case transaction
|
||||
(:send :receive) [send-and-receive-activity activity]
|
||||
;; WIP to add the mint activity.
|
||||
;; :mint [mint-activity activity]
|
||||
nil))
|
||||
|
||||
(defn view
|
||||
|
||||
@@ -172,17 +172,20 @@
|
||||
|
||||
(defn get-network-details
|
||||
[chain-id]
|
||||
(condp contains? chain-id
|
||||
#{constants/ethereum-mainnet-chain-id constants/ethereum-goerli-chain-id
|
||||
constants/ethereum-sepolia-chain-id}
|
||||
mainnet-network-details
|
||||
(as-> chain-id $
|
||||
(condp contains? $
|
||||
#{constants/ethereum-mainnet-chain-id constants/ethereum-goerli-chain-id
|
||||
constants/ethereum-sepolia-chain-id}
|
||||
mainnet-network-details
|
||||
|
||||
#{constants/arbitrum-mainnet-chain-id constants/arbitrum-goerli-chain-id
|
||||
constants/arbitrum-sepolia-chain-id}
|
||||
arbitrum-network-details
|
||||
#{constants/arbitrum-mainnet-chain-id constants/arbitrum-goerli-chain-id
|
||||
constants/arbitrum-sepolia-chain-id}
|
||||
arbitrum-network-details
|
||||
|
||||
#{constants/optimism-mainnet-chain-id constants/optimism-goerli-chain-id
|
||||
constants/optimism-sepolia-chain-id}
|
||||
optimism-network-details
|
||||
#{constants/optimism-mainnet-chain-id constants/optimism-goerli-chain-id
|
||||
constants/optimism-sepolia-chain-id}
|
||||
optimism-network-details
|
||||
|
||||
nil))
|
||||
nil)
|
||||
(when $
|
||||
(assoc $ :chain-id chain-id))))
|
||||
|
||||
@@ -13,26 +13,26 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- on-disconnect
|
||||
[wallet-account {:keys [name topic]}]
|
||||
[wallet-account {:keys [name topic pairing-topic]}]
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch
|
||||
[:wallet-connect/disconnect-dapp
|
||||
{:topic topic
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:wallet-connect/remove-pairing-by-topic topic])
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :dapp-disconnect-success
|
||||
:type :positive
|
||||
:text (i18n/label :t/disconnect-dapp-success
|
||||
{:dapp name
|
||||
:account (:name wallet-account)})}]))
|
||||
:on-fail (fn []
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :dapp-disconnect-failure
|
||||
:type :negative
|
||||
:text (i18n/label :t/disconnect-dapp-fail
|
||||
{:dapp name
|
||||
:account (:name wallet-account)})}]))}]))
|
||||
{:topic topic
|
||||
:pairing-topic pairing-topic
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :dapp-disconnect-success
|
||||
:type :positive
|
||||
:text (i18n/label :t/disconnect-dapp-success
|
||||
{:dapp name
|
||||
:account (:name wallet-account)})}]))
|
||||
:on-fail (fn []
|
||||
(rf/dispatch [:toasts/upsert
|
||||
{:id :dapp-disconnect-failure
|
||||
:type :negative
|
||||
:text (i18n/label :t/disconnect-dapp-fail
|
||||
{:dapp name
|
||||
:account (:name wallet-account)})}]))}]))
|
||||
|
||||
(defn- on-dapp-disconnect-press
|
||||
[wallet-account dapp]
|
||||
@@ -83,7 +83,8 @@
|
||||
[]
|
||||
(let [{:keys [bottom]} (safe-area/get-insets)
|
||||
{:keys [color] :as wallet-account} (rf/sub [:wallet/current-viewing-account])
|
||||
pairings (rf/sub [:wallet-connect/pairings])
|
||||
sessions (rf/sub
|
||||
[:wallet-connect/sessions-for-current-account])
|
||||
theme (quo.theme/use-theme)]
|
||||
[rn/view {:flex 1}
|
||||
[header
|
||||
@@ -91,7 +92,7 @@
|
||||
:wallet-account wallet-account
|
||||
:on-close #(rf/dispatch [:navigate-back])
|
||||
:on-add #(rf/dispatch [:navigate-to :screen/wallet.scan-dapp])}]
|
||||
(if (empty? pairings)
|
||||
(if (empty? sessions)
|
||||
[quo/empty-state
|
||||
{:title (i18n/label :t/no-dapps)
|
||||
:description (i18n/label :t/no-dapps-description)
|
||||
@@ -99,16 +100,16 @@
|
||||
:container-style style/empty-container-style}]
|
||||
[rn/view (style/dapps-container bottom)
|
||||
[rn/flat-list
|
||||
{:data pairings
|
||||
{:data sessions
|
||||
:always-bounce-vertical false
|
||||
:content-container-style (style/dapps-list theme)
|
||||
:render-fn (fn [{:keys [topic]
|
||||
{:keys [icons name url]} :peerMetadata}]
|
||||
:render-fn (fn [{:keys [topic pairingTopic name url iconUrl]}]
|
||||
[quo/dapp
|
||||
{:dapp {:avatar (get icons 0)
|
||||
:name name
|
||||
:value url
|
||||
:topic topic}
|
||||
{:dapp {:avatar iconUrl
|
||||
:name name
|
||||
:value url
|
||||
:topic topic
|
||||
:pairing-topic pairingTopic}
|
||||
:accessibility-label (str "dapp-" topic)
|
||||
:state :default
|
||||
:action :icon
|
||||
|
||||
@@ -187,15 +187,8 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/update-receiver-networks
|
||||
(fn [{:keys [db]} [selected-networks]]
|
||||
(let [amount (get-in db [:wallet :ui :send :amount])
|
||||
disabled-from-chain-ids (get-in db [:wallet :ui :send :disabled-from-chain-ids])
|
||||
filtered-disabled-from-chain-ids (filter (fn [chain-id]
|
||||
(some #(= chain-id %)
|
||||
selected-networks))
|
||||
disabled-from-chain-ids)]
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :send :receiver-networks] selected-networks)
|
||||
(assoc-in [:wallet :ui :send :disabled-from-chain-ids] filtered-disabled-from-chain-ids))
|
||||
(let [amount (get-in db [:wallet :ui :send :amount])]
|
||||
{:db (assoc-in db [:wallet :ui :send :receiver-networks] selected-networks)
|
||||
:fx [[:dispatch [:wallet/get-suggested-routes {:amount amount}]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
|
||||
@@ -2,8 +2,19 @@
|
||||
(:require
|
||||
[cljs.test :refer-macros [is testing]]
|
||||
[re-frame.db :as rf-db]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
status-im.contexts.wallet.send.events
|
||||
[test-helpers.unit :as h]))
|
||||
[status-im.contexts.wallet.send.utils :as send-utils]
|
||||
[test-helpers.unit :as h]
|
||||
[utils.money :as money]))
|
||||
|
||||
(defn collectible-with-balance
|
||||
[balance]
|
||||
{:name "DOG #1"
|
||||
:description
|
||||
"dogs are cute and this one is the cutestdogs are cute and this one is the cutest"
|
||||
:ownership [{:address "0x01"
|
||||
:balance balance}]})
|
||||
|
||||
(h/deftest-event :wallet/update-receiver-networks
|
||||
[event-id dispatch]
|
||||
@@ -12,19 +23,6 @@
|
||||
selected-networks-after [:ethereum :optimism]
|
||||
expected-db {:wallet {:ui {:send {:receiver-networks selected-networks-after}}}}]
|
||||
(reset! rf-db/app-db {:wallet {:ui {:send {:receiver-networks selected-networks-before}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id selected-networks-after]))))))
|
||||
|
||||
(testing "if receiver network removed, it is also removed from disabled ones"
|
||||
(let [selected-networks-before [:ethereum :optimism :arbitrum]
|
||||
selected-networks-after [:ethereum :optimism]
|
||||
disabled-from-chain-ids-before [:optimism :arbitrum]
|
||||
disabled-from-chain-ids-after [:optimism]
|
||||
expected-db {:wallet {:ui {:send {:receiver-networks selected-networks-after
|
||||
:disabled-from-chain-ids
|
||||
disabled-from-chain-ids-after}}}}]
|
||||
(reset! rf-db/app-db {:wallet {:ui {:send {:receiver-networks selected-networks-before
|
||||
:disabled-from-chain-ids
|
||||
disabled-from-chain-ids-before}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id selected-networks-after])))))))
|
||||
|
||||
(h/deftest-event :wallet/set-token-to-send
|
||||
@@ -163,3 +161,298 @@
|
||||
result (dispatch [event-id {:amount amount}])]
|
||||
(testing "amount set"
|
||||
(is (match? amount (get-in result [:db :wallet :ui :send :amount]))))))
|
||||
|
||||
(h/deftest-event :wallet/clean-send-data
|
||||
[event-id dispatch]
|
||||
(let [token-symbol "ETH"
|
||||
token {:symbol "ETH"
|
||||
:name "Ether"
|
||||
:networks #{{:chain-id 421614}
|
||||
{:chain-id 11155420}
|
||||
{:chain-id 11155111}}}
|
||||
receiver-networks [421614 11155420]]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:token-display-name token-symbol
|
||||
:token token
|
||||
:receiver-networks receiver-networks}
|
||||
:other-props :value}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui]) :send)))))
|
||||
|
||||
(h/deftest-event :wallet/select-address-tab
|
||||
[event-id dispatch]
|
||||
(let [expected-db {:wallet {:ui {:send {:select-address-tab "tab"}}}}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send nil}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id "tab"]))))))
|
||||
|
||||
(h/deftest-event :wallet/clean-send-address
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:to-address "0x01"
|
||||
:recipient {:recipient-type :saved-address
|
||||
:label "label"}
|
||||
:other-props :value}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :to-address)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :recipient)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/clean-send-amount
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:amount 10
|
||||
:other-props :value}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :amount)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/clean-disabled-from-networks
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:disabled-from-chain-ids [:optimism]
|
||||
:other-props :value}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :disabled-from-chain-ids)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/clean-from-locked-amounts
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:from-locked-amounts "value"
|
||||
:other-props :value}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :from-locked-amounts)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/disable-from-networks
|
||||
[event-id dispatch]
|
||||
(let [expected-db {:wallet {:ui {:send {:disabled-from-chain-ids [:optimism]
|
||||
:other-props :value}}}}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id [:optimism]]))))))
|
||||
|
||||
(h/deftest-event :wallet/unlock-from-amount
|
||||
[event-id dispatch]
|
||||
(let [expected-db {:wallet {:ui {:send {:other-props :value
|
||||
:from-locked-amounts {}}}}}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:from-locked-amounts {:chain-id [1 10]}}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id :chain-id]))))))
|
||||
|
||||
(h/deftest-event :wallet/lock-from-amount
|
||||
[event-id dispatch]
|
||||
(let [expected-db {:wallet {:ui {:send {:other-props :value
|
||||
:from-locked-amounts {:amount 10}}}}}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id :amount 10]))))))
|
||||
|
||||
(h/deftest-event :wallet/clean-selected-token
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:token "ETH"
|
||||
:token-display-name "ETH"
|
||||
:tx-type :tx/collectible-erc-721}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :token)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :token-display-name)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :tx-type)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/clean-selected-collectible
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:collectible "ETH"
|
||||
:token-display-name "ETH"
|
||||
:amount 10}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :collectible)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :token-display-name)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :amount)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/clean-suggested-routes
|
||||
[event-id dispatch]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send
|
||||
{:other-props :value
|
||||
:suggested-routes ["1" "2"]
|
||||
:route "1"
|
||||
:amount 10
|
||||
:from-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
|
||||
:to-values-by-chain [{:chain-id 1} {:chain-id 10} {:chain-id 42161}]
|
||||
:sender-network-values [:eth :arb1]
|
||||
:receiver-network-values [:eth :arb1]
|
||||
:network-links [{:from-chain-id 1
|
||||
:to-chain-id 10
|
||||
:position-diff 1}]
|
||||
:loading-suggested-routes? false
|
||||
:suggested-routes-call-timestamp ["1" "2"]}}}})
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :suggested-routes)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :route)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :amount)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :from-values-by-chain)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :to-values-by-chain)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :sender-network-values)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :receiver-network-values)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :network-links)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send])
|
||||
:loading-suggested-routes?)))
|
||||
(is (not (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send])
|
||||
:suggested-routes-call-timestamp)))
|
||||
(is (contains? (get-in (dispatch [event-id]) [:db :wallet :ui :send]) :other-props)))
|
||||
|
||||
(h/deftest-event :wallet/suggested-routes-error
|
||||
[event-id dispatch]
|
||||
(let [sender-network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}
|
||||
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}]
|
||||
receiver-network-amounts [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}]
|
||||
expected-result {:db {:wallet {:ui {:send
|
||||
{:sender-network-values
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
sender-network-amounts)
|
||||
:receiver-network-values
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
receiver-network-amounts)
|
||||
:loading-suggested-routes? false
|
||||
:suggested-routes {:best []}}}}}
|
||||
:fx [[:dispatch
|
||||
[:toasts/upsert
|
||||
{:id :send-transaction-error
|
||||
:type :negative
|
||||
:text "error"}]]]}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:sender-network-values sender-network-amounts
|
||||
:receiver-network-values receiver-network-amounts
|
||||
:route :values
|
||||
:loading-suggested-routes? true}}}})
|
||||
(is (match? expected-result (dispatch [event-id {:message "error"}])))))
|
||||
|
||||
(h/deftest-event :wallet/reset-network-amounts-to-zero
|
||||
[event-id dispatch]
|
||||
(let [sender-network-values [{:chain-id 1 :total-amount (money/bignumber "100") :type :default}
|
||||
{:chain-id 10 :total-amount (money/bignumber "200") :type :default}]
|
||||
receiver-network-values [{:chain-id 1 :total-amount (money/bignumber "100") :type :loading}]
|
||||
disabled-from-chain-ids [:ethereum]
|
||||
sender-network-zero (send-utils/reset-network-amounts-to-zero
|
||||
{:network-amounts sender-network-values
|
||||
:disabled-chain-ids disabled-from-chain-ids})
|
||||
receiver-network-zero (send-utils/reset-network-amounts-to-zero
|
||||
{:network-amounts receiver-network-values
|
||||
:disabled-chain-ids []})]
|
||||
(testing "if sender-network-value and receiver-network-value are not empty"
|
||||
(let [expected-db {:wallet {:ui {:send {:other-props :value
|
||||
:sender-network-values sender-network-zero
|
||||
:receiver-network-values receiver-network-zero}}}}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:sender-network-values sender-network-values
|
||||
:receiver-network-values receiver-network-values
|
||||
:network-links [{:from-chain-id 1
|
||||
:to-chain-id 10
|
||||
:position-diff 1}]}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id]))))))
|
||||
(testing "if only receiver-network-value is empty"
|
||||
(let [expected-db {:wallet {:ui {:send {:other-props :value
|
||||
:sender-network-values sender-network-zero}}}}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:sender-network-values sender-network-values
|
||||
:receiver-network-values []
|
||||
:network-links [{:from-chain-id 1
|
||||
:to-chain-id 10
|
||||
:position-diff 1}]}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id]))))))
|
||||
(testing "if receiver-network-value and sender-network-values are empty"
|
||||
(let [expected-db {:wallet {:ui {:send {:other-props :value}}}}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:sender-network-values []
|
||||
:receiver-network-values []
|
||||
:network-links [{:from-chain-id 1
|
||||
:to-chain-id 10
|
||||
:position-diff 1}]}}}})
|
||||
(is (match? expected-db (:db (dispatch [event-id]))))))))
|
||||
|
||||
(h/deftest-event :wallet/select-send-address
|
||||
[event-id dispatch]
|
||||
(let [address "eth:arb1:0x01"
|
||||
prefix "eth:arb1:"
|
||||
to-address "0x01"
|
||||
recipient {:type :saved-address
|
||||
:label "0x01...23f"}
|
||||
stack-id :screen/wallet.select-address
|
||||
start-flow? false
|
||||
tx-type :tx/collectible-erc-721]
|
||||
(testing "testing when collectible balance is more than 1"
|
||||
(let [collectible (collectible-with-balance 2)
|
||||
testnet-enabled? false
|
||||
goerli-enabled? false
|
||||
receiver-networks (network-utils/resolve-receiver-networks
|
||||
{:prefix prefix
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
expected-result {:db {:wallet {:ui {:send {:other-props :value
|
||||
:recipient recipient
|
||||
:to-address to-address
|
||||
:address-prefix prefix
|
||||
:receiver-preferred-networks
|
||||
receiver-networks
|
||||
:receiver-networks receiver-networks
|
||||
:tx-type tx-type
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? false
|
||||
:is-goerli-enabled? false}}
|
||||
:fx [nil
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-send-flow}]]]}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:tx-type tx-type
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? testnet-enabled?
|
||||
:is-goerli-enabled? goerli-enabled?}})
|
||||
(is (match? expected-result
|
||||
(dispatch [event-id
|
||||
{:address address
|
||||
:recipient recipient
|
||||
:stack-id stack-id
|
||||
:start-flow? start-flow?}])))))
|
||||
(testing "testing when collectible balance is 1"
|
||||
(let [collectible (collectible-with-balance 1)
|
||||
testnet-enabled? false
|
||||
goerli-enabled? false
|
||||
receiver-networks (network-utils/resolve-receiver-networks
|
||||
{:prefix prefix
|
||||
:testnet-enabled? testnet-enabled?
|
||||
:goerli-enabled? goerli-enabled?})
|
||||
expected-result {:db {:wallet {:ui {:send {:other-props :value
|
||||
:recipient recipient
|
||||
:to-address to-address
|
||||
:address-prefix prefix
|
||||
:receiver-preferred-networks
|
||||
receiver-networks
|
||||
:receiver-networks receiver-networks
|
||||
:tx-type tx-type
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? false
|
||||
:is-goerli-enabled? false}}
|
||||
:fx [[:dispatch [:wallet/get-suggested-routes {:amount 1}]]
|
||||
[:dispatch
|
||||
[:wallet/wizard-navigate-forward
|
||||
{:current-screen stack-id
|
||||
:start-flow? start-flow?
|
||||
:flow-id :wallet-send-flow}]]]}]
|
||||
(reset! rf-db/app-db
|
||||
{:wallet {:ui {:send {:other-props :value
|
||||
:tx-type tx-type
|
||||
:collectible collectible}}}
|
||||
:profile/profile {:test-networks-enabled? testnet-enabled?
|
||||
:is-goerli-enabled? goerli-enabled?}})
|
||||
(is (match? expected-result
|
||||
(dispatch [event-id
|
||||
{:address address
|
||||
:recipient recipient
|
||||
:stack-id stack-id
|
||||
:start-flow? start-flow?}])))))))
|
||||
|
||||
@@ -120,7 +120,7 @@
|
||||
[]
|
||||
[quo/alert-banner
|
||||
{:action? true
|
||||
:text (i18n/label :t/not-enough-assets)
|
||||
:text (i18n/label :t/not-enough-assets-to-pay-gas-fees)
|
||||
:button-text (i18n/label :t/buy-eth)
|
||||
:on-button-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content buy-token/view}])}])
|
||||
@@ -154,11 +154,9 @@
|
||||
[input-state set-input-state] (rn/use-state controlled-input/init-state)
|
||||
[just-toggled-mode? set-just-toggled-mode?] (rn/use-state false)
|
||||
clear-input! #(set-input-state controlled-input/delete-all)
|
||||
handle-on-confirm (fn []
|
||||
handle-on-confirm (fn [amount]
|
||||
(rf/dispatch [:wallet/set-token-amount-to-send
|
||||
{:amount
|
||||
(controlled-input/input-value
|
||||
input-state)
|
||||
{:amount amount
|
||||
:stack-id current-screen-id}]))
|
||||
{fiat-currency :currency} (rf/sub [:profile/profile])
|
||||
{token-symbol :symbol
|
||||
|
||||
@@ -157,7 +157,6 @@
|
||||
[quo/data-item
|
||||
{:container-style style/detail-item
|
||||
:blur? false
|
||||
:description :default
|
||||
:card? false
|
||||
:status :default
|
||||
:size :small
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
(ns status-im.contexts.wallet.send.utils
|
||||
(:require
|
||||
[legacy.status-im.utils.hex :as utils.hex]
|
||||
[native-module.core :as native-module]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[utils.hex :as utils.hex]
|
||||
[utils.money :as money]))
|
||||
|
||||
(defn amount-in-hex
|
||||
|
||||
@@ -23,22 +23,39 @@
|
||||
:block-number blockNumber
|
||||
:accounts accounts})
|
||||
(case event-type
|
||||
"pending-transaction-status-changed" {:fx
|
||||
[[:dispatch
|
||||
[:wallet/pending-transaction-status-changed-received
|
||||
(transforms/js->clj event-js)]]]}
|
||||
"wallet-owned-collectibles-filtering-done" {:fx [[:dispatch
|
||||
[:wallet/owned-collectibles-filtering-done
|
||||
(transforms/js->clj event-js)]]]}
|
||||
"wallet-get-collectibles-details-done" {:fx [[:dispatch
|
||||
[:wallet/get-collectible-details-done
|
||||
(transforms/js->clj event-js)]]]}
|
||||
"wallet-tick-reload" {:fx [[:dispatch [:wallet/reload]]]}
|
||||
"wallet-blockchain-status-changed" {:fx [[:dispatch
|
||||
[:wallet/blockchain-status-changed
|
||||
(transforms/js->clj event-js)]]]}
|
||||
"wallet-activity-filtering-done" {:fx
|
||||
[[:dispatch
|
||||
[:wallet/activity-filtering-for-current-account-done
|
||||
(transforms/js->clj event-js)]]]}
|
||||
"pending-transaction-status-changed"
|
||||
{:fx
|
||||
[[:dispatch
|
||||
[:wallet/pending-transaction-status-changed-received
|
||||
(transforms/js->clj event-js)]]]}
|
||||
|
||||
"wallet-owned-collectibles-filtering-done"
|
||||
{:fx [[:dispatch
|
||||
[:wallet/owned-collectibles-filtering-done
|
||||
(transforms/js->clj event-js)]]]}
|
||||
|
||||
"wallet-get-collectibles-details-done"
|
||||
{:fx [[:dispatch
|
||||
[:wallet/get-collectible-details-done
|
||||
(transforms/js->clj event-js)]]]}
|
||||
|
||||
"wallet-tick-reload"
|
||||
{:fx [[:dispatch [:wallet/reload]]]}
|
||||
|
||||
"wallet-blockchain-status-changed"
|
||||
{:fx [[:dispatch
|
||||
[:wallet/blockchain-status-changed
|
||||
(transforms/js->clj event-js)]]]}
|
||||
|
||||
"wallet-activity-filtering-done"
|
||||
{:fx
|
||||
[[:dispatch
|
||||
[:wallet/activity-filtering-for-current-account-done
|
||||
(transforms/js->clj event-js)]]]}
|
||||
|
||||
"wallet-activity-filtering-entries-updated"
|
||||
{:fx [[:dispatch
|
||||
[:wallet/activities-filtering-entries-updated
|
||||
(transforms/js->clj event-js)]]]}
|
||||
|
||||
(log/debug ::unknown-wallet-event :type event-type)))))
|
||||
|
||||
@@ -85,12 +85,45 @@
|
||||
|
||||
(defn required-networks-supported?
|
||||
[proposal supported-networks]
|
||||
(let [required-networks (get-in proposal [:params :requiredNamespaces :eip155 :chains])
|
||||
supported-eip155 (set (map chain-id->eip155 supported-networks))]
|
||||
(every? #(contains? supported-eip155 %) required-networks)))
|
||||
(let [supported-namespaces #{:eip155}
|
||||
required-namespaces (get-in proposal [:params :requiredNamespaces])]
|
||||
(when (every? #(contains? supported-namespaces %)
|
||||
(keys required-namespaces))
|
||||
(let [required-networks (get-in required-namespaces [:eip155 :chains])
|
||||
supported-eip155 (set (map chain-id->eip155 supported-networks))]
|
||||
(every? #(contains? supported-eip155 %)
|
||||
required-networks)))))
|
||||
|
||||
(defn get-networks-by-mode
|
||||
[db]
|
||||
(let [test-mode? (get-in db [:profile/profile :test-networks-enabled?])
|
||||
networks (get-in db [:wallet :networks (if test-mode? :test :prod)])]
|
||||
(mapv #(-> % :chain-id) networks)))
|
||||
|
||||
(defn add-full-testnet-name
|
||||
"Updates the `:full-name` key with the full testnet name if using testnet `:chain-id`.\n
|
||||
e.g. `{:full-name \"Mainnet\"}` -> `{:full-name \"Mainnet Sepolia\"`}`"
|
||||
[network]
|
||||
(let [add-testnet-name (fn [testnet-name]
|
||||
(update network :full-name #(str % " " testnet-name)))]
|
||||
(condp #(contains? %1 %2) (:chain-id network)
|
||||
constants/sepolia-chain-ids (add-testnet-name constants/sepolia-full-name)
|
||||
constants/goerli-chain-ids (add-testnet-name constants/goerli-full-name)
|
||||
network)))
|
||||
|
||||
(defn event-should-be-handled?
|
||||
[db {:keys [topic]}]
|
||||
(some #(= topic %)
|
||||
(map :topic (:wallet-connect/sessions db))))
|
||||
|
||||
(defn sdk-session->db-session
|
||||
[{:keys [topic expiry pairingTopic] :as session}]
|
||||
{:topic topic
|
||||
:expiry expiry
|
||||
:sessionJson (transforms/clj->json session)
|
||||
:pairingTopic pairingTopic
|
||||
:name (get-in session [:peer :metadata :name])
|
||||
:iconUrl (get-in session [:peer :metadata :icons 0])
|
||||
:url (get-in session [:peer :metadata :url])
|
||||
:accounts (get-in session [:namespaces :eip155 :accounts])
|
||||
:disconnected false})
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
(ns status-im.contexts.wallet.wallet-connect.effects
|
||||
(:require
|
||||
[cljs-bean.core :as bean]
|
||||
[native-module.core :as native-module]
|
||||
[promesa.core :as promesa]
|
||||
[re-frame.core :as rf]
|
||||
[react-native.wallet-connect :as wallet-connect]
|
||||
[status-im.config :as config]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.wallet-connect.core :as wallet-connect-core]
|
||||
[status-im.contexts.wallet.wallet-connect.signing :as signing]
|
||||
[status-im.contexts.wallet.wallet-connect.transactions :as transactions]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.security.core :as security]
|
||||
[utils.transforms :as transforms]))
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/init
|
||||
@@ -34,13 +31,6 @@
|
||||
:event wc-event
|
||||
:handler handler})))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/fetch-pairings
|
||||
(fn [{:keys [web3-wallet on-success on-fail]}]
|
||||
(-> (wallet-connect/get-pairings web3-wallet)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-fail))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/pair
|
||||
(fn [{:keys [web3-wallet url on-success on-fail]}]
|
||||
@@ -56,13 +46,6 @@
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-fail))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/fetch-active-sessions
|
||||
(fn [{:keys [web3-wallet on-success on-fail]}]
|
||||
(-> (wallet-connect/get-active-sessions web3-wallet)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-fail))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/approve-session
|
||||
(fn [{:keys [web3-wallet proposal supported-namespaces on-success on-fail]}]
|
||||
@@ -77,38 +60,68 @@
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-fail)))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/fetch-active-sessions
|
||||
(fn [{:keys [web3-wallet on-success on-fail]}]
|
||||
(-> (wallet-connect/get-active-sessions web3-wallet)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-fail))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/sign-message
|
||||
(fn [{:keys [password address data on-success on-error]}]
|
||||
(-> {:data data
|
||||
:account address
|
||||
:password (security/safe-unmask-data password)}
|
||||
bean/->js
|
||||
transforms/clj->json
|
||||
native-module/sign-message
|
||||
(promesa/then wallet-connect-core/extract-native-call-signature)
|
||||
(fn [{:keys [password address data rpc-method on-success on-error]}]
|
||||
(let [password (security/safe-unmask-data password)]
|
||||
(-> (condp =
|
||||
rpc-method
|
||||
:personal-sign
|
||||
(signing/personal-sign password address data)
|
||||
|
||||
:eth-sign
|
||||
(signing/eth-sign password address data)
|
||||
|
||||
(signing/personal-sign password address data))
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error)))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/prepare-transaction
|
||||
(fn [{:keys [tx chain-id on-success on-error]}]
|
||||
(-> (transactions/prepare-transaction tx
|
||||
chain-id
|
||||
transactions/default-tx-priority)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/sign-transaction
|
||||
(fn [{:keys [password address chain-id tx on-success on-error]}]
|
||||
(-> (transactions/sign-transaction (security/safe-unmask-data password) address tx chain-id)
|
||||
(fn [{:keys [password address chain-id tx-hash tx-args on-success on-error]}]
|
||||
(-> (transactions/sign-transaction (security/safe-unmask-data password)
|
||||
address
|
||||
tx-hash
|
||||
tx-args
|
||||
chain-id)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/send-transaction
|
||||
(fn [{:keys [password address chain-id tx on-success on-error]}]
|
||||
(-> (transactions/send-transaction (security/safe-unmask-data password) address tx chain-id)
|
||||
(fn [{:keys [password address chain-id tx-hash tx-args on-success on-error]}]
|
||||
(-> (transactions/send-transaction (security/safe-unmask-data password)
|
||||
address
|
||||
tx-hash
|
||||
tx-args
|
||||
chain-id)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
(rf/reg-fx
|
||||
:effects.wallet-connect/sign-typed-data
|
||||
(fn [{:keys [password address data version on-success on-error]}]
|
||||
(-> (wallet-connect-core/sign-typed-data version data address (security/safe-unmask-data password))
|
||||
(promesa/then wallet-connect-core/extract-native-call-signature)
|
||||
(fn [{:keys [password address data version chain-id on-success on-error]}]
|
||||
(-> (signing/eth-sign-typed-data (security/safe-unmask-data password)
|
||||
address
|
||||
data
|
||||
chain-id
|
||||
version)
|
||||
(promesa/then on-success)
|
||||
(promesa/catch on-error))))
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
status-im.contexts.wallet.wallet-connect.responding-events
|
||||
[status-im.contexts.wallet.wallet-connect.utils :as wc-utils]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]))
|
||||
[utils.i18n :as i18n]
|
||||
[utils.transforms :as types]))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/init
|
||||
@@ -22,12 +23,7 @@
|
||||
(fn [{:keys [db]} [web3-wallet]]
|
||||
{:db (assoc db :wallet-connect/web3-wallet web3-wallet)
|
||||
:fx [[:dispatch [:wallet-connect/register-event-listeners]]
|
||||
[:effects.wallet-connect/fetch-pairings
|
||||
{:web3-wallet web3-wallet
|
||||
:on-fail #(log/error "Failed to get dApp pairings" {:error %})
|
||||
:on-success (fn [data]
|
||||
(rf/dispatch [:wallet-connect/set-pairings
|
||||
(js->clj data :keywordize-keys true)]))}]]}))
|
||||
[:dispatch [:wallet-connect/fetch-persisted-sessions]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/register-event-listeners
|
||||
@@ -40,7 +36,11 @@
|
||||
[:effects.wallet-connect/register-event-listener
|
||||
[web3-wallet
|
||||
constants/wallet-connect-session-request-event
|
||||
#(rf/dispatch [:wallet-connect/on-session-request %])]]]})))
|
||||
#(rf/dispatch [:wallet-connect/on-session-request %])]]
|
||||
[:effects.wallet-connect/register-event-listener
|
||||
[web3-wallet
|
||||
constants/wallet-connect-session-delete-event
|
||||
#(rf/dispatch [:wallet-connect/on-session-delete %])]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-init-fail
|
||||
@@ -54,20 +54,24 @@
|
||||
(fn [{:keys [db]} [proposal]]
|
||||
(log/info "Received Wallet Connect session proposal: " {:id (:id proposal)})
|
||||
(let [accounts (get-in db [:wallet :accounts])
|
||||
without-watched (remove :watch-only? (vals accounts))
|
||||
current-viewing-address (get-in db [:wallet :current-viewing-account-address])
|
||||
available-accounts (filter #(and (:operable? %)
|
||||
(not (:watch-only? %)))
|
||||
(vals accounts))
|
||||
networks (wallet-connect-core/get-networks-by-mode db)
|
||||
session-networks (wallet-connect-core/proposal-networks-intersection proposal
|
||||
networks)
|
||||
required-networks-supported? (wallet-connect-core/required-networks-supported? proposal
|
||||
networks)]
|
||||
(if required-networks-supported?
|
||||
(if (and (not-empty session-networks) required-networks-supported?)
|
||||
{:db (update db
|
||||
:wallet-connect/current-proposal assoc
|
||||
:request proposal
|
||||
:session-networks session-networks
|
||||
:address (-> without-watched
|
||||
first
|
||||
:address))
|
||||
:address (or current-viewing-address
|
||||
(-> available-accounts
|
||||
first
|
||||
:address)))
|
||||
:fx [[:dispatch
|
||||
[:open-modal :screen/wallet.wallet-connect-session-proposal]]]}
|
||||
{:fx [[:dispatch
|
||||
@@ -85,9 +89,16 @@
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-request
|
||||
(fn [_ [event]]
|
||||
(log/info "Received Wallet Connect session request: " event)
|
||||
{:fx [[:dispatch [:wallet-connect/process-session-request event]]]}))
|
||||
(fn [{:keys [db]} [event]]
|
||||
(when (wallet-connect-core/event-should-be-handled? db event)
|
||||
{:fx [[:dispatch [:wallet-connect/process-session-request event]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/on-session-delete
|
||||
(fn [{:keys [db]} [{:keys [topic] :as event}]]
|
||||
(when (wallet-connect-core/event-should-be-handled? db event)
|
||||
(log/info "Received Wallet Connect session delete: " event)
|
||||
{:fx [[:dispatch [:wallet-connect/disconnect-session topic]]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/reset-current-session-proposal
|
||||
@@ -104,28 +115,18 @@
|
||||
(fn [{:keys [db]}]
|
||||
{:db (dissoc db :wallet-connect/current-request)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/set-pairings
|
||||
(fn [{:keys [db]} [pairings]]
|
||||
{:db (assoc db :wallet-connect/pairings pairings)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/remove-pairing-by-topic
|
||||
(fn [{:keys [db]} [topic]]
|
||||
{:db (update db
|
||||
:wallet-connect/pairings
|
||||
(fn [pairings]
|
||||
(remove #(= (:topic %) topic) pairings)))}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/disconnect-dapp
|
||||
(fn [{:keys [db]} [{:keys [topic on-success on-fail]}]]
|
||||
(fn [{:keys [db]} [{:keys [pairing-topic on-success on-fail]}]]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)]
|
||||
{:fx [[:effects.wallet-connect/disconnect
|
||||
{:web3-wallet web3-wallet
|
||||
:topic topic
|
||||
:topic pairing-topic
|
||||
:on-fail on-fail
|
||||
:on-success on-success}]]})))
|
||||
:on-success (fn []
|
||||
(rf/dispatch [:wallet-connect/disconnect-session pairing-topic])
|
||||
(when on-success
|
||||
(on-success)))}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/pair
|
||||
@@ -137,15 +138,6 @@
|
||||
:on-fail #(log/error "Failed to pair with dApp" {:error %})
|
||||
:on-success #(log/info "dApp paired successfully")}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/fetch-active-sessions
|
||||
(fn [{:keys [db]}]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)]
|
||||
{:fx [[:effects.wallet-connect/fetch-active-sessions
|
||||
{:web3-wallet web3-wallet
|
||||
:on-fail #(log/error "Failed to get active sessions" {:error %})
|
||||
:on-success #(log/info "Got active sessions successfully" {:sessions %})}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/approve-session
|
||||
(fn [{:keys [db]}]
|
||||
@@ -204,10 +196,55 @@
|
||||
{:version version}))}]]]}
|
||||
{:fx [[:dispatch [:wallet-connect/pair scanned-text]]]}))))
|
||||
|
||||
;; We first load sessions from database, then we initiate a call to Wallet Connect SDK and
|
||||
;; then replace the list we have stored in the database with the one that came from the SDK.
|
||||
;; In addition to that, we also update the backend state by marking sessions that are not
|
||||
;; active anymore by calling `:wallet-connect/disconnect-session`.
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/fetch-active-sessions-success
|
||||
(fn [{:keys [db now]} [sessions]]
|
||||
(let [persisted-sessions (:wallet-connect/sessions db)
|
||||
sessions (->> (js->clj sessions :keywordize-keys true)
|
||||
vals
|
||||
(map wallet-connect-core/sdk-session->db-session))
|
||||
expired-sessions (remove
|
||||
(fn [{:keys [expiry]}]
|
||||
(> expiry (/ now 1000)))
|
||||
persisted-sessions)]
|
||||
{:fx (mapv (fn [{:keys [pairingTopic]}]
|
||||
[:wallet-connect/disconnect-session pairingTopic])
|
||||
expired-sessions)
|
||||
:db (assoc db :wallet-connect/sessions sessions)})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/fetch-active-sessions
|
||||
(fn [{:keys [db]}]
|
||||
(let [web3-wallet (get db :wallet-connect/web3-wallet)]
|
||||
{:fx [[:effects.wallet-connect/fetch-active-sessions
|
||||
{:web3-wallet web3-wallet
|
||||
:on-fail #(log/error "Failed to get active sessions" {:error %})
|
||||
:on-success #(rf/dispatch [:wallet-connect/fetch-active-sessions-success %])}]]})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/fetch-persisted-sessions-success
|
||||
(fn [{:keys [db]} [sessions]]
|
||||
{:db (assoc db :wallet-connect/persisted-sessions sessions)}))
|
||||
(let [sessions' (mapv (fn [{:keys [sessionJson] :as session}]
|
||||
(assoc session
|
||||
:accounts
|
||||
(-> sessionJson
|
||||
types/json->clj
|
||||
:namespaces
|
||||
:eip155
|
||||
:accounts)))
|
||||
sessions)]
|
||||
{:fx [[:dispatch [:wallet-connect/fetch-active-sessions]]]
|
||||
:db (assoc db :wallet-connect/sessions sessions')})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/fetch-persisted-sessions-fail
|
||||
(fn [_ [error]]
|
||||
(log/info "Wallet Connect fetch persisted sessions failed" error)
|
||||
{:fx [[:dispatch [:wallet-connect/fetch-active-sessions]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/fetch-persisted-sessions
|
||||
@@ -218,7 +255,7 @@
|
||||
;; 0 means, return everything
|
||||
:params [0]
|
||||
:on-success [:wallet-connect/fetch-persisted-sessions-success]
|
||||
:on-error #(log/info "Wallet Connect fetch persisted sessions failed" %)}]]]}))
|
||||
:on-error [:wallet-connect/fetch-persisted-sessions-fail]}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/persist-session
|
||||
@@ -226,5 +263,22 @@
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wallet_addWalletConnectSession"
|
||||
:params [(js/JSON.stringify session-info)]
|
||||
:on-success #(log/info "Wallet Connect session persisted")
|
||||
:on-success (fn []
|
||||
(log/info "Wallet Connect session persisted")
|
||||
(rf/dispatch [:wallet-connect/fetch-persisted-sessions]))
|
||||
:on-error #(log/info "Wallet Connect session persistence failed" %)}]]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet-connect/disconnect-session
|
||||
(fn [{:keys [db]} [pairing-topic]]
|
||||
{:db (update db
|
||||
:wallet-connect/sessions
|
||||
(fn [sessions]
|
||||
(->> sessions
|
||||
(remove #(= (:pairingTopic %) pairing-topic))
|
||||
(into []))))
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wallet_disconnectWalletConnectSession"
|
||||
:params [pairing-topic]
|
||||
:on-success #(log/info "Wallet Connect session disconnected")
|
||||
:on-error #(log/info "Wallet Connect session persistence failed" %)}]]]}))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user