Compare commits
38
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5691049a41 | ||
|
|
db6a014bbd | ||
|
|
a13975f3f6 | ||
|
|
c473b8c9b1 | ||
|
|
1f333cc937 | ||
|
|
460aaedbca | ||
|
|
66639fc3ed | ||
|
|
2cc689a896 | ||
|
|
b4866ff728 | ||
|
|
eaa5016094 | ||
|
|
66f77e1467 | ||
|
|
d16c1a3c85 | ||
|
|
a049fd341e | ||
|
|
140fa3115c | ||
|
|
147676ae8c | ||
|
|
1e40d49369 | ||
|
|
b17f2892c7 | ||
|
|
b28a8e153e | ||
|
|
35a1905396 | ||
|
|
2e8776d0a6 | ||
|
|
99506c810d | ||
|
|
e83f6ff445 | ||
|
|
f51f52ec27 | ||
|
|
e58e2209bb | ||
|
|
8aa1cadc66 | ||
|
|
91c22df498 | ||
|
|
e221e23255 | ||
|
|
e8e05e58e0 | ||
|
|
ac4ffd83db | ||
|
|
b021b1e20a | ||
|
|
b650591e58 | ||
|
|
0581fc2f9d | ||
|
|
ef9cc55501 | ||
|
|
3b3a39e37b | ||
|
|
b255874e95 | ||
|
|
1c83916fc3 | ||
|
|
31acf51b1e | ||
|
|
424d2d4b5c |
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -71,7 +71,7 @@ pipeline {
|
||||
}
|
||||
stage('Upload') {
|
||||
steps { script {
|
||||
def urls = apks.collect { s3.uploadArtifact(it) }
|
||||
def urls = apks.collect { s5cmd.upload(it) }
|
||||
if (urls.size() > 1) { /* Return only the universal APK. */
|
||||
env.PKG_URL = urls.find { it.contains('universal') }
|
||||
} else { /* If no universal is available pick first. */
|
||||
|
||||
+24
-3
@@ -1,5 +1,7 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
import groovy.json.JsonBuilder
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
@@ -72,7 +74,7 @@ pipeline {
|
||||
iOS: utils.pkgUrl(ios),
|
||||
Diawi: utils.getEnv(ios, 'DIAWI_URL'),
|
||||
/* upload the sha256 checksums file too */
|
||||
SHA: s3.uploadArtifact(sha),
|
||||
SHA: s5cmd.upload(sha),
|
||||
]
|
||||
/* add URLs to the build description */
|
||||
jenkins.setBuildDesc(urls)
|
||||
@@ -83,7 +85,7 @@ pipeline {
|
||||
steps { script {
|
||||
switch (utils.getBuildType()) {
|
||||
case 'nightly': /* Create JSON file with newest build URLs */
|
||||
s3.updateBucketJSON(urls, 'latest.json');
|
||||
updateBucketJSON(urls, 'latest.json');
|
||||
break;
|
||||
case 'release':
|
||||
github.publishReleaseFiles(repo: 'status-mobile');
|
||||
@@ -114,3 +116,22 @@ def Boolean getPublishDefault(Boolean previousValue) {
|
||||
if (previousValue != null) { return previousValue }
|
||||
return false
|
||||
}
|
||||
|
||||
/* Helper for updating JSON with newest builds. */
|
||||
def updateBucketJSON(urls, fileName) {
|
||||
/* latest.json has slightly different key names */
|
||||
def content = [
|
||||
DIAWI: urls.Diawi,
|
||||
APK: urls.Apk, IOS: urls.iOS,
|
||||
APP: urls.App, MAC: urls.Mac,
|
||||
WIN: urls.Win, SHA: urls.SHA
|
||||
]
|
||||
def filePath = "${pwd()}/pkg/${fileName}"
|
||||
/* it might not exist */
|
||||
sh "mkdir -p ${pwd()}/pkg"
|
||||
def contentJson = new JsonBuilder(content).toPrettyString()
|
||||
println "${filePath}:\n${contentJson}"
|
||||
writeFile(file: filePath, text: contentJson)
|
||||
return s5cmd.upload(filePath)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -75,7 +75,7 @@ pipeline {
|
||||
stage('Upload') {
|
||||
steps {
|
||||
script {
|
||||
env.PKG_URL = s3.uploadArtifact(LOG_FILE)
|
||||
env.PKG_URL = s5cmd.upload(LOG_FILE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.9.1'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -32,14 +32,16 @@ status-mobile code that makes it to the `develop` branch, should always point to
|
||||
In practice, this means that sometimes they need to be merged in lockstep.
|
||||
1) Create a PR in status-go and status-mobile. Update the status-go version to the PR revision `scripts/update-status-go.sh $git_revision`.
|
||||
2) Get both PRs reviewed and approved. Once status-mobile PR has been approved, go through manual QA testing if necessary. Don't merge status-mobile PR just yet.
|
||||
3) Now that you know the integration between client & server is working, bump the `VERSION` in status-go and merge it.
|
||||
4) Once merged, tag the version with the new version and push the tag:
|
||||
3) Now that you know the integration between client & server is working, merge the status-go PR first.
|
||||
4) Once merged, tag the merged commit with the new version and push the tag:
|
||||
```
|
||||
git checkout develop
|
||||
git pull develop
|
||||
git tag vx.y.z
|
||||
make tag-version
|
||||
git push origin vx.y.z
|
||||
```
|
||||
:warning: If a specific commit need to tagged in status-go, use `make tag-version TARGET_COMMIT={hash}`. More info about tagging in [status-go](https://github.com/status-im/status-go/blob/develop/RELEASING.md#tagging-versions).
|
||||
|
||||
5) Update status-mobile with the new status-go version, using the new tag `scripts/update-status-go.sh "vx.y.z"`
|
||||
6) If you had to rebase status-go to include new changes, e2e test MUST be re-run. If there's any issue you will
|
||||
have to fix in status-go with another PR and follow the same process.
|
||||
|
||||
@@ -31,7 +31,7 @@ NOW:
|
||||
(defn view
|
||||
[{:keys [on-press on-long-press icon]}]
|
||||
(let [[pressed? set-pressed] (rn/use-state false)
|
||||
theme (theme/use-theme-value)
|
||||
theme (theme/use-theme)
|
||||
on-press-in (rn/use-callback #(set-pressed true))
|
||||
on-press-out (rn/use-callback #(set-pressed nil))]
|
||||
[rn/pressable
|
||||
@@ -47,7 +47,7 @@ NOW:
|
||||
- We no longer need to create an anonymous function for rendering. This removes unnecessary confusion and the need for specific knowledge on how it works and why it was needed.
|
||||
- `rn/use-state` is used instead of `reagent/atom`
|
||||
- State values no longer need to be dereferenced; they are accessible as regular symbols. This eliminates a common bug where the "@" symbol was inadvertently omitted.
|
||||
- `theme/with-theme` wrapper is not needed anymore, `(theme/use-theme-value)` hook can be used directly in the components
|
||||
- `theme/with-theme` wrapper is not needed anymore, `(theme/use-theme)` hook can be used directly in the components
|
||||
- `:f>` not needed anymore, all components are functional by default
|
||||
- `rn/use-callback` hook should be used for anon callback functions
|
||||
|
||||
|
||||
+1
-1
@@ -57,7 +57,7 @@ in {
|
||||
yarn = super.yarn.override { nodejs = super.nodejs-18_x; };
|
||||
openjdk = super.openjdk11_headless;
|
||||
xcodeWrapper = callPackage ./pkgs/xcodeenv/compose-xcodewrapper.nix { } {
|
||||
versions = ["15.1" "15.2" "15.3"];
|
||||
versions = ["15.1" "15.2" "15.3" "15.4"];
|
||||
};
|
||||
go = super.go_1_21;
|
||||
clang = super.clang_15;
|
||||
|
||||
+3
-2
@@ -20,9 +20,10 @@
|
||||
"@react-native-community/netinfo": "^4.4.0",
|
||||
"@react-native-community/push-notification-ios": "^1.4.1",
|
||||
"@react-native-community/slider": "^3.0.0",
|
||||
"@walletconnect/react-native-compat": "^2.12.2",
|
||||
"@walletconnect/web3wallet": "^1.11.2",
|
||||
"@walletconnect/react-native-compat": "2.11.2",
|
||||
"@walletconnect/web3wallet": "1.10.2",
|
||||
"base-64": "^1.0.0",
|
||||
"big-integer": "1.6.51",
|
||||
"bignumber.js": "git+https://github.com/status-im/bignumber.js.git#refs/tags/v4.0.2-status",
|
||||
"chance": "^1.1.0",
|
||||
"emojilib": "^2.4.0",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 781 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -17,7 +17,7 @@
|
||||
(reg-root-key-sub :ui/search :ui/search)
|
||||
(reg-root-key-sub :network/type :network/type)
|
||||
(reg-root-key-sub :network-status :network-status)
|
||||
(reg-root-key-sub :peers-count :peers-count)
|
||||
(reg-root-key-sub :peer-stats/count :peer-stats/count)
|
||||
(reg-root-key-sub :peers-summary :peers-summary)
|
||||
(reg-root-key-sub :web3-node-version :web3-node-version)
|
||||
|
||||
|
||||
@@ -1,14 +1,9 @@
|
||||
(ns legacy.status-im.ui.components.connectivity.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.ui.components.animation :as animation]
|
||||
[legacy.status-im.ui.components.colors :as colors]
|
||||
[legacy.status-im.ui.components.core :as quo]
|
||||
[legacy.status-im.ui.components.list.item :as list.item]
|
||||
[legacy.status-im.ui.components.react :as react]
|
||||
[re-frame.core :as re-frame]
|
||||
[utils.i18n :as i18n])
|
||||
(:require-macros [legacy.status-im.utils.views :as views :refer [defview letsubs]]))
|
||||
[legacy.status-im.ui.components.react :as react])
|
||||
(:require-macros [legacy.status-im.utils.views :as views]))
|
||||
|
||||
(defn easing
|
||||
[direction n]
|
||||
@@ -72,112 +67,3 @@
|
||||
colors/white)
|
||||
:left
|
||||
(* 0.15 parent-width))}]]]))
|
||||
|
||||
(defview loading-indicator
|
||||
[]
|
||||
(letsubs [fetching? [:mailserver/fetching?]
|
||||
window-width [:dimensions/window-width]]
|
||||
(when fetching?
|
||||
[loading-indicator-anim window-width])))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[event]
|
||||
(re-frame/dispatch [:bottom-sheet/hide-old])
|
||||
(re-frame/dispatch event))
|
||||
|
||||
(defview connectivity-sheet
|
||||
[]
|
||||
(letsubs [{:keys [peers node mobile sync]} [:connectivity/state]
|
||||
current-mailserver-name [:mailserver/current-name]
|
||||
peers-count [:peers-count]
|
||||
{:keys [syncing-on-mobile-network?]} [:profile/profile]]
|
||||
[:<>
|
||||
[quo/header {:title (i18n/label :t/connection-status) :border-bottom false}]
|
||||
[quo/list-header (i18n/label :t/peer-to-peer)]
|
||||
(if (= peers :offline)
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/not-connected-to-peers)
|
||||
:accessibility-label "not-connected-to-peers"
|
||||
:subtitle (i18n/label :t/unable-to-send-messages)
|
||||
:subtitle-max-lines 2
|
||||
:theme :negative
|
||||
:icon :main-icons/network}]
|
||||
[list.item/list-item
|
||||
{:title (str (i18n/label :t/connected-to)
|
||||
" " peers-count
|
||||
" " (string/lower-case (i18n/label :t/peers)))
|
||||
:accessibility-label "connected-to-n-peers"
|
||||
:subtitle (i18n/label :t/can-send-messages)
|
||||
:subtitle-max-lines 2
|
||||
:theme :positive
|
||||
:icon :main-icons/network}])
|
||||
[quo/list-header (i18n/label :t/history-nodes)]
|
||||
(cond
|
||||
(#{:error :offline} node)
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/not-connected-nodes)
|
||||
:accessibility-label "not-connected-nodes"
|
||||
:subtitle (i18n/label :t/unable-to-fetch)
|
||||
:theme :negative
|
||||
:icon :main-icons/mailserver}]
|
||||
(= node :disabled)
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/nodes-disabled)
|
||||
:accessibility-label "nodes-disabled"
|
||||
:subtitle (i18n/label :t/unable-to-fetch)
|
||||
:disabled true
|
||||
:icon :main-icons/mailserver}]
|
||||
(and mobile (not sync))
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/waiting-wi-fi)
|
||||
:accessibility-label "waiting-wi-fi"
|
||||
:subtitle (i18n/label :t/unable-to-fetch)
|
||||
:disabled true
|
||||
:icon :main-icons/mailserver}]
|
||||
(= node :connecting)
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/connecting)
|
||||
:accessibility-label "connecting"
|
||||
:subtitle (i18n/label :t/unable-to-fetch)
|
||||
:icon :main-icons/mailserver}]
|
||||
(= node :online)
|
||||
[list.item/list-item
|
||||
{:title (str (i18n/label :t/connected-to) " " current-mailserver-name)
|
||||
:accessibility-label "connected-to-mailserver"
|
||||
:subtitle (i18n/label :t/you-can-fetch)
|
||||
:theme :positive
|
||||
:icon :main-icons/mailserver}])
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/settings)
|
||||
:accessibility-label "settings"
|
||||
:theme :accent
|
||||
:on-press #(hide-sheet-and-dispatch [:navigate-to :legacy-sync-settings])
|
||||
:icon :main-icons/settings}]
|
||||
(when mobile
|
||||
[:<>
|
||||
[react/view
|
||||
{:margin-vertical 8
|
||||
:background-color colors/gray-lighter
|
||||
:height 36
|
||||
:align-items :center
|
||||
:justify-content :center}
|
||||
[react/text {:style {:color colors/gray}} (i18n/label :t/youre-on-mobile-network)]]
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/mobile-network-use-mobile)
|
||||
:accessibility-label "mobile-network-use-mobile"
|
||||
:accessory :switch
|
||||
:on-press #(re-frame/dispatch [:mobile-network/set-syncing
|
||||
(not syncing-on-mobile-network?)])
|
||||
:active syncing-on-mobile-network?}]
|
||||
[react/text {:style {:margin-horizontal 16 :margin-bottom 12 :color colors/gray}}
|
||||
(i18n/label :t/status-mobile-descr)]])]))
|
||||
|
||||
(defn get-icon
|
||||
[{:keys [peers node mobile sync]}]
|
||||
(if (or (= peers :offline)
|
||||
(= node :offline)
|
||||
(= node :connecting))
|
||||
:main-icons/offline
|
||||
(if mobile
|
||||
(if sync :main-icons/mobile-sync :main-icons/mobile-sync-off)
|
||||
(when (#{:error :disabled} node) :main-icons/node-offline))))
|
||||
|
||||
@@ -1,17 +1,21 @@
|
||||
(ns legacy.status-im.ui.screens.peers-stats
|
||||
(:require
|
||||
[react-native.core :as react-native.core]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as re-frame]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn peers-stats
|
||||
[]
|
||||
(let [peers-count (re-frame/sub [:peers-count])]
|
||||
[react-native.core/view
|
||||
{:flex 1
|
||||
:margin-horizontal 8}
|
||||
[react-native.core/view
|
||||
(let [peers-count (rf/sub [:peer-stats/count])]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(rf/dispatch [:peer-stats/get-count])))
|
||||
|
||||
[rn/view
|
||||
{:style {:flex 1
|
||||
:margin-horizontal 8}}
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
:margin-vertical 8
|
||||
:justify-content :space-between}}
|
||||
[react-native.core/text (str (i18n/label :t/peers-count) ": " peers-count)]]]))
|
||||
[rn/text (str (i18n/label :t/peers-count) ": " peers-count)]]]))
|
||||
|
||||
@@ -128,7 +128,6 @@
|
||||
:current-chat-id
|
||||
:network
|
||||
:network-status
|
||||
:peers-count
|
||||
:peers-summary
|
||||
:sync-state
|
||||
:view-id
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
status-type]}]
|
||||
(and
|
||||
(= status-type constants/visibility-status-inactive)
|
||||
(> (:peers-count db) 0))
|
||||
(pos? (:peer-stats/count db)))
|
||||
;; Disable broadcasting further updates
|
||||
(conj {:ms 1000
|
||||
:dispatch
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
(:require
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.buttons.predictive-keyboard.style :as style]
|
||||
[quo.components.info.info-message :as info-message]
|
||||
[quo.components.info.info-message.view :as info-message]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
@@ -57,17 +57,17 @@
|
||||
:key-fn str}]
|
||||
|
||||
:error
|
||||
[info-message/info-message
|
||||
{:icon :i/info
|
||||
:size :default
|
||||
:type :error}
|
||||
[info-message/view
|
||||
{:icon :i/info
|
||||
:size :default
|
||||
:status :error}
|
||||
text]
|
||||
|
||||
:info
|
||||
[info-message/info-message
|
||||
(merge {:icon :i/info
|
||||
:size :default
|
||||
:type (if (= type :error) :error :default)}
|
||||
[info-message/view
|
||||
(merge {:icon :i/info
|
||||
:size :default
|
||||
:status (if (= type :error) :error :default)}
|
||||
(when blur?
|
||||
{:text-color colors/white-opa-70
|
||||
:icon-color colors/white-opa-40}))
|
||||
|
||||
@@ -26,7 +26,8 @@
|
||||
(reanimated/set-shared-value x-pos clamped-x)
|
||||
(when (and reached-end? (not sliding-complete?))
|
||||
(set-sliding-complete true)
|
||||
(when on-complete (on-complete reset-fn))))))
|
||||
(when on-complete
|
||||
(on-complete reset-fn))))))
|
||||
(gesture/on-end (fn [event]
|
||||
(let [x-translation (oops/oget event "translationX")
|
||||
reached-end? (>= x-translation track-width)]
|
||||
@@ -54,9 +55,10 @@
|
||||
on-track-layout (rn/use-callback
|
||||
#(set-track-width (oops/oget % "nativeEvent.layout.width")))
|
||||
reset-fn (rn/use-callback
|
||||
(fn []
|
||||
(fn [keep-at-end-after-slide?]
|
||||
(set-sliding-complete false)
|
||||
(animations/reset-track-position x-pos)))
|
||||
(when-not keep-at-end-after-slide?
|
||||
(animations/reset-track-position x-pos))))
|
||||
dimensions (rn/use-callback
|
||||
(partial utils/get-dimensions
|
||||
(or track-width constants/default-width)
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
(ns quo.components.info.info-message
|
||||
(:require
|
||||
[quo.components.icon :as quo.icons]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn get-color
|
||||
[k theme]
|
||||
(case k
|
||||
:success (colors/resolve-color :success theme)
|
||||
:error (colors/resolve-color :danger theme)
|
||||
:warning (colors/resolve-color :warning theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(defn info-message
|
||||
"[info-message opts \"message\"]
|
||||
opts
|
||||
{:type :default/:success/:error
|
||||
:size :default/:tiny
|
||||
:icon :i/info ;; info message icon
|
||||
:text-color colors/white ;; text color override
|
||||
:icon-color colors/white ;; icon color override
|
||||
:no-icon-color? false ;; disable tint color for icon"
|
||||
[{:keys [type size icon text-color icon-color no-icon-color? style accessibility-label
|
||||
container-style]} message]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
weight (if (= size :default) :regular :medium)
|
||||
icon-size (if (= size :default) 16 12)
|
||||
size (if (= size :default) :paragraph-2 :label)
|
||||
text-color (or text-color (get-color type theme))
|
||||
icon-color (or icon-color text-color)]
|
||||
[rn/view
|
||||
{:style (merge {:flex-direction :row
|
||||
:align-items :center}
|
||||
style
|
||||
container-style)}
|
||||
[quo.icons/icon icon
|
||||
{:color icon-color
|
||||
:no-color no-icon-color?
|
||||
:size icon-size}]
|
||||
[text/text
|
||||
{:accessibility-label accessibility-label
|
||||
:size size
|
||||
:weight weight
|
||||
:style {:color text-color
|
||||
:margin-horizontal 4}} message]]))
|
||||
@@ -0,0 +1,32 @@
|
||||
(ns quo.components.info.info-message.component-spec
|
||||
(:require
|
||||
[quo.components.info.info-message.view :as info-message]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Info: Info Message"
|
||||
(h/test "basic render"
|
||||
(h/render-with-theme-provider
|
||||
[info-message/view
|
||||
{:status :default
|
||||
:size :default
|
||||
:accessibility-label :info-message
|
||||
:icon :i/placeholder} "Message"])
|
||||
(h/is-truthy (h/get-by-label-text :info-message)))
|
||||
|
||||
(h/test "render with correct message"
|
||||
(h/render-with-theme-provider
|
||||
[info-message/view
|
||||
{:status :default
|
||||
:size :default
|
||||
:accessibility-label :info-message
|
||||
:icon :i/placeholder} "Message"])
|
||||
(h/is-truthy (h/get-by-text "Message")))
|
||||
|
||||
(h/test "render icon"
|
||||
(h/render-with-theme-provider
|
||||
[info-message/view
|
||||
{:status :default
|
||||
:size :default
|
||||
:accessibility-label :info-message
|
||||
:icon :i/placeholder} "Message"])
|
||||
(h/is-truthy (h/get-by-label-text :icon))))
|
||||
@@ -0,0 +1,6 @@
|
||||
(ns quo.components.info.info-message.style)
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
:gap 4
|
||||
:align-items :center})
|
||||
@@ -0,0 +1,53 @@
|
||||
(ns quo.components.info.info-message.view
|
||||
(:require [quo.components.icon :as icons]
|
||||
[quo.components.info.info-message.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]))
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:status {:optional true} [:maybe [:enum :default :success :error :warning]]]
|
||||
[:size {:optional true} [:maybe [:enum :default :tiny]]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:icon :keyword]
|
||||
[:color {:optional true} [:maybe :string]]
|
||||
[:text-color {:optional true} [:maybe :string]]
|
||||
[:icon-color {:optional true} [:maybe :string]]
|
||||
[:no-icon-color? {:optional true} [:maybe :boolean]]
|
||||
[:accessibility-label {:optional true} [:maybe :keyword]]
|
||||
[:container-style {:optional true} [:maybe :map]]]]
|
||||
[:message :string]]
|
||||
:any])
|
||||
|
||||
(defn- get-color
|
||||
[status theme blur?]
|
||||
(case status
|
||||
:success (if blur? colors/success-60 (colors/resolve-color :success theme))
|
||||
:error (if blur? colors/danger-60 (colors/resolve-color :danger theme))
|
||||
:warning (if blur? colors/warning-60 (colors/resolve-color :warning theme))
|
||||
(if blur? colors/white-opa-40 (colors/theme-colors colors/neutral-50 colors/neutral-40 theme))))
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [status size blur? icon color icon-color text-color no-icon-color? container-style
|
||||
accessibility-label]} message]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
default-color (get-color status theme blur?)
|
||||
text-color (or text-color color default-color)
|
||||
icon-color (or icon-color color default-color)]
|
||||
[rn/view {:style (merge style/container container-style)}
|
||||
[icons/icon icon
|
||||
{:size (if (= size :tiny) 12 16)
|
||||
:color icon-color
|
||||
:no-color? no-icon-color?}]
|
||||
[text/text
|
||||
{:size (if (= size :tiny) :label :paragraph-2)
|
||||
:accessibility-label accessibility-label
|
||||
:style {:color text-color}} message]]))
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
||||
@@ -44,13 +44,14 @@
|
||||
[:label :string]
|
||||
[:fiat-value :string]
|
||||
[:token-value :string]
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:state {:optional true} [:enum :pressed :active :disabled :default]]
|
||||
[:on-press {:optional true} [:maybe fn?]]]]]
|
||||
:any])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [on-press state customization-color]
|
||||
[{:keys [on-press container-style state customization-color]
|
||||
:as props
|
||||
:or {customization-color :blue}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
@@ -59,7 +60,8 @@
|
||||
on-press-out (rn/use-callback #(set-pressed false))
|
||||
internal-state (if pressed? :pressed state)]
|
||||
[rn/pressable
|
||||
{:style (style/container internal-state customization-color theme)
|
||||
{:style (merge (style/container internal-state customization-color theme)
|
||||
container-style)
|
||||
:on-press-in (when-not (= state :disabled) on-press-in)
|
||||
:on-press-out (when-not (= state :disabled) on-press-out)
|
||||
:on-press (when-not (= state :disabled) on-press)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def container-style
|
||||
(def container
|
||||
{:margin-horizontal 8
|
||||
:padding-vertical 8
|
||||
:padding-horizontal 12
|
||||
@@ -43,9 +43,9 @@
|
||||
(defn user
|
||||
[{:keys [short-chat-key primary-name secondary-name photo-path online? contact? verified?
|
||||
untrustworthy? on-press on-long-press accessory customization-color theme
|
||||
allow-multiple-presses? disabled?]}]
|
||||
allow-multiple-presses? disabled? container-style]}]
|
||||
[rn/touchable-highlight
|
||||
{:style container-style
|
||||
{:style (merge container container-style)
|
||||
:underlay-color (colors/resolve-color customization-color theme 5)
|
||||
:allow-multiple-presses? allow-multiple-presses?
|
||||
:accessibility-label :user-list
|
||||
|
||||
@@ -34,6 +34,12 @@
|
||||
(set-state (fn [prev-state]
|
||||
(assoc prev-state :image-loaded? true)))))
|
||||
|
||||
(defn on-load
|
||||
[evt set-state]
|
||||
(let [source (.. evt -nativeEvent -source)
|
||||
aspect-ratio (/ (.-width source) (.-height source))]
|
||||
(set-state (fn [prev-state] (assoc prev-state :image-aspect-ratio aspect-ratio)))))
|
||||
|
||||
(defn on-load-error
|
||||
[set-state]
|
||||
(js/setTimeout (fn []
|
||||
@@ -147,6 +153,7 @@
|
||||
[reanimated/view {:style (style/supported-file image-opacity)}
|
||||
[rn/image
|
||||
{:style style/image
|
||||
:on-load #(on-load % set-state)
|
||||
:on-load-start #(set-load-time (fn [start-time] (- (datetime/now) start-time)))
|
||||
:on-load-end #(on-load-end {:load-time load-time
|
||||
:set-state set-state
|
||||
@@ -197,6 +204,7 @@
|
||||
[reanimated/view {:style (style/supported-file image-opacity)}
|
||||
[rn/image
|
||||
{:style style/image
|
||||
:on-load #(on-load % set-state)
|
||||
:on-load-start #(set-load-time (fn [start-time] (- (datetime/now) start-time)))
|
||||
:on-load-end #(on-load-end {:load-time load-time
|
||||
:set-state set-state
|
||||
@@ -219,12 +227,13 @@
|
||||
(defn- view-internal
|
||||
[{:keys [container-style type on-press on-long-press supported-file?]
|
||||
:as props}]
|
||||
(let [[state set-state] (rn/use-state {:image-loaded? false
|
||||
:image-error? false
|
||||
:avatar-loaded? false})
|
||||
(let [[state set-state] (rn/use-state {:image-loaded? false
|
||||
:image-aspect-ratio nil
|
||||
:image-error? false
|
||||
:avatar-loaded? false})
|
||||
collectible-ready? (or (:image-loaded? state) (not supported-file?))]
|
||||
[rn/pressable
|
||||
{:on-press (when collectible-ready? on-press)
|
||||
{:on-press (when collectible-ready? #(on-press (:image-aspect-ratio state)))
|
||||
:on-long-press (when collectible-ready? on-long-press)
|
||||
:accessibility-label :collectible-list-item
|
||||
:style container-style}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
(ns quo.components.profile.expanded-collectible.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius 16})
|
||||
(defn container
|
||||
[aspect-ratio]
|
||||
(cond-> {:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius 16}
|
||||
aspect-ratio (assoc :width "100%"
|
||||
:aspect-ratio aspect-ratio)))
|
||||
|
||||
(defn image
|
||||
[square? aspect-ratio theme]
|
||||
@@ -25,18 +28,43 @@
|
||||
:border-color (colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)})
|
||||
|
||||
(defn fallback
|
||||
[{:keys [theme]}]
|
||||
{:background-color (colors/theme-colors colors/neutral-2_5 colors/neutral-90 theme)
|
||||
:border-style :dashed
|
||||
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:border-width 1
|
||||
:border-radius 16
|
||||
:width "100%"
|
||||
:aspect-ratio 1
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
([theme]
|
||||
(fallback theme 1))
|
||||
([theme aspect-ratio]
|
||||
{:background-color (colors/theme-colors colors/neutral-2_5 colors/neutral-90 theme)
|
||||
:border-style :dashed
|
||||
:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:border-width 1
|
||||
:border-radius 16
|
||||
:width "100%"
|
||||
:aspect-ratio aspect-ratio
|
||||
:align-items :center
|
||||
:justify-content :center}))
|
||||
|
||||
(def counter
|
||||
{:position :absolute
|
||||
:top 12
|
||||
:right 12})
|
||||
|
||||
(defn loading-image-with-opacity
|
||||
[opacity]
|
||||
[{:align-items :center
|
||||
:aspect-ratio 1
|
||||
:border-radius 16
|
||||
:justify-content :center
|
||||
:opacity opacity
|
||||
:position :absolute
|
||||
:width "100%"
|
||||
:z-index 1}])
|
||||
|
||||
(defn gradient-view
|
||||
[aspect-ratio]
|
||||
{:border-radius 16
|
||||
:width "100%"
|
||||
:aspect-ratio aspect-ratio
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(defn supported-file
|
||||
[opacity]
|
||||
{:opacity opacity})
|
||||
|
||||
@@ -1,17 +1,53 @@
|
||||
(ns quo.components.profile.expanded-collectible.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[promesa.core :as promesa]
|
||||
[quo.components.counter.collectible-counter.view :as collectible-counter]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.profile.expanded-collectible.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.gradients :as gradients]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[schema.core :as schema]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(def timing-options-out 650)
|
||||
(def timing-options-in 1000)
|
||||
(def first-load-time 500)
|
||||
(def cached-load-time 200)
|
||||
(def error-wait-time 800)
|
||||
|
||||
(defn on-load-end
|
||||
[{:keys [load-time set-state loader-opacity image-opacity]}]
|
||||
(reanimated/animate loader-opacity 0 timing-options-out)
|
||||
(reanimated/animate image-opacity 1 timing-options-in)
|
||||
(if (> load-time cached-load-time)
|
||||
(js/setTimeout
|
||||
(fn []
|
||||
(set-state (fn [prev-state]
|
||||
(assoc prev-state :image-loaded? true))))
|
||||
first-load-time)
|
||||
(set-state (fn [prev-state]
|
||||
(assoc prev-state :image-loaded? true)))))
|
||||
|
||||
(defn on-load-error
|
||||
[set-state]
|
||||
(js/setTimeout (fn []
|
||||
(set-state (fn [prev-state] (assoc prev-state :image-error? true))))
|
||||
error-wait-time))
|
||||
|
||||
(defn- loading-image
|
||||
[{:keys [theme gradient-color-index loader-opacity aspect-ratio]}]
|
||||
[reanimated/view
|
||||
{:style (style/loading-image-with-opacity loader-opacity)}
|
||||
[gradients/view
|
||||
{:theme theme
|
||||
:container-style (style/gradient-view aspect-ratio)
|
||||
:color-index gradient-color-index}]])
|
||||
|
||||
(defn- counter-view
|
||||
[counter]
|
||||
[collectible-counter/view
|
||||
@@ -21,7 +57,7 @@
|
||||
(defn- fallback-view
|
||||
[{:keys [label theme counter on-mount]}]
|
||||
(rn/use-mount on-mount)
|
||||
[rn/view {:style (style/fallback {:theme theme})}
|
||||
[rn/view {:style (style/fallback theme)}
|
||||
[counter-view counter]
|
||||
[rn/view
|
||||
[icon/icon :i/sad {:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}]]
|
||||
@@ -33,45 +69,57 @@
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [container-style square? on-press counter image-src native-ID supported-file?
|
||||
on-collectible-load]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
[image-size set-image-size] (rn/use-state {})
|
||||
[image-error? set-image-error] (rn/use-state (or (nil? image-src)
|
||||
(string/blank? image-src)))]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(promesa/let [[image-width image-height] (rn/image-get-size image-src)]
|
||||
(set-image-size {:width image-width
|
||||
:height image-height
|
||||
:aspect-ratio (/ image-width image-height)})))
|
||||
[image-src])
|
||||
on-collectible-load aspect-ratio]}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
loader-opacity (reanimated/use-shared-value
|
||||
(if supported-file? 1 0))
|
||||
image-opacity (reanimated/use-shared-value
|
||||
(if supported-file? 0 1))
|
||||
[load-time set-load-time] (rn/use-state (datetime/now))
|
||||
[state set-state] (rn/use-state {:image-loaded? false
|
||||
:image-error? (or (nil? image-src)
|
||||
(string/blank?
|
||||
image-src))})]
|
||||
[rn/pressable
|
||||
{:on-press (when (and (not image-error?) supported-file?) on-press)
|
||||
{:on-press (when (and (not (:image-error? state)) supported-file?) on-press)
|
||||
:accessibility-label :expanded-collectible
|
||||
:style (merge container-style style/container)}
|
||||
:style (merge container-style
|
||||
(style/container aspect-ratio))}
|
||||
(cond
|
||||
(not supported-file?)
|
||||
[fallback-view
|
||||
{:label (i18n/label :t/unsupported-file)
|
||||
:counter counter
|
||||
:theme theme
|
||||
:on-mount on-collectible-load}]
|
||||
{:aspect-ratio aspect-ratio
|
||||
:label (i18n/label :t/unsupported-file)
|
||||
:counter counter
|
||||
:theme theme
|
||||
:on-mount on-collectible-load}]
|
||||
|
||||
image-error?
|
||||
(:image-error? state)
|
||||
[fallback-view
|
||||
{:label (i18n/label :t/cant-fetch-info)
|
||||
:counter counter
|
||||
:theme theme
|
||||
:on-mount on-collectible-load}]
|
||||
|
||||
:else
|
||||
[rn/view
|
||||
(not (:image-loaded? state))
|
||||
[loading-image
|
||||
{:aspect-ratio aspect-ratio
|
||||
:loader-opacity loader-opacity
|
||||
:theme theme
|
||||
:gradient-color-index :gradient-5}])
|
||||
(when supported-file?
|
||||
[reanimated/view {:style (style/supported-file image-opacity)}
|
||||
[rn/image
|
||||
{:style (style/image square? (:aspect-ratio image-size) theme)
|
||||
:source image-src
|
||||
:native-ID native-ID
|
||||
:on-error #(set-image-error true)
|
||||
:on-load on-collectible-load}]
|
||||
{:style (style/image square? aspect-ratio theme)
|
||||
:source image-src
|
||||
:native-ID native-ID
|
||||
:on-load-start #(set-load-time (fn [start-time] (- (datetime/now) start-time)))
|
||||
:on-load-end #(on-load-end {:load-time load-time
|
||||
:set-state set-state
|
||||
:loader-opacity loader-opacity
|
||||
:image-opacity image-opacity})
|
||||
:on-error #(on-load-error set-state)
|
||||
:on-load on-collectible-load}]
|
||||
(when counter
|
||||
[counter-view counter])
|
||||
[rn/view {:style (style/collectible-border theme)}]])]))
|
||||
@@ -81,6 +129,7 @@
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:aspect-ratio {:optional true} [:maybe number?]]
|
||||
[:image-src {:optional true} [:maybe string?]]
|
||||
[:supported-file? {:optional true} [:maybe boolean?]]
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
[{:keys [checked? blur? accessibility-label container-style on-change icon customization-color]} label]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press on-change
|
||||
{:on-press (when on-change
|
||||
#(on-change (not checked?)))
|
||||
:accessibility-label :disclaimer-touchable-opacity}
|
||||
[rn/view {:style (merge container-style (style/container blur? theme))}
|
||||
[selectors/view
|
||||
|
||||
@@ -6,8 +6,14 @@
|
||||
[{:keys [size card? blur? actionable? theme]}]
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:padding-vertical (when (= size :default) 8)
|
||||
:padding-horizontal (when (= size :default) 12)
|
||||
:padding-vertical (case size
|
||||
:default 8
|
||||
:large 12
|
||||
nil)
|
||||
:padding-horizontal (case size
|
||||
:default 12
|
||||
:large 16
|
||||
nil)
|
||||
:border-radius 16
|
||||
:border-width (when (and card? (not= size :small)) 1)
|
||||
:background-color (if blur?
|
||||
@@ -24,15 +30,27 @@
|
||||
|
||||
(defn loading-container
|
||||
[size blur? theme]
|
||||
{:width (if (= size :default) 132 72)
|
||||
:height (if (= size :default) 16 10)
|
||||
{:width (case size
|
||||
:large 132
|
||||
:small 72
|
||||
132)
|
||||
:height (case size
|
||||
:large 16
|
||||
:small 10
|
||||
16)
|
||||
:background-color (if blur?
|
||||
colors/white-opa-5
|
||||
(colors/theme-colors colors/neutral-5
|
||||
colors/neutral-90
|
||||
theme))
|
||||
:border-radius (if (= size :default) 6 3)
|
||||
:margin-vertical (if (= size :default) 4 3)})
|
||||
:border-radius (case size
|
||||
:large 6
|
||||
:small 3
|
||||
6)
|
||||
:margin-vertical (case size
|
||||
:large 4
|
||||
:small 3
|
||||
4)})
|
||||
|
||||
(def subtitle-container
|
||||
{:flex-direction :row
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
:container-style container-style
|
||||
:theme theme))
|
||||
:on-press #(when (= action :selector) (on-press))
|
||||
:pointer-events :box-only}
|
||||
:pointer-events (when (= action :selector) :box-only)}
|
||||
[rn/view {:style style/header-container}
|
||||
[avatar props]
|
||||
[rn/view
|
||||
|
||||
+2
-2
@@ -68,7 +68,7 @@
|
||||
quo.components.graph.wallet-graph.view
|
||||
quo.components.header
|
||||
quo.components.icon
|
||||
quo.components.info.info-message
|
||||
quo.components.info.info-message.view
|
||||
quo.components.info.information-box.view
|
||||
quo.components.inputs.address-input.view
|
||||
quo.components.inputs.input.view
|
||||
@@ -301,7 +301,7 @@
|
||||
(def icon quo.components.icon/icon)
|
||||
|
||||
;;;; Info
|
||||
(def info-message quo.components.info.info-message/info-message)
|
||||
(def info-message quo.components.info.info-message.view/view)
|
||||
(def information-box quo.components.info.information-box.view/view)
|
||||
|
||||
;;;; Inputs
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
quo.components.dropdowns.network-dropdown.component-spec
|
||||
quo.components.gradient.gradient-cover.component-spec
|
||||
quo.components.graph.wallet-graph.component-spec
|
||||
quo.components.info.info-message.component-spec
|
||||
quo.components.inputs.address-input.component-spec
|
||||
quo.components.inputs.input.component-spec
|
||||
quo.components.inputs.locked-input.component-spec
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
(ns status-im.common.check-before-syncing.style)
|
||||
|
||||
(def buttons-container
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:gap 12
|
||||
:padding-vertical 12})
|
||||
|
||||
(def button {:flex 1})
|
||||
|
||||
(def checkbox
|
||||
{:margin-top 16
|
||||
:flex-direction :row
|
||||
:align-items :center})
|
||||
|
||||
(def checkbox-text {:margin-left 10})
|
||||
|
||||
(def checkboxes-container {:margin-bottom 10 :padding-right 10})
|
||||
|
||||
(def header {:margin-bottom 8})
|
||||
|
||||
(def description {:margin-right -33})
|
||||
|
||||
(def view-container {:padding-horizontal 33})
|
||||
@@ -0,0 +1,74 @@
|
||||
(ns status-im.common.check-before-syncing.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.check-before-syncing.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def checks
|
||||
[(i18n/label :t/check-before-syncing-doc-checkbox-1)
|
||||
(i18n/label :t/check-before-syncing-doc-checkbox-2)
|
||||
(i18n/label :t/check-before-syncing-doc-checkbox-3)])
|
||||
|
||||
(defn- checkbox
|
||||
[on-change customization-color description]
|
||||
[rn/view {:style style/checkbox}
|
||||
[quo/selectors
|
||||
{:type :checkbox
|
||||
:blur? true
|
||||
:customization-color customization-color
|
||||
:on-change on-change}]
|
||||
[quo/text {:style style/checkbox-text} description]])
|
||||
|
||||
(defn- compute-new-checked-count
|
||||
[set-checked-count checked?]
|
||||
(if checked?
|
||||
(set-checked-count inc)
|
||||
(set-checked-count dec)))
|
||||
|
||||
(defn- hide-bottom-sheet
|
||||
[]
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-submit customization-color]}]
|
||||
(let [[checked-count set-checked-count] (rn/use-state 0)
|
||||
on-change (partial compute-new-checked-count set-checked-count)
|
||||
render-checkbox (rn/use-callback
|
||||
(partial checkbox on-change customization-color)
|
||||
[customization-color])
|
||||
on-cancel hide-bottom-sheet
|
||||
on-continue (rn/use-callback
|
||||
(fn []
|
||||
(hide-bottom-sheet)
|
||||
(on-submit))
|
||||
[on-submit])]
|
||||
[rn/view
|
||||
{:style style/view-container
|
||||
:accessibility-label :check-before-syncing-bottom-sheet}
|
||||
[quo/text
|
||||
{:weight :semi-bold
|
||||
:size :heading-2
|
||||
:style style/header} (i18n/label :t/check-before-syncing)]
|
||||
[quo/text {:style style/description} (i18n/label :t/check-before-syncing-doc-description)]
|
||||
|
||||
(into
|
||||
[rn/view {:style style/checkboxes-container}]
|
||||
(mapv render-checkbox checks))
|
||||
|
||||
[rn/view {:style style/buttons-container}
|
||||
[quo/button
|
||||
{:type :grey
|
||||
:container-style style/button
|
||||
:accessibility-label :cancel-button
|
||||
:on-press on-cancel}
|
||||
(i18n/label :t/cancel)]
|
||||
[quo/button
|
||||
{:container-style style/button
|
||||
:disabled? (not= checked-count (count checks))
|
||||
:customization-color (or customization-color :blue)
|
||||
:accessibility-label :continue-button
|
||||
|
||||
:on-press on-continue}
|
||||
(i18n/label :t/continue)]]]))
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
(defn contact-list-item
|
||||
[{:keys [on-press on-long-press accessory allow-multiple-presses? disabled?]}
|
||||
{:keys [primary-name secondary-name public-key compressed-key ens-verified added?]}
|
||||
{:keys [primary-name secondary-name public-key compressed-key ens-verified added?
|
||||
container-style]}
|
||||
theme]
|
||||
(let [photo-path (rf/sub [:chats/photo-path public-key])
|
||||
online? (rf/sub [:visibility-status-updates/online? public-key])
|
||||
@@ -25,4 +26,5 @@
|
||||
:on-press on-press
|
||||
:on-long-press on-long-press
|
||||
:accessory accessory
|
||||
:container-style container-style
|
||||
:disabled? disabled?}]))
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
:on-change-text #(reset! entered-password %)}]
|
||||
(when (not-empty error)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:containstyle {:margin-top 8}}
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:container-style {:margin-top 8}}
|
||||
(i18n/label :t/oops-wrong-password)])
|
||||
[quo/button
|
||||
{:container-style {:margin-bottom 12 :margin-top 40}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
(ns status-im.common.peer-stats.events
|
||||
(:require
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/reg-event-fx :peer-stats/get-count
|
||||
(fn []
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method :wakuext_peers
|
||||
:on-success [:peer-stats/get-count-success]
|
||||
:on-error (fn [error]
|
||||
(log/error "failed to fetch wakuv2 peer count"
|
||||
{:error error}))}]]]}))
|
||||
|
||||
(rf/reg-event-fx :peer-stats/get-count-success
|
||||
(fn [{:keys [db]} [response]]
|
||||
{:db (assoc db :peer-stats/count (count response))}))
|
||||
@@ -195,7 +195,7 @@
|
||||
true)
|
||||
|
||||
(defn view
|
||||
[{:keys [title subtitle validate-fn on-success-scan error-message share-button? import-keypair?]}]
|
||||
[{:keys [title subtitle validate-fn on-success-scan error-message share-button?]}]
|
||||
(let [insets (safe-area/get-insets)
|
||||
qr-code-succeed? (reagent/atom false)
|
||||
qr-view-finder (reagent/atom {})
|
||||
@@ -233,9 +233,7 @@
|
||||
:set-qr-code-succeeded (fn [value]
|
||||
(when on-success-scan
|
||||
(on-success-scan value))
|
||||
(if import-keypair?
|
||||
(set-rescan-timeout)
|
||||
(rf/dispatch [:navigate-back])))
|
||||
(rf/dispatch [:navigate-back]))
|
||||
:set-rescan-timeout set-rescan-timeout}])
|
||||
[rn/view {:style (style/root-container (:top insets))}
|
||||
[header
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
[status-im.contexts.communities.discover.events]
|
||||
[status-im.contexts.profile.push-notifications.local.events :as local-notifications]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
@@ -20,17 +19,10 @@
|
||||
peers-count (count peers-summary)]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db
|
||||
:peers-summary peers-summary
|
||||
:peers-count peers-count)}
|
||||
:peers-summary peers-summary
|
||||
:peer-stats/count peers-count)}
|
||||
(visibility-status-updates/peers-summary-change peers-count))))
|
||||
|
||||
(rf/reg-event-fx :wakuv2-peer-stats
|
||||
(fn [{:keys [db]} [^js peer-stats-js]]
|
||||
(let [peer-stats (transforms/js->clj peer-stats-js)]
|
||||
{:db (assoc db
|
||||
:peer-stats peer-stats
|
||||
:peers-count (count (:peers peer-stats)))})))
|
||||
|
||||
(rf/defn process
|
||||
{:events [:signals/signal-received]}
|
||||
[{:keys [db] :as cofx} event-str]
|
||||
@@ -46,9 +38,6 @@
|
||||
"wallet"
|
||||
{:fx [[:dispatch [:wallet/signal-received event-js]]]}
|
||||
|
||||
"wakuv2.peerstats"
|
||||
(debounce/debounce-and-dispatch [:wakuv2-peer-stats event-js] 1000)
|
||||
|
||||
"envelope.sent"
|
||||
(messages.transport/update-envelopes-status
|
||||
cofx
|
||||
|
||||
@@ -32,9 +32,8 @@
|
||||
:on-cancel #(rf/dispatch [:standard-auth/authorize-with-password
|
||||
args-with-biometric-btn])
|
||||
:on-success (fn []
|
||||
(when (fn? on-close)
|
||||
(on-close))
|
||||
(rf/dispatch [:standard-auth/on-biometric-success on-auth-success]))
|
||||
(rf/dispatch [:standard-auth/on-biometric-success on-auth-success])
|
||||
(rf/dispatch [:standard-auth/close on-close]))
|
||||
:on-fail (fn [err]
|
||||
(rf/dispatch [:standard-auth/authorize-with-password
|
||||
args-with-biometric-btn])
|
||||
@@ -48,6 +47,7 @@
|
||||
[{:keys [db]} [on-auth-success]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:keychain/get-user-password [key-uid on-auth-success]]
|
||||
[:dispatch [:standard-auth/set-success true]]
|
||||
[:dispatch [:standard-auth/reset-login-password]]]}))
|
||||
|
||||
(schema/=> on-biometric-success events-schema/?on-biometric-success)
|
||||
@@ -74,6 +74,7 @@
|
||||
(fn [password]
|
||||
(let [sha3-pwd (security/hash-masked-password password)
|
||||
on-auth-success-callback #(on-auth-success sha3-pwd)]
|
||||
(rf/dispatch [:standard-auth/set-success true])
|
||||
(rf/dispatch [:standard-auth/reset-login-password])
|
||||
(if has-partially-operable-accounts?
|
||||
(rf/dispatch [:wallet/make-partially-operable-accounts-fully-operable
|
||||
@@ -92,10 +93,7 @@
|
||||
{:fx [[:dispatch [:standard-auth/reset-login-password]]
|
||||
[:dispatch
|
||||
[:show-bottom-sheet
|
||||
{:on-close (fn []
|
||||
(rf/dispatch [:standard-auth/reset-login-password])
|
||||
(when on-close
|
||||
(on-close)))
|
||||
{:on-close #(rf/dispatch [:standard-auth/close on-close])
|
||||
:theme theme
|
||||
:shell? blur?
|
||||
:content #(bottom-sheet-password-view args)}]]]})
|
||||
@@ -107,3 +105,23 @@
|
||||
:standard-auth/reset-login-password
|
||||
(fn [{:keys [db]}]
|
||||
{:db (update db :profile/login dissoc :password :error)}))
|
||||
|
||||
(rf/reg-fx
|
||||
:standard-auth/on-close
|
||||
(fn [{:keys [on-close success?]}]
|
||||
(when on-close
|
||||
(on-close success?))))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:standard-auth/close
|
||||
(fn [{:keys [db]} [on-close]]
|
||||
{:db (assoc-in db [:profile/login :success?] false)
|
||||
:fx [[:dispatch [:standard-auth/reset-login-password]]
|
||||
[:standard-auth/on-close
|
||||
{:on-close on-close
|
||||
:success? (get-in db [:profile/login :success?])}]]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:standard-auth/set-success
|
||||
(fn [{:keys [db]} [success?]]
|
||||
{:db (assoc-in db [:profile/login :success?] success?)}))
|
||||
|
||||
@@ -16,8 +16,7 @@
|
||||
[error]
|
||||
(if (and (some? error)
|
||||
(or (= error "file is not a database")
|
||||
(string/starts-with? error "failed to set ")
|
||||
(string/starts-with? error "Failed")))
|
||||
(string/starts-with? (string/lower-case error) "failed")))
|
||||
(i18n/label :t/oops-wrong-password)
|
||||
error))
|
||||
|
||||
@@ -34,9 +33,9 @@
|
||||
[theme])]
|
||||
[rn/view {:style style/error-message}
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
error-message]
|
||||
[rn/pressable
|
||||
{:hit-slop {:top 6 :bottom 20 :left 0 :right 0}
|
||||
|
||||
@@ -16,7 +16,8 @@
|
||||
on-complete (rn/use-callback
|
||||
(fn [reset]
|
||||
(rf/dispatch [:standard-auth/authorize
|
||||
{:on-close #(js/setTimeout reset 200)
|
||||
{:on-close (fn [success?]
|
||||
(js/setTimeout #(reset success?) 200))
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
|
||||
@@ -282,6 +282,8 @@
|
||||
(def ^:const wallet-connect-session-proposal-event "session_proposal")
|
||||
(def ^:const wallet-connect-session-request-event "session_request")
|
||||
|
||||
(def ^:const transaction-pending-type-wallet-connect-transfer "WalletConnectTransfer")
|
||||
|
||||
(def ^:const dapp-permission-contact-code "contact-code")
|
||||
(def ^:const dapp-permission-web3 "web3")
|
||||
(def ^:const dapp-permission-qr-code "qr-code")
|
||||
@@ -503,6 +505,9 @@
|
||||
(def ^:const optimism-network-name :optimism)
|
||||
(def ^:const arbitrum-network-name :arbitrum)
|
||||
|
||||
(def ^:const layer-1-network 1)
|
||||
(def ^:const layer-2-network 2)
|
||||
|
||||
(def ^:const default-network-names [mainnet-network-name optimism-network-name arbitrum-network-name])
|
||||
|
||||
(def ^:const default-network-count (count default-network-names))
|
||||
@@ -548,3 +553,10 @@
|
||||
(def ^:const community-joined-notification-type "communityJoined")
|
||||
|
||||
(def ^:const default-telemetry-server-url "https://telemetry.status.im")
|
||||
|
||||
(def ^:const contact-item-height 56)
|
||||
|
||||
(def ^:const slippages [0.1 0.5 1])
|
||||
(def ^:const default-slippage 0.5)
|
||||
(def ^:const max-recommended-slippage 5)
|
||||
(def ^:const max-slippage-decimal-places 2)
|
||||
|
||||
@@ -105,10 +105,10 @@
|
||||
:max-length constants/max-group-chat-name-length}]
|
||||
(when error-message
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:icon :i/info
|
||||
:size :default
|
||||
:style {:margin-top 8 :margin-left 20 :margin-bottom 16}}
|
||||
{:status :error
|
||||
:icon :i/info
|
||||
:size :default
|
||||
:container-style {:margin-top 8 :margin-left 20 :margin-bottom 16}}
|
||||
error-message])
|
||||
[quo/divider-line]
|
||||
[rn/view
|
||||
|
||||
@@ -173,20 +173,21 @@
|
||||
|
||||
(defn avatar-view
|
||||
[{:keys [contact chat-id full-name color muted? image]}]
|
||||
(if contact ; `contact` is passed when it's not a group chat
|
||||
(let [online? (rf/sub [:visibility-status-updates/online? chat-id])
|
||||
photo-path (rf/sub [:chats/photo-path chat-id])]
|
||||
[quo/user-avatar
|
||||
(cond-> {:full-name full-name
|
||||
:size :small
|
||||
:online? online?
|
||||
:profile-picture photo-path}
|
||||
muted?
|
||||
(assoc :ring? false))])
|
||||
[quo/group-avatar
|
||||
{:customization-color color
|
||||
:picture (when image {:uri image})
|
||||
:size :size-32}]))
|
||||
[rn/view {:style {:justify-content :center}}
|
||||
(if contact ; `contact` is passed when it's not a group chat
|
||||
(let [online? (rf/sub [:visibility-status-updates/online? chat-id])
|
||||
photo-path (rf/sub [:chats/photo-path chat-id])]
|
||||
[quo/user-avatar
|
||||
(cond-> {:full-name full-name
|
||||
:size :small
|
||||
:online? online?
|
||||
:profile-picture photo-path}
|
||||
muted?
|
||||
(assoc :ring? false))])
|
||||
[quo/group-avatar
|
||||
{:customization-color color
|
||||
:picture (when image {:uri image})
|
||||
:size :size-32}])])
|
||||
|
||||
(defn- notification-layout
|
||||
[child]
|
||||
|
||||
@@ -66,7 +66,8 @@
|
||||
(chat-list-item/chat-list-item item theme))
|
||||
:scroll-event-throttle 8
|
||||
:content-container-style {:padding-bottom
|
||||
jump-to.constants/floating-shell-button-height}
|
||||
jump-to.constants/floating-shell-button-height
|
||||
:padding-top 8}
|
||||
:on-scroll #(common.banner/set-scroll-shared-value
|
||||
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
|
||||
:shared-value scroll-shared-value})}])))
|
||||
|
||||
@@ -98,9 +98,8 @@
|
||||
window-height
|
||||
loading-indicator-page-loading-height)]
|
||||
[rn/view {:padding-top top-spacing}
|
||||
;; Only use animated loading skeleton for ios
|
||||
;; https://github.com/status-im/status-mobile/issues/17426
|
||||
[quo/skeleton-list (skeleton-list-props :messages parent-height platform/ios?)]]))
|
||||
;; Don't use animated loading skeleton https://github.com/status-im/status-mobile/issues/17426
|
||||
[quo/skeleton-list (skeleton-list-props :messages parent-height false)]]))
|
||||
|
||||
(defn header-height
|
||||
[{:keys [insets able-to-send-message? images reply edit link-previews? input-content-height]}]
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
[status-im.contexts.chat.messenger.messages.pin.events :as messages.pin]
|
||||
[status-im.contexts.communities.events :as communities]
|
||||
[status-im.contexts.shell.activity-center.events :as activity-center]
|
||||
[status-im.contexts.wallet.data-store :as wallet.data-store]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -54,8 +55,11 @@
|
||||
^js cleared-histories (.-clearedHistories response-js)
|
||||
^js identity-images (.-identityImages response-js)
|
||||
^js accounts (.-accounts response-js)
|
||||
^js keypairs (.-keypairs response-js)
|
||||
^js ens-username-details-js (.-ensUsernameDetails response-js)
|
||||
^js customization-color-js (.-customizationColor response-js)
|
||||
^js saved-addresses-js (.-savedAddresses response-js)
|
||||
^js watch-only-accounts (.-watchOnlyAccounts response-js)
|
||||
sync-handler (when-not process-async process-response)]
|
||||
(cond
|
||||
|
||||
@@ -177,6 +181,22 @@
|
||||
(rf/merge cofx
|
||||
(process-next response-js sync-handler)))
|
||||
|
||||
(seq watch-only-accounts)
|
||||
(do
|
||||
(js-delete response-js "watchOnlyAccounts")
|
||||
(rf/merge cofx
|
||||
{:fx [[:dispatch
|
||||
[:wallet/reconcile-watch-only-accounts
|
||||
(types/js->clj watch-only-accounts)]]]}
|
||||
(process-next response-js sync-handler)))
|
||||
|
||||
(seq keypairs)
|
||||
(do
|
||||
(js-delete response-js "keypairs")
|
||||
(rf/merge cofx
|
||||
{:fx [[:dispatch [:wallet/reconcile-keypairs (types/js->clj keypairs)]]]}
|
||||
(process-next response-js sync-handler)))
|
||||
|
||||
(seq settings)
|
||||
(do
|
||||
(js-delete response-js "settings")
|
||||
@@ -199,6 +219,13 @@
|
||||
(models.visibility-status-updates/sync-visibility-status-update
|
||||
current-visibility-status-clj)))
|
||||
|
||||
(seq saved-addresses-js)
|
||||
(let [saved-addresses (-> saved-addresses-js types/js->clj wallet.data-store/rpc->saved-addresses)]
|
||||
(js-delete response-js "savedAddresses")
|
||||
(rf/merge cofx
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]}
|
||||
(process-next response-js sync-handler)))
|
||||
|
||||
(seq ens-username-details-js)
|
||||
(let [ens-username-details-clj (types/js->clj ens-username-details-js)]
|
||||
(js-delete response-js "ensUsernameDetails")
|
||||
|
||||
@@ -6,32 +6,44 @@
|
||||
[status-im.common.contact-list-item.view :as contact-list-item]
|
||||
[status-im.common.contact-list.view :as contact-list]
|
||||
[status-im.common.home.actions.view :as home.actions]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.communities.actions.channel-view-details.style :as style]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- contact-item
|
||||
[public-key]
|
||||
(let [show-profile-actions #(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [home.actions/contact-actions
|
||||
{:public-key public-key}])}])
|
||||
[primary-name secondary-name] (rf/sub [:contacts/contact-two-names-by-identity
|
||||
public-key])
|
||||
{:keys [ens-verified added? compressed-key]} (rf/sub [:contacts/contact-by-address public-key])
|
||||
theme (quo.theme/use-theme)]
|
||||
[public-key _ _ {:keys [theme]}]
|
||||
(let [show-profile-actions (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [home.actions/contact-actions
|
||||
{:public-key public-key}])}]))
|
||||
[public-key])
|
||||
on-press (rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:chat.ui/show-profile public-key]))
|
||||
[public-key])
|
||||
[primary-name
|
||||
secondary-name] (rf/sub [:contacts/contact-two-names-by-identity public-key])
|
||||
{:keys [ens-verified
|
||||
added?
|
||||
compressed-key]} (rf/sub [:contacts/contact-by-address public-key])]
|
||||
[contact-list-item/contact-list-item
|
||||
{:on-press #(rf/dispatch [:chat.ui/show-profile public-key])
|
||||
{:on-press on-press
|
||||
:on-long-press show-profile-actions
|
||||
:accessory {:type :options
|
||||
:on-press show-profile-actions}}
|
||||
{:primary-name primary-name
|
||||
:secondary-name secondary-name
|
||||
:compressed-key compressed-key
|
||||
:public-key public-key
|
||||
:ens-verified ens-verified
|
||||
:added? added?}
|
||||
{:primary-name primary-name
|
||||
:secondary-name secondary-name
|
||||
:compressed-key compressed-key
|
||||
:public-key public-key
|
||||
:ens-verified ens-verified
|
||||
:added? added?
|
||||
;; We hardcode the height of the container to match exactly the height
|
||||
;; used in the `get-item-layout` function.
|
||||
:container-style {:height constants/contact-item-height}}
|
||||
theme]))
|
||||
|
||||
(defn- footer
|
||||
@@ -40,10 +52,12 @@
|
||||
|
||||
(defn- get-item-layout
|
||||
[_ index]
|
||||
#js {:length 200 :offset (* 200 index) :index index})
|
||||
#js {:length constants/contact-item-height
|
||||
:offset (* constants/contact-item-height index)
|
||||
:index index})
|
||||
|
||||
(defn- members
|
||||
[items]
|
||||
[items theme]
|
||||
[rn/section-list
|
||||
{:key-fn :public-key
|
||||
:content-container-style {:padding-bottom 20}
|
||||
@@ -53,70 +67,70 @@
|
||||
:sticky-section-headers-enabled false
|
||||
:render-section-header-fn contact-list/contacts-section-header
|
||||
:render-section-footer-fn footer
|
||||
:render-data {:theme theme}
|
||||
:render-fn contact-item
|
||||
:scroll-event-throttle 8}])
|
||||
:scroll-event-throttle 32}])
|
||||
|
||||
(defn view
|
||||
[_args]
|
||||
(fn []
|
||||
(let [{:keys [chat-id community-id]} (rf/sub [:get-screen-params
|
||||
:screen/chat.view-channel-members-and-details])
|
||||
{:keys [description chat-name emoji muted chat-type color]
|
||||
:as chat} (rf/sub [:chats/chat-by-id chat-id])
|
||||
pins-count (rf/sub [:chats/pin-messages-count chat-id])
|
||||
items (rf/sub [:communities/sorted-community-members-section-list
|
||||
community-id chat-id])
|
||||
theme (quo.theme/use-theme)]
|
||||
(rn/use-mount (fn []
|
||||
(rf/dispatch [:pin-message/load-pin-messages chat-id])))
|
||||
[:<>
|
||||
(when (ff/enabled? ::ff/shell.jump-to)
|
||||
[quo/floating-shell-button
|
||||
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
|
||||
:customization-color color
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
style/floating-shell-button])
|
||||
[quo/gradient-cover {:customization-color color :opacity 0.4}]
|
||||
[quo/page-nav
|
||||
{:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side [{:icon-name :i/options
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [home.actions/chat-actions
|
||||
chat
|
||||
false
|
||||
true])}])}]}]
|
||||
[quo/text-combinations
|
||||
{:container-style style/text-combinations
|
||||
:title [quo/channel-name
|
||||
{:channel-name chat-name
|
||||
:unlocked? true}]
|
||||
:theme theme
|
||||
:emoji (when (not (string/blank? emoji)) (string/trim emoji))
|
||||
:customization-color color
|
||||
:title-accessibility-label :welcome-title
|
||||
:description description
|
||||
:description-accessibility-label :welcome-sub-title}]
|
||||
[rn/view {:style style/wrapper}
|
||||
[rn/view
|
||||
{:style style/channel-actions-wrapper}
|
||||
[quo/channel-actions
|
||||
{:actions
|
||||
[{:big? true
|
||||
:label (i18n/label :t/pinned-messages-2)
|
||||
:customization-color color
|
||||
:icon :i/pin
|
||||
:counter-value pins-count
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:pin-message/show-pins-bottom-sheet
|
||||
chat-id]))}
|
||||
{:label (if muted (i18n/label :t/unmute-channel) (i18n/label :t/mute-channel))
|
||||
:customization-color color
|
||||
:icon (if muted :i/muted :i/activity-center)
|
||||
:on-press (fn []
|
||||
(if muted
|
||||
(home.actions/unmute-chat-action chat-id)
|
||||
(home.actions/mute-chat-action chat-id chat-type muted)))}]}]]]
|
||||
[members items color]])))
|
||||
[]
|
||||
(let [{:keys [chat-id community-id]} (rf/sub [:get-screen-params
|
||||
:screen/chat.view-channel-members-and-details])
|
||||
{:keys [description chat-name emoji muted chat-type color]
|
||||
:as chat} (rf/sub [:chats/chat-by-id chat-id])
|
||||
pins-count (rf/sub [:chats/pin-messages-count chat-id])
|
||||
items (rf/sub [:communities/sorted-community-members-section-list
|
||||
community-id chat-id])
|
||||
theme (quo.theme/use-theme)]
|
||||
(rn/use-mount (fn []
|
||||
(rf/dispatch [:pin-message/load-pin-messages chat-id])))
|
||||
[:<>
|
||||
(when (ff/enabled? ::ff/shell.jump-to)
|
||||
[quo/floating-shell-button
|
||||
{:jump-to {:on-press #(rf/dispatch [:shell/navigate-to-jump-to])
|
||||
:customization-color color
|
||||
:label (i18n/label :t/jump-to)}}
|
||||
style/floating-shell-button])
|
||||
[quo/gradient-cover {:customization-color color :opacity 0.4}]
|
||||
[quo/page-nav
|
||||
{:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:right-side [{:icon-name :i/options
|
||||
:on-press #(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [home.actions/chat-actions
|
||||
chat
|
||||
false
|
||||
true])}])}]}]
|
||||
[quo/text-combinations
|
||||
{:container-style style/text-combinations
|
||||
:title [quo/channel-name
|
||||
{:channel-name chat-name
|
||||
:unlocked? true}]
|
||||
:theme theme
|
||||
:emoji (when (not (string/blank? emoji)) (string/trim emoji))
|
||||
:customization-color color
|
||||
:title-accessibility-label :welcome-title
|
||||
:description description
|
||||
:description-accessibility-label :welcome-sub-title}]
|
||||
[rn/view {:style style/wrapper}
|
||||
[rn/view
|
||||
{:style style/channel-actions-wrapper}
|
||||
[quo/channel-actions
|
||||
{:actions
|
||||
[{:big? true
|
||||
:label (i18n/label :t/pinned-messages-2)
|
||||
:customization-color color
|
||||
:icon :i/pin
|
||||
:counter-value pins-count
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:dismiss-keyboard])
|
||||
(rf/dispatch [:pin-message/show-pins-bottom-sheet
|
||||
chat-id]))}
|
||||
{:label (if muted (i18n/label :t/unmute-channel) (i18n/label :t/mute-channel))
|
||||
:customization-color color
|
||||
:icon (if muted :i/muted :i/activity-center)
|
||||
:on-press (fn []
|
||||
(if muted
|
||||
(home.actions/unmute-chat-action chat-id)
|
||||
(home.actions/mute-chat-action chat-id chat-type muted)))}]}]]]
|
||||
[members items theme]]))
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
re-frame.db
|
||||
[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.not-implemented :as not-implemented]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.config :as config]
|
||||
@@ -25,6 +26,14 @@
|
||||
[:onboarding/navigate-to-sign-in-by-syncing]
|
||||
1000))
|
||||
|
||||
(defn- show-check-before-syncing
|
||||
[]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [check-before-syncing/view
|
||||
{:on-submit navigate-to-sign-in-by-syncing}])
|
||||
:shell? true}]))
|
||||
|
||||
(defn- navigate-to-sign-in-by-seed-phrase
|
||||
[create-profile?]
|
||||
(rf/dispatch [:onboarding/navigate-to-sign-in-by-seed-phrase
|
||||
@@ -62,7 +71,7 @@
|
||||
:accessibility-label :scan-sync-code-option-card
|
||||
:image (resources/get-image :generate-keys)
|
||||
:max-height (option-card-max-height window-height)
|
||||
:on-press navigate-to-sign-in-by-syncing}])
|
||||
:on-press show-check-before-syncing}])
|
||||
|
||||
(defn sign-in-options
|
||||
[sign-in-type]
|
||||
|
||||
@@ -38,14 +38,11 @@
|
||||
[rn/view {:style style/info-message}
|
||||
(when shown
|
||||
[quo/info-message
|
||||
{:type status
|
||||
:size :default
|
||||
:icon (if (= status :success) :i/positive-state :i/info)
|
||||
:text-color (when (= status :default)
|
||||
colors/white-70-blur)
|
||||
:icon-color (when (= status :default)
|
||||
colors/white-70-blur)
|
||||
:style {}}
|
||||
{:status status
|
||||
:size :default
|
||||
:icon (if (= status :success) :i/positive-state :i/info)
|
||||
:color (when (= status :default)
|
||||
colors/white-70-blur)}
|
||||
text])]])
|
||||
|
||||
(defn password-inputs
|
||||
|
||||
@@ -158,12 +158,11 @@
|
||||
:on-change-text on-change-text}}]]
|
||||
|
||||
[quo/info-message
|
||||
{:type info-type
|
||||
:size :default
|
||||
:icon (if valid-name? :i/positive-state :i/info)
|
||||
:text-color (when (= :default info-type) colors/white-70-blur)
|
||||
:icon-color (when (= :default info-type) colors/white-70-blur)
|
||||
:style style/info-message}
|
||||
{:status info-type
|
||||
:size :default
|
||||
:icon (if valid-name? :i/positive-state :i/info)
|
||||
:color (when (= :default info-type) colors/white-70-blur)
|
||||
:container-style style/info-message}
|
||||
info-message]
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im.contexts.preview.quo.buttons.slide-button
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
@@ -18,41 +17,36 @@
|
||||
:type :boolean}
|
||||
{:key :blur?
|
||||
:type :boolean}
|
||||
{:key :keep-at-end-after-slide?
|
||||
:type :boolean}
|
||||
(preview/customization-color-option {:key :color})])
|
||||
|
||||
(defn f-view
|
||||
[]
|
||||
(let [state (reagent/atom {:disabled? false
|
||||
:color :blue
|
||||
:size :size-48})
|
||||
color (reagent/cursor state [:color])
|
||||
blur? (reagent/cursor state [:blur?])
|
||||
complete? (reagent/atom false)]
|
||||
(let [state (reagent/atom {:disabled? false
|
||||
:color :blue
|
||||
:size :size-48
|
||||
:keep-at-end-after-slide? false})
|
||||
color (reagent/cursor state [:color])
|
||||
blur? (reagent/cursor state [:blur?])
|
||||
keep-at-end-after-slide? (reagent/cursor state [:keep-at-end-after-slide?])]
|
||||
(fn []
|
||||
(rn/use-effect (fn []
|
||||
(reset! complete? true)
|
||||
(js/setTimeout #(reset! complete? false) 50))
|
||||
[(:size @state)])
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:component-container-style (when-not @blur? (:align-items :center))
|
||||
:blur? @blur?
|
||||
:show-blur-background? true}
|
||||
(if (not @complete?)
|
||||
[quo/slide-button
|
||||
{:track-text "We gotta slide"
|
||||
:track-icon :face-id
|
||||
:customization-color @color
|
||||
:size (:size @state)
|
||||
:disabled? (:disabled? @state)
|
||||
:blur? @blur?
|
||||
:type (:type @state)
|
||||
:on-complete (fn [_]
|
||||
(js/setTimeout (fn [] (reset! complete? true))
|
||||
1000)
|
||||
(js/alert "I don't wanna slide anymore"))}]
|
||||
[quo/button {:on-press (fn [] (reset! complete? false))}
|
||||
"Try again"])])))
|
||||
[quo/slide-button
|
||||
{:track-text "We gotta slide"
|
||||
:track-icon :face-id
|
||||
:customization-color @color
|
||||
:size (:size @state)
|
||||
:disabled? (:disabled? @state)
|
||||
:blur? @blur?
|
||||
:type (:type @state)
|
||||
:on-complete (fn [reset-fn]
|
||||
(js/alert "Slide complete")
|
||||
(reset-fn @keep-at-end-after-slide?))}]])))
|
||||
|
||||
(defn view [] [:f> f-view])
|
||||
|
||||
@@ -1,28 +1,43 @@
|
||||
(ns status-im.contexts.preview.quo.info.info-message
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[react-native.core :as rn]
|
||||
[status-im.contexts.preview.quo.preview :as preview]))
|
||||
|
||||
(def descriptor
|
||||
[{:key :type
|
||||
[{:key :status
|
||||
:type :select
|
||||
:options [{:key :default}
|
||||
{:key :success}
|
||||
{:key :error}]}
|
||||
{:key :error}
|
||||
{:key :warning}]}
|
||||
{:key :size
|
||||
:type :select
|
||||
:options [{:key :default}
|
||||
{:key :tiny}]}
|
||||
{:key :blur?
|
||||
:type :boolean}
|
||||
{:key :icon
|
||||
:type :select
|
||||
:options [{:key :i/placeholder}
|
||||
{:key :i/info}]}
|
||||
{:key :message
|
||||
:type :text}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom {:type :default
|
||||
:size :default
|
||||
:icon :i/placeholder
|
||||
:message "This is a message"})]
|
||||
(fn []
|
||||
[preview/preview-container {:state state :descriptor descriptor}
|
||||
[quo/info-message @state (:message @state)]])))
|
||||
(let [[state set-state] (rn/use-state
|
||||
{:status :default
|
||||
:size :default
|
||||
:message "This is a message"
|
||||
:blur? false
|
||||
:icon :i/placeholder})
|
||||
blur? (:blur? state)]
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor
|
||||
:blur-dark-only? true
|
||||
:show-blur-background? blur?
|
||||
:blur? blur?
|
||||
:set-state set-state}
|
||||
[quo/info-message (dissoc state :message) (:message state)]]))
|
||||
|
||||
@@ -65,9 +65,9 @@
|
||||
:customization-color :blue}
|
||||
:header [rn/view
|
||||
[quo/info-message
|
||||
{:type :success
|
||||
:size :tiny
|
||||
:icon :i/placeholder}
|
||||
{:status :success
|
||||
:size :tiny
|
||||
:icon :i/placeholder}
|
||||
"info-message as title"]]
|
||||
:body [quo/snippet {:language :clojure :max-lines 15 :syntax true}
|
||||
snippet-preview/clojure-example]
|
||||
|
||||
@@ -55,7 +55,8 @@
|
||||
{:type :select
|
||||
:key :size
|
||||
:options [{:key :default}
|
||||
{:key :small}]}])
|
||||
{:key :small}
|
||||
{:key :large}]}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
|
||||
@@ -68,9 +68,9 @@
|
||||
:on-change-text on-nickname-change
|
||||
:on-submit-editing on-nickname-submit}]
|
||||
[quo/info-message
|
||||
{:icon :i/info
|
||||
:size :default
|
||||
:type (if-not (string/blank? error-msg) :error :default)}
|
||||
{:icon :i/info
|
||||
:size :default
|
||||
:status (if-not (string/blank? error-msg) :error :default)}
|
||||
(if-not (string/blank? error-msg)
|
||||
error-msg
|
||||
(i18n/label :t/nickname-visible-to-you))]]
|
||||
|
||||
@@ -58,9 +58,9 @@
|
||||
:on-change-text on-change-text}]
|
||||
(when-not (string/blank? error-msg)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
error-msg])]
|
||||
[rn/view {:style style/button-wrapper}
|
||||
[quo/button
|
||||
|
||||
@@ -58,9 +58,9 @@
|
||||
:on-change-text on-change-text}]
|
||||
(when-not (string/blank? @error-msg)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
@error-msg])]
|
||||
[rn/view {:style style/button-wrapper}
|
||||
[quo/button
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[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.standard-authentication.core :as standard-authentication]
|
||||
[status-im.config :as config]
|
||||
@@ -41,6 +42,17 @@
|
||||
:linear
|
||||
50))
|
||||
|
||||
(defn- show-check-before-syncing
|
||||
[]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn [] [check-before-syncing/view
|
||||
{:on-submit
|
||||
#(debounce/throttle-and-dispatch
|
||||
[:open-modal :screen/onboarding.sign-in]
|
||||
1000)}])
|
||||
:shell? true}]))
|
||||
|
||||
(defn new-account-options
|
||||
[]
|
||||
[quo/action-drawer
|
||||
@@ -55,9 +67,7 @@
|
||||
:accessibility-label :create-new-profile}
|
||||
{:icon :i/multi-profile
|
||||
:label (i18n/label :t/add-existing-status-profile)
|
||||
:on-press #(debounce/throttle-and-dispatch
|
||||
[:open-modal :screen/onboarding.sign-in]
|
||||
1000)
|
||||
:on-press show-check-before-syncing
|
||||
:accessibility-label :multi-profile}]]])
|
||||
|
||||
(defn show-new-account-options
|
||||
|
||||
@@ -61,7 +61,14 @@
|
||||
:image :icon
|
||||
:blur? true
|
||||
:action :arrow})]
|
||||
[{:title (i18n/label :t/syncing)
|
||||
[(when config/show-not-implemented-features?
|
||||
{:title (i18n/label :t/privacy-and-security)
|
||||
:on-press #(rf/dispatch [:open-modal :screen/settings-privacy-and-security])
|
||||
:image-props :i/privacy
|
||||
:image :icon
|
||||
:blur? true
|
||||
:action :arrow})
|
||||
{:title (i18n/label :t/syncing)
|
||||
:on-press #(rf/dispatch [:open-modal :settings-syncing])
|
||||
:image-props :i/syncing
|
||||
:image :icon
|
||||
|
||||
+3
-4
@@ -24,12 +24,11 @@
|
||||
[rn/view {:style style/info-message}
|
||||
(when shown?
|
||||
[quo/info-message
|
||||
(cond-> {:type status
|
||||
:size :default}
|
||||
(cond-> {:status status
|
||||
:size :default}
|
||||
(not= :success status) (assoc :icon :i/info)
|
||||
(= :success status) (assoc :icon :i/positive-state)
|
||||
(= :default status) (assoc :text-color colors/white-70-blur
|
||||
:icon-color colors/white-70-blur))
|
||||
(= :default status) (assoc :color colors/white-70-blur))
|
||||
text])]])
|
||||
|
||||
(defn- calc-password-strength
|
||||
|
||||
+3
-3
@@ -43,9 +43,9 @@
|
||||
{:style style/error-container}
|
||||
(when error
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
(i18n/label :t/oops-wrong-password)])]
|
||||
[quo/information-box
|
||||
{:type :error
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.contexts.profile.settings.visibility-sheet.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[status-im.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -17,6 +18,10 @@
|
||||
[:visibility-status-updates/visibility-status-update
|
||||
public-key])
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(rf/dispatch [:peer-stats/get-count])))
|
||||
|
||||
[quo/action-drawer
|
||||
[[{:icon :i/online
|
||||
:no-icon-color? true
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
(ns status-im.contexts.settings.privacy-and-security.style)
|
||||
|
||||
(def title-container
|
||||
{:flex 0
|
||||
:padding-horizontal 20
|
||||
:margin-vertical 12})
|
||||
|
||||
(defn page-wrapper
|
||||
[top-inset]
|
||||
{:padding-top top-inset
|
||||
:flex 1})
|
||||
@@ -0,0 +1,42 @@
|
||||
(ns status-im.contexts.settings.privacy-and-security.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.theme]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.contexts.settings.privacy-and-security.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn navigate-back
|
||||
[]
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [insets (safe-area/get-insets)
|
||||
customization-color (rf/sub [:profile/customization-color])]
|
||||
[quo/overlay
|
||||
{:type :shell
|
||||
:container-style (style/page-wrapper (:top insets))}
|
||||
[quo/page-nav
|
||||
{:key :header
|
||||
:background :blur
|
||||
:icon-name :i/arrow-left
|
||||
:on-press navigate-back}]
|
||||
[quo/standard-title
|
||||
{:title (i18n/label :t/privacy-and-security)
|
||||
:container-style style/title-container
|
||||
:accessibility-label :privacy-and-security-header
|
||||
:customization-color customization-color}]
|
||||
[quo/category
|
||||
{:key :category
|
||||
:data [{:title "Dummy"
|
||||
:image-props :i/placeholder
|
||||
:image :icon
|
||||
:blur? true
|
||||
:action :selector
|
||||
:action-props {:on-change identity
|
||||
:checked? false}
|
||||
:on-press identity}]
|
||||
:blur? true
|
||||
:list-type :settings}]]))
|
||||
@@ -92,7 +92,7 @@
|
||||
(rf/reg-event-fx :wallet/make-keypairs-accounts-fully-operable make-keypairs-accounts-fully-operable)
|
||||
|
||||
(defn connection-string-for-import-keypair
|
||||
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string on-success]}]]
|
||||
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string]}]]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:fx [[:effects.syncing/import-keypairs-keystores
|
||||
{:key-uid key-uid
|
||||
@@ -100,7 +100,6 @@
|
||||
:keypairs-key-uids keypairs-key-uids
|
||||
:connection-string connection-string
|
||||
:on-success (fn [key-uids]
|
||||
(rf/call-continuation on-success)
|
||||
(rf/dispatch [:wallet/make-keypairs-accounts-fully-operable key-uids]))
|
||||
:on-fail (fn [error]
|
||||
(log/error "failed to import missing key pairs with connection string"
|
||||
@@ -113,7 +112,7 @@
|
||||
(rf/reg-event-fx :wallet/connection-string-for-import-keypair connection-string-for-import-keypair)
|
||||
|
||||
(defn success-keypair-qr-scan
|
||||
[_ [connection-string keypairs-key-uids on-import-success]]
|
||||
[_ [connection-string keypairs-key-uids]]
|
||||
{:fx [[:dispatch
|
||||
[:standard-auth/authorize-with-password
|
||||
{:blur? true
|
||||
@@ -125,8 +124,7 @@
|
||||
[:wallet/connection-string-for-import-keypair
|
||||
{:connection-string connection-string
|
||||
:keypairs-key-uids keypairs-key-uids
|
||||
:sha3-pwd password
|
||||
:on-success on-import-success}]))}]]]})
|
||||
:sha3-pwd password}]))}]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/success-keypair-qr-scan success-keypair-qr-scan)
|
||||
|
||||
|
||||
+3
-3
@@ -128,9 +128,9 @@
|
||||
:default-value private-key}]
|
||||
(when flow-state
|
||||
[quo/info-message
|
||||
{:type (if (= flow-state :correct-private-key) :success :error)
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
{:status (if (= flow-state :correct-private-key) :success :error)
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
(case flow-state
|
||||
:correct-private-key (i18n/label :t/correct-private-key)
|
||||
:invalid-private-key (i18n/label :t/invalid-private-key)
|
||||
|
||||
+1
-3
@@ -13,14 +13,12 @@
|
||||
on-success-scan (rn/use-callback (fn [scanned-text]
|
||||
(rf/dispatch [:wallet/success-keypair-qr-scan
|
||||
scanned-text
|
||||
keypairs-key-uids
|
||||
[:navigate-back]])
|
||||
keypairs-key-uids])
|
||||
[keypairs-key-uids]))]
|
||||
[scan-qr-code/view
|
||||
{:title (i18n/label :t/scan-key-pairs-qr-code)
|
||||
:subtitle (i18n/label :t/find-it-in-setting)
|
||||
:share-button? false
|
||||
:import-keypair? true
|
||||
:validate-fn sync-utils/valid-connection-string?
|
||||
:error-message (i18n/label :t/invalid-key-pair-qr)
|
||||
:on-success-scan on-success-scan}]))
|
||||
|
||||
@@ -94,9 +94,8 @@
|
||||
:error? (not (string/blank? error-msg))}]
|
||||
(when-not (string/blank? error-msg)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:container-style style/error-container}
|
||||
error-msg])]]))
|
||||
|
||||
|
||||
+2
-2
@@ -85,8 +85,8 @@
|
||||
{:accessibility-label :error-message
|
||||
:size :default
|
||||
:icon :i/alert
|
||||
:type :error
|
||||
:style style/info-message}
|
||||
:status :error
|
||||
:container-style style/info-message}
|
||||
error-msg])))
|
||||
|
||||
(defn- existing-saved-address
|
||||
|
||||
@@ -23,15 +23,29 @@
|
||||
|
||||
(rf/reg-event-fx :wallet/save-address save-address)
|
||||
|
||||
(defn- update-saved-addresses
|
||||
[saved-addresses-db new-saved-addresses]
|
||||
(reduce
|
||||
(fn [acc {:keys [address removed? test?] :as saved-address}]
|
||||
(let [db-key (if test? :test :prod)]
|
||||
(if removed?
|
||||
(update acc db-key dissoc address)
|
||||
(assoc-in acc [db-key address] saved-address))))
|
||||
(or saved-addresses-db
|
||||
{:test {}
|
||||
:prod {}})
|
||||
new-saved-addresses))
|
||||
|
||||
(defn reconcile-saved-addresses
|
||||
[{:keys [db]} [saved-addresses]]
|
||||
{:db (update-in db [:wallet :saved-addresses] update-saved-addresses saved-addresses)})
|
||||
|
||||
(rf/reg-event-fx :wallet/reconcile-saved-addresses reconcile-saved-addresses)
|
||||
|
||||
(defn get-saved-addresses-success
|
||||
[{:keys [db]} [raw-saved-addresses]]
|
||||
(let [saved-addresses (reduce
|
||||
(fn [result {:keys [address test?] :as saved-address}]
|
||||
(assoc-in result [(if test? :test :prod) address] saved-address))
|
||||
{:test {}
|
||||
:prod {}}
|
||||
(data-store/rpc->saved-addresses raw-saved-addresses))]
|
||||
{:db (assoc-in db [:wallet :saved-addresses] saved-addresses)}))
|
||||
[_ [raw-saved-addresses]]
|
||||
(let [saved-addresses (data-store/rpc->saved-addresses raw-saved-addresses)]
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/get-saved-addresses-success get-saved-addresses-success)
|
||||
|
||||
@@ -52,15 +66,17 @@
|
||||
(rf/reg-event-fx :wallet/get-saved-addresses get-saved-addresses)
|
||||
|
||||
(defn delete-saved-address-success
|
||||
[_ [toast-message]]
|
||||
{:fx [[:dispatch [:wallet/get-saved-addresses]]
|
||||
[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]})
|
||||
[{:keys [db]} [{:keys [address test-networks-enabled? toast-message]}]]
|
||||
(let [db-key (if test-networks-enabled? :test :prod)
|
||||
saved-address (get-in db [:wallet :saved-addresses db-key address])]
|
||||
{:fx [[:dispatch [:wallet/reconcile-saved-addresses [(assoc saved-address :removed? true)]]]
|
||||
[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch-later
|
||||
{:ms 100
|
||||
:dispatch [:toasts/upsert
|
||||
{:type :positive
|
||||
:theme :dark
|
||||
:text toast-message}]}]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address-success delete-saved-address-success)
|
||||
|
||||
@@ -82,7 +98,10 @@
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_deleteSavedAddress"
|
||||
:params [address test-networks-enabled?]
|
||||
:on-success [:wallet/delete-saved-address-success toast-message]
|
||||
:on-success [:wallet/delete-saved-address-success
|
||||
{:address address
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:toast-message toast-message}]
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/delete-saved-address delete-saved-address)
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.contexts.settings.wallet.saved-addresses.events :as events]))
|
||||
[status-im.contexts.settings.wallet.saved-addresses.events :as events]
|
||||
[status-im.contexts.wallet.data-store :as data-store]))
|
||||
|
||||
(deftest get-saved-addresses-test
|
||||
(testing "get saved addresses - dispatches RPC call"
|
||||
@@ -15,7 +16,7 @@
|
||||
:on-error [:wallet/saved-addresses-rpc-error :get-saved-addresses]}]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
(def saved-address-1
|
||||
(def saved-address-rpc-1
|
||||
{:isTest false
|
||||
:address "0x1"
|
||||
:mixedcaseAddress "0x1"
|
||||
@@ -26,21 +27,45 @@
|
||||
:colorId "purple"
|
||||
:removed false})
|
||||
|
||||
(def saved-address-1
|
||||
{:test? true
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:oeth:"
|
||||
:network-preferences-names `(:mainnet :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
:ens? false
|
||||
:customization-color :blue
|
||||
:removed? false})
|
||||
|
||||
(def saved-address-2
|
||||
{:isTest true
|
||||
:address "0x2"
|
||||
:mixedcaseAddress "0x2"
|
||||
:chainShortNames "eth:arb1:oeth:"
|
||||
:name "Bob"
|
||||
:createdAt 1716826714
|
||||
:ens ""
|
||||
:colorId "blue"
|
||||
:removed false})
|
||||
{:test? false
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:name "Alicia Keys"
|
||||
:created-at 1716826806
|
||||
:ens "alicia.eth"
|
||||
:ens? true
|
||||
:customization-color :purple
|
||||
:removed? false})
|
||||
|
||||
(deftest get-saved-addresses-success-test
|
||||
(let [cofx {:db {}}
|
||||
raw-saved-addresses [saved-address-rpc-1]
|
||||
effects (events/get-saved-addresses-success cofx [raw-saved-addresses])
|
||||
saved-addresses (data-store/rpc->saved-addresses raw-saved-addresses)
|
||||
result-fx (:fx effects)
|
||||
expected-fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]]
|
||||
(is (match? expected-fx result-fx))))
|
||||
|
||||
(deftest reconcile-saved-addresses-test
|
||||
(testing "no saved addresses"
|
||||
(let [cofx {:db {}}
|
||||
effects (events/get-saved-addresses-success cofx nil)
|
||||
effects (events/reconcile-saved-addresses cofx nil)
|
||||
result-db (:db effects)
|
||||
expected-db {:wallet {:saved-addresses {:test {}
|
||||
:prod {}}}}]
|
||||
@@ -48,15 +73,15 @@
|
||||
|
||||
(testing "one test saved address"
|
||||
(let [cofx {:db {}}
|
||||
effects (events/get-saved-addresses-success cofx [[saved-address-2]])
|
||||
effects (events/reconcile-saved-addresses cofx [[saved-address-1]])
|
||||
result-db (:db effects)
|
||||
expected-db {:wallet {:saved-addresses
|
||||
{:test {"0x2" {:test? true
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
{:test {"0x1" {:test? true
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:oeth:"
|
||||
:ens? false
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:network-preferences-names `(:mainnet :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
@@ -67,29 +92,73 @@
|
||||
|
||||
(testing "two saved addresses (test and prod)"
|
||||
(let [cofx {:db {}}
|
||||
effects (events/get-saved-addresses-success cofx [[saved-address-1 saved-address-2]])
|
||||
effects (events/reconcile-saved-addresses cofx [[saved-address-1 saved-address-2]])
|
||||
result-db (:db effects)
|
||||
expected-db {:wallet {:saved-addresses
|
||||
{:test {"0x2" {:test? true
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
{:test {"0x1" {:test? true
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:oeth:"
|
||||
:ens? false
|
||||
:network-preferences-names `(:mainnet :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
:customization-color :blue
|
||||
:removed? false}}
|
||||
:prod {"0x1" {:test? false
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:prod {"0x2" {:test? false
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:ens? false
|
||||
:name "Amy"
|
||||
:ens? true
|
||||
:name "Alicia Keys"
|
||||
:created-at 1716826806
|
||||
:ens ""
|
||||
:ens "alicia.eth"
|
||||
:customization-color :purple
|
||||
:removed? false}}}}}]
|
||||
(is (match? expected-db result-db))))
|
||||
|
||||
(testing "remove a test saved addresses"
|
||||
(let [cofx {:db {:wallet {:saved-addresses
|
||||
{:test {"0x1" {:test? true
|
||||
:address "0x1"
|
||||
:mixedcase-address "0x1"
|
||||
:chain-short-names "eth:oeth:"
|
||||
:ens? false
|
||||
:network-preferences-names `(:mainnet :optimism)
|
||||
:name "Bob"
|
||||
:created-at 1716826714
|
||||
:ens ""
|
||||
:customization-color :blue
|
||||
:removed? false}}
|
||||
:prod {"0x2" {:test? false
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum
|
||||
:optimism)
|
||||
:ens? true
|
||||
:name "Alicia Keys"
|
||||
:created-at 1716826806
|
||||
:ens "alicia.eth"
|
||||
:customization-color :purple
|
||||
:removed? false}}}}}}
|
||||
effects (events/reconcile-saved-addresses cofx
|
||||
[[(assoc saved-address-1 :removed? true)
|
||||
saved-address-2]])
|
||||
result-db (:db effects)
|
||||
expected-db {:wallet {:saved-addresses
|
||||
{:test {}
|
||||
:prod {"0x2" {:test? false
|
||||
:address "0x2"
|
||||
:mixedcase-address "0x2"
|
||||
:chain-short-names "eth:arb1:oeth:"
|
||||
:network-preferences-names `(:mainnet :arbitrum :optimism)
|
||||
:ens? true
|
||||
:name "Alicia Keys"
|
||||
:created-at 1716826806
|
||||
:ens "alicia.eth"
|
||||
:customization-color :purple
|
||||
:removed? false}}}}}]
|
||||
(is (match? expected-db result-db)))))
|
||||
@@ -141,7 +210,10 @@
|
||||
expected-fx [[:json-rpc/call
|
||||
[{:method "wakuext_deleteSavedAddress"
|
||||
:params [address test-networks-enabled?]
|
||||
:on-success [:wallet/delete-saved-address-success toast-message]
|
||||
:on-success [:wallet/delete-saved-address-success
|
||||
{:address address
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:toast-message toast-message}]
|
||||
:on-error [:wallet/delete-saved-address-failed]}]]]]
|
||||
(is (match? expected-fx result-fx)))))
|
||||
|
||||
|
||||
+1
-1
@@ -109,7 +109,7 @@
|
||||
:on-press open-show-address-qr
|
||||
:accessibility-label :show-address-qr-code}
|
||||
{:icon :i/edit
|
||||
:label (i18n/label :t/edit-account)
|
||||
:label (i18n/label :t/edit-details)
|
||||
:blur? true
|
||||
:on-press open-edit-saved-address
|
||||
:accessibility-label :edit-saved-address}
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.check-before-syncing.view :as check-before-syncing]
|
||||
[status-im.contexts.syncing.device.view :as device]
|
||||
[status-im.contexts.syncing.syncing-devices-list.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -13,19 +14,31 @@
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn open-setup-syncing
|
||||
[]
|
||||
(rf/dispatch [:open-modal :settings-setup-syncing]))
|
||||
[customization-color]
|
||||
(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:theme :dark
|
||||
:shell? true
|
||||
:content
|
||||
(fn [] [check-before-syncing/view
|
||||
{:customization-color customization-color
|
||||
:on-submit #(rf/dispatch [:open-modal :settings-setup-syncing])}])}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [devices (rf/sub [:pairing/installations])
|
||||
devices-with-button (map #(assoc % :show-button? true) devices)
|
||||
user-device (first devices-with-button)
|
||||
other-devices (rest devices-with-button)
|
||||
profile-color (rf/sub [:profile/customization-color])
|
||||
{:keys [paired-devices unpaired-devices]} (group-by
|
||||
#(if (:enabled? %) :paired-devices :unpaired-devices)
|
||||
other-devices)]
|
||||
(let [devices (rf/sub [:pairing/installations])
|
||||
devices-with-button (map #(assoc % :show-button? true) devices)
|
||||
user-device (first devices-with-button)
|
||||
other-devices (rest devices-with-button)
|
||||
profile-color (rf/sub [:profile/customization-color])
|
||||
open-setup-syncing-with-customization-color (rn/use-callback (partial open-setup-syncing
|
||||
profile-color)
|
||||
[profile-color])
|
||||
{:keys [paired-devices unpaired-devices]} (group-by
|
||||
#(if (:enabled? %)
|
||||
:paired-devices
|
||||
:unpaired-devices)
|
||||
other-devices)]
|
||||
[quo/overlay {:type :shell :top-inset? true}
|
||||
[quo/page-nav
|
||||
{:type :no-title
|
||||
@@ -47,7 +60,7 @@
|
||||
:type :primary
|
||||
:customization-color profile-color
|
||||
:icon-only? true
|
||||
:on-press open-setup-syncing}
|
||||
:on-press open-setup-syncing-with-customization-color}
|
||||
:i/add]]
|
||||
[device/view (merge user-device {:this-device? true})]
|
||||
(when (seq paired-devices)
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- on-collectible-press
|
||||
[{:keys [id]}]
|
||||
(rf/dispatch [:wallet/get-collectible-details id]))
|
||||
[{:keys [id]} aspect-ratio]
|
||||
(rf/dispatch [:wallet/get-collectible-details id aspect-ratio]))
|
||||
|
||||
(defn- on-collectible-long-press
|
||||
[{:keys [preview-url collectible-details id]}]
|
||||
|
||||
@@ -103,8 +103,8 @@
|
||||
(when activity-state
|
||||
[quo/info-message
|
||||
(assoc props
|
||||
:style style/info-message
|
||||
:size :default)
|
||||
:container-style style/info-message
|
||||
:size :default)
|
||||
(i18n/label message)])))
|
||||
|
||||
(defn view
|
||||
@@ -163,7 +163,7 @@
|
||||
{:accessibility-label :error-message
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:type :error
|
||||
:style style/info-message}
|
||||
:status :error
|
||||
:container-style style/info-message}
|
||||
@validation-msg]
|
||||
[activity-indicator activity-state])]]))))
|
||||
[activity-indicator])]]))))
|
||||
|
||||
+6
-6
@@ -117,12 +117,12 @@
|
||||
{:weight :monospace}
|
||||
(:address derivation-path)]]
|
||||
[quo/info-message
|
||||
{:type (case state
|
||||
:has-activity :success
|
||||
:no-activity :warning
|
||||
:default)
|
||||
:icon (if (= state :scanning) :i/scanning :i/done)
|
||||
:style style/info}
|
||||
{:status (case state
|
||||
:has-activity :success
|
||||
:no-activity :warning
|
||||
:default)
|
||||
:icon (if (= state :scanning) :i/scanning :i/done)
|
||||
:style style/info}
|
||||
(i18n/label (case state
|
||||
:has-activity :t/address-activity
|
||||
:no-activity :t/address-no-activity
|
||||
|
||||
@@ -91,7 +91,7 @@
|
||||
:error error}]
|
||||
(when error
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:container-style style/error-container}
|
||||
|
||||
@@ -87,7 +87,7 @@
|
||||
:container-style (style/title-input-container error)}]
|
||||
(when error
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:container-style {:margin-left 20
|
||||
|
||||
@@ -167,12 +167,13 @@
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-collectible-details
|
||||
(fn [_ [collectible-id]]
|
||||
(fn [{:keys [db]} [collectible-id aspect-ratio]]
|
||||
(let [request-id 0
|
||||
collectible-id-converted (cske/transform-keys transforms/->PascalCaseKeyword collectible-id)
|
||||
data-type (collectible-data-types :details)
|
||||
request-params [request-id [collectible-id-converted] data-type]]
|
||||
{:fx [[:json-rpc/call
|
||||
{:db (assoc-in db [:wallet :last-collectible-aspect-ratio] aspect-ratio)
|
||||
:fx [[:json-rpc/call
|
||||
[{:method "wallet_getCollectiblesByUniqueIDAsync"
|
||||
:params request-params
|
||||
:on-error (fn [error]
|
||||
@@ -197,7 +198,7 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/clear-last-collectible-details
|
||||
(fn [{:keys [db]}]
|
||||
{:db (update-in db [:wallet] dissoc :last-collectible-details)}))
|
||||
{:db (update-in db [:wallet] dissoc :last-collectible-details :last-collectible-aspect-ratio)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/trigger-share-collectible
|
||||
(fn [_ [{:keys [title uri]}]]
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
|
||||
(defn preview-container
|
||||
[]
|
||||
{:margin-horizontal 8
|
||||
:margin-top (+ (header-height) 12)})
|
||||
{:padding-horizontal 8
|
||||
:margin-top (+ (header-height) 12)})
|
||||
|
||||
(def header
|
||||
{:margin-horizontal 20
|
||||
|
||||
@@ -150,6 +150,7 @@
|
||||
set-title-ref (rn/use-callback #(reset! title-ref %))
|
||||
animation-shared-element-id (rf/sub [:animation-shared-element-id])
|
||||
collectible-owner (rf/sub [:wallet/last-collectible-details-owner])
|
||||
aspect-ratio (rf/sub [:wallet/last-collectible-aspect-ratio])
|
||||
{:keys [id
|
||||
preview-url
|
||||
collection-data
|
||||
@@ -180,7 +181,8 @@
|
||||
[rn/view
|
||||
[gradient-layer preview-uri]
|
||||
[quo/expanded-collectible
|
||||
{:image-src preview-uri
|
||||
{:aspect-ratio aspect-ratio
|
||||
:image-src preview-uri
|
||||
:container-style (style/preview-container)
|
||||
:counter (utils/collectible-owned-counter total-owned)
|
||||
:native-ID (when (= animation-shared-element-id token-id) :shared-element)
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
[status-im.contexts.wallet.sheets.account-options.view :as account-options]
|
||||
[status-im.contexts.wallet.sheets.network-filter.view :as network-filter]
|
||||
[status-im.contexts.wallet.sheets.select-account.view :as select-account]
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn get-bottom-sheet-args
|
||||
@@ -36,7 +37,7 @@
|
||||
:networks networks
|
||||
:align-center? true
|
||||
:networks-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}])
|
||||
:right-side [(when (and true
|
||||
:right-side [(when (and (ff/enabled? ::wallet.wallet-connect)
|
||||
(not watch-only?))
|
||||
{:icon-name :i/dapps
|
||||
:on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])})
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
:as collectible}
|
||||
index]
|
||||
(let [on-press-fn (rn/use-callback #(when on-press
|
||||
(on-press collectible)))
|
||||
(on-press collectible %)))
|
||||
on-long-press-fn (rn/use-callback #(when on-long-press
|
||||
(on-long-press collectible)))]
|
||||
[quo/collectible-list-item
|
||||
|
||||
@@ -62,7 +62,7 @@
|
||||
:container-style (style/title-input-container error)}]
|
||||
(when error
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
{:status :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:container-style {:margin-left 20
|
||||
|
||||
@@ -177,7 +177,7 @@
|
||||
"This function returns token values in the props of token-value (quo) component"
|
||||
[{:keys [token color currency currency-symbol]}]
|
||||
(let [balance (calculate-total-token-balance token)
|
||||
fiat-value (calculate-token-fiat-value
|
||||
fiat-unformatted-value (calculate-token-fiat-value
|
||||
{:currency currency
|
||||
:balance balance
|
||||
:token token})
|
||||
@@ -191,7 +191,7 @@
|
||||
crypto-value (get-standard-crypto-format token balance)
|
||||
fiat-value (get-standard-fiat-format crypto-value
|
||||
currency-symbol
|
||||
fiat-value)]
|
||||
fiat-unformatted-value)]
|
||||
{:token (:symbol token)
|
||||
:token-name (:name token)
|
||||
:state :default
|
||||
@@ -201,10 +201,11 @@
|
||||
(neg? change-pct-24hour) :negative
|
||||
:else :empty)
|
||||
:customization-color color
|
||||
:values {:crypto-value crypto-value
|
||||
:fiat-value fiat-value
|
||||
:fiat-change formatted-token-price
|
||||
:percentage-change percentage-change}}))
|
||||
:values {:crypto-value crypto-value
|
||||
:fiat-value fiat-value
|
||||
:fiat-unformatted-value fiat-unformatted-value
|
||||
:fiat-change formatted-token-price
|
||||
:percentage-change percentage-change}}))
|
||||
|
||||
(defn get-multichain-address
|
||||
[networks address]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils.networks :as network-utils]
|
||||
[utils.collection :as utils.collection]
|
||||
[utils.money :as money]
|
||||
[utils.number :as utils.number]
|
||||
[utils.transforms :as transforms]))
|
||||
@@ -154,9 +155,35 @@
|
||||
:colorId :customization-color
|
||||
:mixedcaseAddress :mixedcase-address
|
||||
:removed :removed?})
|
||||
(update :customization-color keyword)
|
||||
(update :customization-color (comp keyword string/lower-case))
|
||||
add-keys-to-saved-address))
|
||||
|
||||
(defn rpc->saved-addresses
|
||||
[saved-addresses]
|
||||
(map rpc->saved-address saved-addresses))
|
||||
|
||||
(defn reconcile-keypairs
|
||||
[keypairs]
|
||||
(let [received-keypairs (rpc->keypairs keypairs)
|
||||
keypair-label #(if % :removed-keypairs :updated-keypairs)
|
||||
{:keys [removed-keypairs
|
||||
updated-keypairs]
|
||||
:or {updated-keypairs []
|
||||
removed-keypairs []}} (group-by (comp keypair-label :removed) received-keypairs)
|
||||
updated-keypairs-by-id (utils.collection/index-by :key-uid updated-keypairs)
|
||||
updated-accounts-by-address (transduce (comp (mapcat :accounts)
|
||||
(filter (comp not :chat))
|
||||
(map #(vector (:address %) %)))
|
||||
conj
|
||||
{}
|
||||
updated-keypairs)
|
||||
removed-keypairs-ids (set (map :key-uid removed-keypairs))
|
||||
removed-account-addresses (transduce (comp (mapcat :accounts)
|
||||
(map :address))
|
||||
conj
|
||||
#{}
|
||||
removed-keypairs)]
|
||||
{:removed-keypair-ids removed-keypairs-ids
|
||||
:removed-account-addresses removed-account-addresses
|
||||
:updated-keypairs-by-id updated-keypairs-by-id
|
||||
:updated-accounts-by-address updated-accounts-by-address}))
|
||||
|
||||
@@ -0,0 +1,240 @@
|
||||
(ns status-im.contexts.wallet.data-store-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [deftest is testing]]
|
||||
[matcher-combinators.matchers :as matchers]
|
||||
matcher-combinators.test
|
||||
[status-im.contexts.wallet.data-store :as sut]))
|
||||
|
||||
(def raw-account
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:name "Account name"
|
||||
:wallet true
|
||||
:chat false
|
||||
:emoji "🍙"
|
||||
:colorId "blue"
|
||||
:type "generated"
|
||||
:createdAt 1716548742000
|
||||
:prodPreferredChainIds "1:42161"
|
||||
:testPreferredChainIds "11155111:421614"
|
||||
:removed false
|
||||
:operable "fully"})
|
||||
|
||||
(def account
|
||||
{:path "m/44'/60'/0'/0/0"
|
||||
:emoji "🍙"
|
||||
:color :blue
|
||||
:wallet true
|
||||
:default-account? true
|
||||
:name "Account name"
|
||||
:type :generated
|
||||
:chat false
|
||||
:test-preferred-chain-ids #{11155111 421614}
|
||||
:watch-only? false
|
||||
:prod-preferred-chain-ids #{1 42161}
|
||||
:created-at 1716548742000
|
||||
:operable :fully
|
||||
:removed false})
|
||||
|
||||
(defn make-raw-account
|
||||
[overrides]
|
||||
(merge raw-account overrides))
|
||||
|
||||
(def raw-keypair-profile
|
||||
{:type "profile"
|
||||
:key-uid "0x000"
|
||||
:accounts [(make-raw-account {:key-uid "0x000"
|
||||
:address "1x000"
|
||||
:wallet false
|
||||
:chat true})
|
||||
(make-raw-account {:key-uid "0x000"
|
||||
:address "2x000"})]})
|
||||
|
||||
(def raw-keypair-seed-phrase
|
||||
{:type "seed"
|
||||
:key-uid "0x123"
|
||||
:accounts [(make-raw-account {:key-uid "0x123"
|
||||
:address "1x123"})]})
|
||||
|
||||
(def raw-keypair-private-key
|
||||
{:type "key"
|
||||
:key-uid "0x456"
|
||||
:accounts [(make-raw-account {:key-uid "0x456"
|
||||
:address "1x456"
|
||||
:operable "no"})]})
|
||||
|
||||
(deftest chain-ids-string->set-test
|
||||
(testing "chaind-ids-string->set splits and parses chain-ids from string"
|
||||
(is (match? #{1 42161}
|
||||
(sut/chain-ids-string->set (:prodPreferredChainIds raw-account))))
|
||||
(is (match? #{11155111 421614}
|
||||
(sut/chain-ids-string->set (:testPreferredChainIds raw-account))))))
|
||||
|
||||
(deftest rpc->keypair-test
|
||||
(testing "rpc->keypair transforms a profile keypair"
|
||||
(is
|
||||
(match? {:type :profile
|
||||
:key-uid "0x000"
|
||||
:lowest-operability :fully
|
||||
:accounts [{:key-uid "0x000"
|
||||
:operable :fully
|
||||
:chat true
|
||||
:wallet false
|
||||
:address "1x000"
|
||||
:path (:path raw-account)
|
||||
:name (:name raw-account)
|
||||
:emoji (:emoji raw-account)
|
||||
:removed (:removed raw-account)
|
||||
:color (keyword (:colorId raw-account))
|
||||
:created-at (:createdAt raw-account)
|
||||
:prod-preferred-chain-ids (sut/chain-ids-string->set
|
||||
(:prodPreferredChainIds raw-account))
|
||||
:test-preferred-chain-ids (sut/chain-ids-string->set
|
||||
(:testPreferredChainIds raw-account))}
|
||||
{:key-uid "0x000"
|
||||
:operable :fully
|
||||
:chat false
|
||||
:wallet true
|
||||
:address "2x000"
|
||||
:path (:path raw-account)
|
||||
:name (:name raw-account)
|
||||
:emoji (:emoji raw-account)
|
||||
:removed (:removed raw-account)
|
||||
:color (keyword (:colorId raw-account))
|
||||
:created-at (:createdAt raw-account)
|
||||
:prod-preferred-chain-ids (sut/chain-ids-string->set
|
||||
(:prodPreferredChainIds raw-account))
|
||||
:test-preferred-chain-ids (sut/chain-ids-string->set
|
||||
(:testPreferredChainIds raw-account))}]}
|
||||
(sut/rpc->keypair raw-keypair-profile))))
|
||||
(testing "rpc->keypair transforms a seed-phrase keypair"
|
||||
(is
|
||||
(match? {:type :seed
|
||||
:key-uid "0x123"
|
||||
:lowest-operability :fully
|
||||
:accounts [{:key-uid "0x123"
|
||||
:address "1x123"
|
||||
:operable :fully
|
||||
:path (:path raw-account)
|
||||
:name (:name raw-account)
|
||||
:emoji (:emoji raw-account)
|
||||
:wallet (:wallet raw-account)
|
||||
:removed (:removed raw-account)
|
||||
:color (keyword (:colorId raw-account))
|
||||
:created-at (:createdAt raw-account)
|
||||
:prod-preferred-chain-ids (sut/chain-ids-string->set
|
||||
(:prodPreferredChainIds raw-account))
|
||||
:test-preferred-chain-ids (sut/chain-ids-string->set
|
||||
(:testPreferredChainIds raw-account))}]}
|
||||
(sut/rpc->keypair raw-keypair-seed-phrase))))
|
||||
(testing "rpc->keypair transforms a raw private-key keypair with inoperable accounts"
|
||||
(is
|
||||
(match? {:type :key
|
||||
:key-uid "0x456"
|
||||
:lowest-operability :no
|
||||
:accounts [{:key-uid "0x456"
|
||||
:address "1x456"
|
||||
:operable :no
|
||||
:path (:path raw-account)
|
||||
:name (:name raw-account)
|
||||
:emoji (:emoji raw-account)
|
||||
:wallet (:wallet raw-account)
|
||||
:removed (:removed raw-account)
|
||||
:color (keyword (:colorId raw-account))
|
||||
:created-at (:createdAt raw-account)
|
||||
:prod-preferred-chain-ids (sut/chain-ids-string->set
|
||||
(:prodPreferredChainIds raw-account))
|
||||
:test-preferred-chain-ids (sut/chain-ids-string->set
|
||||
(:testPreferredChainIds
|
||||
raw-account))}]}
|
||||
(sut/rpc->keypair raw-keypair-private-key)))))
|
||||
|
||||
(deftest rpc->keypairs-test
|
||||
(testing "rpc->keypairs transforms and sorts raw keypairs"
|
||||
(is
|
||||
(match? [(sut/rpc->keypair raw-keypair-profile)
|
||||
(sut/rpc->keypair raw-keypair-seed-phrase)
|
||||
(sut/rpc->keypair raw-keypair-private-key)]
|
||||
(sut/rpc->keypairs [raw-keypair-seed-phrase
|
||||
raw-keypair-private-key
|
||||
raw-keypair-profile])))))
|
||||
|
||||
(deftest reconcile-keypairs-test
|
||||
(testing "reconcile-keypairs represents updated key pairs and accounts"
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
map? matchers/equals]
|
||||
{:removed-keypair-ids #{}
|
||||
:removed-account-addresses #{}
|
||||
:updated-accounts-by-address {"1x123" (merge account
|
||||
{:key-uid "0x123"
|
||||
:address "1x123"})
|
||||
"1x456" (merge account
|
||||
{:key-uid "0x456"
|
||||
:address "1x456"
|
||||
:operable :no})}
|
||||
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts [(merge account
|
||||
{:key-uid "0x123"
|
||||
:address "1x123"})]}
|
||||
"0x456" {:key-uid "0x456"
|
||||
:type :key
|
||||
:lowest-operability :no
|
||||
:accounts [(merge account
|
||||
{:key-uid "0x456"
|
||||
:address "1x456"
|
||||
:operable :no})]}}})
|
||||
(sut/reconcile-keypairs [raw-keypair-seed-phrase
|
||||
raw-keypair-private-key]))))
|
||||
(testing "reconcile-keypairs represents removed key pairs and accounts"
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
map? matchers/equals]
|
||||
{:removed-keypair-ids #{"0x456"}
|
||||
:removed-account-addresses #{"1x456"}
|
||||
:updated-accounts-by-address {"1x123" (merge account
|
||||
{:key-uid "0x123"
|
||||
:address "1x123"})}
|
||||
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts [(merge account
|
||||
{:key-uid "0x123"
|
||||
:address "1x123"})]}}})
|
||||
(sut/reconcile-keypairs [raw-keypair-seed-phrase
|
||||
(assoc raw-keypair-private-key :removed true)]))))
|
||||
(testing "reconcile-keypairs ignores chat accounts inside updated accounts"
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
map? matchers/equals]
|
||||
{:removed-keypair-ids #{}
|
||||
:removed-account-addresses #{}
|
||||
:updated-accounts-by-address {"2x000" (merge account
|
||||
{:key-uid "0x000"
|
||||
:address "2x000"
|
||||
:chat false
|
||||
:wallet true
|
||||
:default-account? true})}
|
||||
:updated-keypairs-by-id {"0x000" {:key-uid "0x000"
|
||||
:type :profile
|
||||
:lowest-operability :fully
|
||||
:accounts [(merge account
|
||||
{:key-uid "0x000"
|
||||
:address "1x000"
|
||||
:chat true
|
||||
:wallet false
|
||||
:default-account? false})
|
||||
(merge account
|
||||
{:key-uid "0x000"
|
||||
:address "2x000"
|
||||
:chat false
|
||||
:wallet true
|
||||
:default-account? true})]}}})
|
||||
(sut/reconcile-keypairs [raw-keypair-profile])))))
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im.contexts.wallet.events
|
||||
(:require
|
||||
[camel-snake-kebab.extras :as cske]
|
||||
[clojure.set]
|
||||
[clojure.string :as string]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.constants :as constants]
|
||||
@@ -81,6 +82,11 @@
|
||||
|
||||
(rf/reg-event-fx :wallet/log-rpc-error log-rpc-error)
|
||||
|
||||
(def refresh-accounts-fx-dispatches
|
||||
[[:dispatch [:wallet/get-wallet-token-for-all-accounts]]
|
||||
[:dispatch [:wallet/request-collectibles-for-all-accounts {:new-request? true}]]
|
||||
[:dispatch [:wallet/check-recent-history-for-all-accounts]]])
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-accounts-success
|
||||
(fn [{:keys [db]} [accounts]]
|
||||
@@ -91,11 +97,9 @@
|
||||
{:db (assoc-in db
|
||||
[:wallet :accounts]
|
||||
(utils.collection/index-by :address wallet-accounts))
|
||||
:fx [[:dispatch [:wallet/get-wallet-token-for-all-accounts]]
|
||||
[:dispatch [:wallet/request-collectibles-for-all-accounts {:new-request? true}]]
|
||||
[:dispatch [:wallet/check-recent-history-for-all-accounts]]
|
||||
(when new-account?
|
||||
[:dispatch [:wallet/navigate-to-new-account navigate-to-account]])]})))
|
||||
:fx (concat refresh-accounts-fx-dispatches
|
||||
[(when new-account?
|
||||
[:dispatch [:wallet/navigate-to-new-account navigate-to-account]])])})))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/get-accounts
|
||||
@@ -309,7 +313,7 @@
|
||||
[]
|
||||
(filter #(string/starts-with? (or (:ens-name %) "") input) contacts))]
|
||||
(if (and input (empty? result))
|
||||
(rf/dispatch [:wallet/search-ens input on-error-fn ".stateofus.eth"])
|
||||
{:fx [[:dispatch [:wallet/search-ens input on-error-fn ".stateofus.eth"]]]}
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :search-address :local-suggestions]
|
||||
(map #(assoc % :type item-types/saved-address) result))
|
||||
@@ -358,11 +362,15 @@
|
||||
|
||||
(rf/reg-event-fx :wallet/address-validation-success
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:wallet :ui :search-address :valid-ens-or-address?] true)}))
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :search-address :valid-ens-or-address?] true)
|
||||
(assoc-in [:wallet :ui :search-address :loading?] false))}))
|
||||
|
||||
(rf/reg-event-fx :wallet/address-validation-failed
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:wallet :ui :search-address :valid-ens-or-address?] false)}))
|
||||
{:db (-> db
|
||||
(assoc-in [:wallet :ui :search-address :valid-ens-or-address?] false)
|
||||
(assoc-in [:wallet :ui :search-address :loading?] false))}))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-local-suggestions
|
||||
(fn [{:keys [db]}]
|
||||
@@ -370,6 +378,10 @@
|
||||
(assoc-in [:wallet :ui :search-address :local-suggestions] [])
|
||||
(assoc-in [:wallet :ui :search-address :valid-ens-or-address?] false))}))
|
||||
|
||||
(rf/reg-event-fx :wallet/searching-address
|
||||
(fn [{:keys [db]}]
|
||||
{:db (assoc-in db [:wallet :ui :search-address :loading?] true)}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/navigate-to-chain-explorer-from-bottom-sheet
|
||||
(fn [_ [explorer-link address]]
|
||||
@@ -545,3 +557,73 @@
|
||||
:wallet/process-watch-only-account-from-backup
|
||||
(fn [_ [{:keys [backedUpWatchOnlyAccount]}]]
|
||||
{:fx [[:dispatch [:wallet/process-account-from-signal backedUpWatchOnlyAccount]]]}))
|
||||
|
||||
(defn reconcile-watch-only-accounts
|
||||
[{:keys [db]} [watch-only-accounts]]
|
||||
(let [existing-accounts-by-address (get-in db [:wallet :accounts])
|
||||
group-label #(if % :removed-accounts :updated-accounts)
|
||||
{:keys [removed-accounts
|
||||
updated-accounts]} (->> watch-only-accounts
|
||||
(map data-store/rpc->account)
|
||||
(group-by (comp group-label :removed)))
|
||||
existing-account-addresses (set (keys existing-accounts-by-address))
|
||||
removed-account-addresses (set (map :address removed-accounts))
|
||||
updated-account-addresses (set (map :address updated-accounts))
|
||||
new-account-addresses (clojure.set/difference updated-account-addresses
|
||||
existing-account-addresses)]
|
||||
{:db (update-in db
|
||||
[:wallet :accounts]
|
||||
(fn [existing-accounts]
|
||||
(merge-with merge
|
||||
(apply dissoc existing-accounts removed-account-addresses)
|
||||
(utils.collection/index-by :address updated-accounts))))
|
||||
:fx (mapcat (fn [address]
|
||||
[[:dispatch [:wallet/get-wallet-token-for-account address]]
|
||||
[:dispatch
|
||||
[:wallet/request-new-collectibles-for-account-from-signal address]]
|
||||
[:dispatch [:wallet/check-recent-history-for-account address]]])
|
||||
new-account-addresses)}))
|
||||
|
||||
(rf/reg-event-fx :wallet/reconcile-watch-only-accounts reconcile-watch-only-accounts)
|
||||
|
||||
(defn reconcile-keypairs
|
||||
[{:keys [db]} [keypairs]]
|
||||
(let [existing-keypairs-by-id (get-in db [:wallet :keypairs])
|
||||
existing-accounts-by-address (get-in db [:wallet :accounts])
|
||||
{:keys [removed-keypair-ids
|
||||
removed-account-addresses
|
||||
updated-keypairs-by-id
|
||||
updated-accounts-by-address]} (data-store/reconcile-keypairs keypairs)
|
||||
updated-keypair-ids (set (keys updated-keypairs-by-id))
|
||||
updated-account-addresses (set (keys updated-accounts-by-address))
|
||||
existing-account-addresses (set (keys existing-accounts-by-address))
|
||||
new-account-addresses (clojure.set/difference updated-account-addresses
|
||||
existing-account-addresses)
|
||||
old-account-addresses (->> (vals existing-accounts-by-address)
|
||||
(filter (fn [{:keys [address key-uid]}]
|
||||
(and (contains? updated-keypair-ids key-uid)
|
||||
(not (contains?
|
||||
updated-accounts-by-address
|
||||
address)))))
|
||||
(map :address))]
|
||||
(cond-> {:db (-> db
|
||||
(assoc-in [:wallet :keypairs]
|
||||
(-> (apply dissoc existing-keypairs-by-id removed-keypair-ids)
|
||||
(merge updated-keypairs-by-id)))
|
||||
(assoc-in [:wallet :accounts]
|
||||
(merge-with merge
|
||||
(apply dissoc
|
||||
existing-accounts-by-address
|
||||
(into removed-account-addresses
|
||||
old-account-addresses))
|
||||
updated-accounts-by-address)))}
|
||||
(seq new-account-addresses)
|
||||
(assoc :fx
|
||||
(mapcat (fn [address]
|
||||
[[:dispatch [:wallet/get-wallet-token-for-account address]]
|
||||
[:dispatch
|
||||
[:wallet/request-new-collectibles-for-account-from-signal address]]
|
||||
[:dispatch [:wallet/check-recent-history-for-account address]]])
|
||||
new-account-addresses)))))
|
||||
|
||||
(rf/reg-event-fx :wallet/reconcile-keypairs reconcile-keypairs)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im.contexts.wallet.events-test
|
||||
(:require
|
||||
[cljs.test :refer-macros [is testing]]
|
||||
[matcher-combinators.matchers :as matchers]
|
||||
matcher-combinators.test
|
||||
[re-frame.db :as rf-db]
|
||||
[status-im.constants :as constants]
|
||||
@@ -150,3 +151,187 @@
|
||||
[:dispatch [:wallet/check-recent-history-for-account address]]]}]
|
||||
(reset! rf-db/app-db {:wallet {:accounts {}}})
|
||||
(is (match? expected-effects (dispatch [event-id raw-account])))))
|
||||
|
||||
(h/deftest-event :wallet/reconcile-keypairs
|
||||
[event-id dispatch]
|
||||
(let [keypair-key-uid (:key-uid raw-account)]
|
||||
(testing "event adds new key pairs"
|
||||
(reset! rf-db/app-db {:wallet {:accounts {}
|
||||
:keypairs {}}})
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
vector? matchers/equals
|
||||
map? matchers/equals]
|
||||
{:db {:wallet {:accounts {(:address account) account}
|
||||
:keypairs {keypair-key-uid {:key-uid keypair-key-uid
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts [account]}}}}
|
||||
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
|
||||
[:dispatch [:wallet/request-new-collectibles-for-account-from-signal address]]
|
||||
[:dispatch [:wallet/check-recent-history-for-account address]]]})
|
||||
(dispatch [event-id
|
||||
[{:key-uid keypair-key-uid
|
||||
:type "seed"
|
||||
:accounts [raw-account]}]]))))
|
||||
(testing "event removes key pairs and accounts that are marked as removed"
|
||||
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account}
|
||||
:keypairs {keypair-key-uid
|
||||
{:key-uid keypair-key-uid
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts [account]}}}})
|
||||
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
vector? matchers/equals
|
||||
map? matchers/equals]
|
||||
{:db {:wallet {:accounts {}
|
||||
:keypairs {}}}})
|
||||
(dispatch [event-id
|
||||
[{:key-uid keypair-key-uid
|
||||
:type "seed"
|
||||
:removed true
|
||||
:accounts [raw-account]}]]))))
|
||||
(testing "event removes accounts not present with key pair"
|
||||
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account
|
||||
"1x001" (assoc account
|
||||
:address "1x001"
|
||||
:key-uid "0x001")}
|
||||
:keypairs {keypair-key-uid
|
||||
{:key-uid keypair-key-uid
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts [account]}
|
||||
"0x001"
|
||||
{:key-uid "0x001"
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts [(assoc account
|
||||
:address "1x001"
|
||||
:key-uid "0x001")]}}}})
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
vector? matchers/equals
|
||||
map? matchers/equals]
|
||||
{:db {:wallet {:accounts {(:address account) account}
|
||||
:keypairs {keypair-key-uid
|
||||
{:key-uid keypair-key-uid
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts [account]}
|
||||
"0x001"
|
||||
{:key-uid "0x001"
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts []}}}}})
|
||||
(dispatch [event-id
|
||||
[{:key-uid "0x001"
|
||||
:type "seed"
|
||||
:accounts []}]]))))
|
||||
(testing "event updates existing key pairs"
|
||||
(reset! rf-db/app-db {:wallet
|
||||
{:accounts {(:address account)
|
||||
(assoc account :operable :no)}
|
||||
:keypairs {keypair-key-uid
|
||||
{:key-uid keypair-key-uid
|
||||
:type :seed
|
||||
:lowest-operability :no
|
||||
:accounts [(assoc account :operable :no)]}}}})
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
vector? matchers/equals
|
||||
map? matchers/equals]
|
||||
{:db {:wallet {:accounts {(:address account) account}
|
||||
:keypairs {keypair-key-uid
|
||||
{:key-uid keypair-key-uid
|
||||
:type :seed
|
||||
:lowest-operability :fully
|
||||
:accounts [account]}}}}})
|
||||
(dispatch [event-id
|
||||
[{:key-uid keypair-key-uid
|
||||
:type "seed"
|
||||
:accounts [raw-account]}]]))))
|
||||
(testing "event ignores chat accounts for key pairs"
|
||||
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account}
|
||||
:keypairs {keypair-key-uid
|
||||
{:key-uid keypair-key-uid
|
||||
:type :profile
|
||||
:lowest-operability :fully
|
||||
:accounts [account
|
||||
(assoc account
|
||||
:address "1x001"
|
||||
:chat true)]}}}})
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
vector? matchers/equals
|
||||
map? matchers/equals]
|
||||
{:db {:wallet {:accounts {(:address account) account}
|
||||
:keypairs {keypair-key-uid
|
||||
{:key-uid keypair-key-uid
|
||||
:type :profile
|
||||
:lowest-operability :fully
|
||||
:accounts [account
|
||||
(assoc account
|
||||
:address "1x001"
|
||||
:chat true)]}}}}})
|
||||
(dispatch [event-id
|
||||
[{:key-uid keypair-key-uid
|
||||
:type "profile"
|
||||
:accounts [raw-account
|
||||
(assoc raw-account
|
||||
:address "1x001"
|
||||
:chat true)]}]]))))))
|
||||
(h/deftest-event :wallet/reconcile-watch-only-accounts
|
||||
[event-id dispatch]
|
||||
(testing "event adds new watch-only accounts"
|
||||
(reset! rf-db/app-db {:wallet {:accounts {}}})
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
vector? matchers/equals
|
||||
map? matchers/equals]
|
||||
{:db {:wallet {:accounts {(:address account) account}}}
|
||||
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
|
||||
[:dispatch
|
||||
[:wallet/request-new-collectibles-for-account-from-signal address]]
|
||||
[:dispatch [:wallet/check-recent-history-for-account address]]]})
|
||||
(dispatch [event-id [raw-account]]))))
|
||||
(testing "event removes watch-only accounts that are marked as removed"
|
||||
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account}}})
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
vector? matchers/equals
|
||||
map? matchers/equals]
|
||||
{:db {:wallet {:accounts {}}}
|
||||
:fx []})
|
||||
(dispatch [event-id [(assoc raw-account :removed true)]]))))
|
||||
(testing "event updates existing watch-only accounts"
|
||||
(reset! rf-db/app-db {:wallet
|
||||
{:accounts {address account}}})
|
||||
(is
|
||||
(match?
|
||||
(matchers/match-with
|
||||
[set? matchers/set-equals
|
||||
vector? matchers/equals
|
||||
map? matchers/equals]
|
||||
{:db {:wallet {:accounts {address (assoc account :name "Test")}}}
|
||||
:fx []})
|
||||
(dispatch [event-id
|
||||
[(assoc raw-account
|
||||
:address address
|
||||
:name "Test")]])))))
|
||||
(cljs.test/run-tests)
|
||||
|
||||
@@ -18,8 +18,8 @@
|
||||
:image (:uri preview-url)}])}]))
|
||||
|
||||
(defn- on-collectible-press
|
||||
[{:keys [id]}]
|
||||
(rf/dispatch [:wallet/get-collectible-details id]))
|
||||
[{:keys [id]} aspect-ratio]
|
||||
(rf/dispatch [:wallet/get-collectible-details id aspect-ratio]))
|
||||
|
||||
(defn view
|
||||
[{:keys [selected-tab]}]
|
||||
|
||||
@@ -82,8 +82,12 @@
|
||||
:token-networks-ids token-networks-ids
|
||||
:tx-type tx-type
|
||||
:receiver? true})
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
receiver-network-values))
|
||||
(->
|
||||
(send-utils/reset-loading-network-amounts-to-zero
|
||||
receiver-network-values)
|
||||
vec
|
||||
(conj {:type :edit})))
|
||||
|
||||
network-links (when routes-available?
|
||||
(send-utils/network-links chosen-route
|
||||
sender-network-values
|
||||
@@ -237,7 +241,8 @@
|
||||
(assoc-in [:wallet :ui :send :token-not-supported-in-receiver-networks?]
|
||||
token-not-supported-in-receiver-networks?))
|
||||
:fx [[:dispatch [:hide-bottom-sheet]]
|
||||
[:dispatch [:wallet/clean-suggested-routes]]]})))
|
||||
[:dispatch [:wallet/clean-suggested-routes]]
|
||||
[:dispatch [:wallet/clean-from-locked-amounts]]]})))
|
||||
|
||||
(rf/reg-event-fx :wallet/clean-selected-token
|
||||
(fn [{:keys [db]}]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user