Compare commits
44
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c038e059d3 | ||
|
|
3521421098 | ||
|
|
f70a743a8c | ||
|
|
a2178951d7 | ||
|
|
7774c4eac1 | ||
|
|
4c4a8b65d4 | ||
|
|
de6d9a6c3b | ||
|
|
da16d1f69e | ||
|
|
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: 6.6 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 781 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.3 KiB |
@@ -108,8 +108,7 @@
|
||||
(when (and (multiaccounts.model/logged-in? db)
|
||||
(= current-theme-type status-im.constants/theme-type-system))
|
||||
{:profile.settings/switch-theme-fx
|
||||
[(get-in db [:profile/profile :appearance])
|
||||
(:view-id db) true]})))
|
||||
[(get-in db [:profile/profile :appearance]) (:view-id db)]})))
|
||||
|
||||
(defn- on-biometric-auth-fail
|
||||
[{:keys [code]}]
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
(defn fallback
|
||||
[{:keys [theme opacity]}]
|
||||
[{:opacity opacity}
|
||||
{:opacity default-opacity-for-image
|
||||
{:opacity 1
|
||||
: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)
|
||||
@@ -60,8 +60,13 @@
|
||||
:padding-right 0
|
||||
:padding-top 4})
|
||||
|
||||
(def card-detail-text
|
||||
{:flex 1})
|
||||
(defn card-detail-text
|
||||
[empty-name? theme]
|
||||
{:flex 1
|
||||
:margin-right 8
|
||||
:color (if empty-name?
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
(colors/theme-colors colors/neutral-100 colors/white theme))})
|
||||
|
||||
(defn card-loader
|
||||
[opacity]
|
||||
@@ -115,6 +120,7 @@
|
||||
[{:opacity opacity}
|
||||
{:flex 1
|
||||
:flex-direction :row
|
||||
:column-gap 8
|
||||
:opacity default-opacity-for-image}])
|
||||
|
||||
(defn supported-file
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns quo.components.profile.collectible-list-item.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.components.avatars.collection-avatar.view :as collection-avatar]
|
||||
[quo.components.counter.collectible-counter.view :as collectible-counter]
|
||||
[quo.components.icon :as icon]
|
||||
@@ -21,7 +22,7 @@
|
||||
(def cached-load-time 200)
|
||||
(def error-wait-time 800)
|
||||
|
||||
(defn on-load-end
|
||||
(defn animate-loading-image
|
||||
[{: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)
|
||||
@@ -34,6 +35,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 []
|
||||
@@ -54,12 +61,12 @@
|
||||
(assoc prev-state :avatar-loaded? true)))))
|
||||
|
||||
(defn- fallback-view
|
||||
[{:keys [label theme image-opacity]}]
|
||||
[reanimated/view
|
||||
{:style (style/fallback {:opacity image-opacity
|
||||
:theme theme})}
|
||||
[{:keys [label theme image-opacity on-load-end]}]
|
||||
(rn/use-mount on-load-end)
|
||||
[reanimated/view {:style (style/fallback {:opacity image-opacity :theme theme})}
|
||||
[rn/view
|
||||
[icon/icon :i/sad {:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}]]
|
||||
[icon/icon :i/sad
|
||||
{:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}]]
|
||||
[rn/view {:style {:height 4}}]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
@@ -87,31 +94,43 @@
|
||||
[{:keys [community? avatar-image-src collectible-name theme state set-state]}]
|
||||
(let [loader-opacity (reanimated/use-shared-value 1)
|
||||
avatar-opacity (reanimated/use-shared-value 0)
|
||||
[load-time set-load-time] (rn/use-state (datetime/now))]
|
||||
[load-time set-load-time] (rn/use-state (datetime/now))
|
||||
set-avatar-loaded (fn []
|
||||
(on-load-avatar {:set-state set-state
|
||||
:load-time load-time
|
||||
:loader-opacity loader-opacity
|
||||
:avatar-opacity avatar-opacity}))
|
||||
empty-name? (string/blank? collectible-name)]
|
||||
(rn/use-mount (fn []
|
||||
(when (string/blank? avatar-image-src)
|
||||
(set-avatar-loaded))))
|
||||
[rn/view {:style style/card-details-container}
|
||||
[reanimated/view {:style (style/avatar-container avatar-opacity)}
|
||||
(if community?
|
||||
[preview-list/view
|
||||
{:type :communities
|
||||
:size :size-20}
|
||||
(cond
|
||||
(string/blank? avatar-image-src)
|
||||
[loading-square theme]
|
||||
|
||||
community?
|
||||
[preview-list/view {:type :communities :size :size-20}
|
||||
[avatar-image-src]]
|
||||
|
||||
:else
|
||||
[collection-avatar/view
|
||||
{:size :size-20
|
||||
:on-start #(set-load-time (fn [start-time] (- (datetime/now) start-time)))
|
||||
:on-load-end #(on-load-avatar {:set-state set-state
|
||||
:load-time load-time
|
||||
:loader-opacity loader-opacity
|
||||
:avatar-opacity avatar-opacity})
|
||||
:on-load-end set-avatar-loaded
|
||||
:image avatar-image-src}])
|
||||
[rn/view {:style {:width 8}}]
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :semi-bold
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1
|
||||
:style style/card-detail-text}
|
||||
collectible-name]]
|
||||
(when (not (:avatar-loaded? state))
|
||||
:style (style/card-detail-text empty-name? theme)}
|
||||
(if empty-name?
|
||||
(i18n/label :t/unknown)
|
||||
collectible-name)]]
|
||||
|
||||
(when-not (:avatar-loaded? state)
|
||||
[reanimated/view {:style (style/card-loader loader-opacity)}
|
||||
[loading-square theme]
|
||||
[loading-message theme]])]))
|
||||
@@ -122,39 +141,44 @@
|
||||
(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))]
|
||||
[load-time set-load-time] (rn/use-state (datetime/now))
|
||||
set-image-loaded (fn []
|
||||
(animate-loading-image {:load-time load-time
|
||||
:set-state set-state
|
||||
:loader-opacity loader-opacity
|
||||
:image-opacity image-opacity}))]
|
||||
[rn/view {:style (style/card-view-container theme)}
|
||||
[rn/view {:style {:aspect-ratio 1}}
|
||||
(cond
|
||||
(:image-error? state)
|
||||
[fallback-view
|
||||
{:image-opacity image-opacity
|
||||
:theme theme
|
||||
:label (i18n/label :t/cant-fetch-info)}]
|
||||
(:image-error? state) [fallback-view
|
||||
{:image-opacity image-opacity
|
||||
:on-load-end set-image-loaded
|
||||
:theme theme
|
||||
:label (i18n/label :t/cant-fetch-info)}]
|
||||
(not supported-file?) [fallback-view
|
||||
{:image-opacity image-opacity
|
||||
:on-load-end set-image-loaded
|
||||
:theme theme
|
||||
:label (i18n/label :t/unsupported-file)}]
|
||||
(not (:image-loaded? state)) [loading-image
|
||||
{:loader-opacity loader-opacity
|
||||
:theme theme
|
||||
:gradient-color-index gradient-color-index}])
|
||||
|
||||
(not supported-file?)
|
||||
[fallback-view
|
||||
{:image-opacity image-opacity
|
||||
:theme theme
|
||||
:label (i18n/label :t/unsupported-file)}]
|
||||
|
||||
(not (:image-loaded? state))
|
||||
[loading-image
|
||||
{:loader-opacity loader-opacity
|
||||
:theme theme
|
||||
:gradient-color-index gradient-color-index}])
|
||||
(when supported-file?
|
||||
[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
|
||||
:loader-opacity loader-opacity
|
||||
:image-opacity image-opacity})
|
||||
:on-load-end set-image-loaded
|
||||
:on-error #(on-load-error set-state)
|
||||
:source image-src}]])]
|
||||
(when (and (:image-loaded? state) (not (:image-error? state)) counter)
|
||||
|
||||
(when (and (or (:image-loaded? state)
|
||||
(not supported-file?))
|
||||
(not (:image-error? state))
|
||||
counter)
|
||||
[collectible-counter/view
|
||||
{:container-style style/collectible-counter
|
||||
:size :size-24
|
||||
@@ -197,11 +221,12 @@
|
||||
[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
|
||||
:loader-opacity loader-opacity
|
||||
:image-opacity image-opacity})
|
||||
:on-load-end #(animate-loading-image {:load-time load-time
|
||||
:set-state set-state
|
||||
:loader-opacity loader-opacity
|
||||
:image-opacity image-opacity})
|
||||
:on-error #(on-load-error set-state)
|
||||
:source image-src}]])
|
||||
(when (and (:image-loaded? state) (not (:image-error? state)) counter)
|
||||
@@ -219,12 +244,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,39 @@
|
||||
(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.i18n :as i18n]))
|
||||
|
||||
(def loader-out 650)
|
||||
(def image-in 1000)
|
||||
(def error-wait-time 800)
|
||||
|
||||
(defn on-load-end
|
||||
[{:keys [loader-opacity image-opacity]}]
|
||||
(reanimated/animate loader-opacity 0 loader-out)
|
||||
(reanimated/animate image-opacity 1 image-in))
|
||||
|
||||
(defn on-load-error
|
||||
[set-error]
|
||||
(js/setTimeout set-error 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 +43,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)}]]
|
||||
@@ -31,56 +53,71 @@
|
||||
:style {:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}}
|
||||
label]])
|
||||
|
||||
(defn- collectible-image
|
||||
[{:keys [aspect-ratio theme gradient-color-index supported-file? set-error native-ID
|
||||
square? image-src on-collectible-load counter]}]
|
||||
(let [loader-opacity (reanimated/use-shared-value (if supported-file? 1 0))
|
||||
image-opacity (reanimated/use-shared-value (if supported-file? 0 1))]
|
||||
[:<>
|
||||
[loading-image
|
||||
{:aspect-ratio aspect-ratio
|
||||
:loader-opacity loader-opacity
|
||||
:theme theme
|
||||
:gradient-color-index gradient-color-index}]
|
||||
|
||||
[reanimated/view {:style (style/supported-file image-opacity)}
|
||||
[rn/image
|
||||
{:style (style/image square? aspect-ratio theme)
|
||||
:source image-src
|
||||
:native-ID native-ID
|
||||
:on-load-end (fn []
|
||||
(on-load-end {:loader-opacity loader-opacity
|
||||
:image-opacity image-opacity}))
|
||||
:on-error #(on-load-error set-error)
|
||||
:on-load on-collectible-load}]
|
||||
(when counter
|
||||
[counter-view counter])
|
||||
[rn/view {:style (style/collectible-border theme)}]]]))
|
||||
|
||||
(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 gradient-color-index]
|
||||
:or {gradient-color-index :gradient-1
|
||||
on-collectible-load (fn [])}}]
|
||||
(let [theme (quo.theme/use-theme)
|
||||
[error? set-error] (rn/use-state (or (nil? image-src)
|
||||
(string/blank? image-src)))]
|
||||
[rn/pressable
|
||||
{:on-press (when (and (not image-error?) supported-file?) on-press)
|
||||
{:style (merge container-style (style/container aspect-ratio))
|
||||
:accessibility-label :expanded-collectible
|
||||
:style (merge container-style style/container)}
|
||||
(cond
|
||||
(not supported-file?)
|
||||
:on-press (when (and (not error?) supported-file?)
|
||||
on-press)}
|
||||
(if (or (not supported-file?) error?)
|
||||
[fallback-view
|
||||
{:label (i18n/label :t/unsupported-file)
|
||||
{:label (i18n/label (if-not supported-file?
|
||||
:t/unsupported-file
|
||||
:t/cant-fetch-info))
|
||||
:counter counter
|
||||
:theme theme
|
||||
:on-mount on-collectible-load}]
|
||||
|
||||
image-error?
|
||||
[fallback-view
|
||||
{:label (i18n/label :t/cant-fetch-info)
|
||||
:counter counter
|
||||
:theme theme
|
||||
:on-mount on-collectible-load}]
|
||||
|
||||
:else
|
||||
[rn/view
|
||||
[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}]
|
||||
(when counter
|
||||
[counter-view counter])
|
||||
[rn/view {:style (style/collectible-border theme)}]])]))
|
||||
[collectible-image
|
||||
{:aspect-ratio aspect-ratio
|
||||
:theme theme
|
||||
:supported-file? supported-file?
|
||||
:set-error set-error
|
||||
:native-ID native-ID
|
||||
:square? square?
|
||||
:image-src image-src
|
||||
:on-collectible-load on-collectible-load
|
||||
:counter counter
|
||||
:gradient-color-index gradient-color-index}])]))
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[: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]]
|
||||
@@ -88,7 +125,8 @@
|
||||
[:square? {:optional true} [:maybe boolean?]]
|
||||
[:counter {:optional true} [:maybe string?]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:on-collectible-load {:optional true} [:maybe fn?]]]]]
|
||||
[:on-collectible-load {:optional true} [:maybe fn?]]
|
||||
[:gradient-color-index {:optional true} [:maybe keyword?]]]]]
|
||||
:any])
|
||||
|
||||
(def view (schema/instrument #'view-internal ?schema))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
[:type {:optional true}
|
||||
[:maybe
|
||||
[:enum :default :multiuser :group :channel :community :token :network :multinetwork :account
|
||||
:collectible :address :icon :audio :wallet-user]]]
|
||||
:collectible :address :icon :audio :wallet-user :dapp]]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
|
||||
@@ -17,16 +17,18 @@
|
||||
[schema.core :as schema]))
|
||||
|
||||
(defn- tag-skeleton
|
||||
[{:keys [size text] :or {size 24}} logo-component]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view {:style (style/tag-container size)}
|
||||
logo-component
|
||||
[rn/view {:style (style/tag-spacing size)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)}
|
||||
text]]]))
|
||||
[{:keys [size text theme]
|
||||
:or {size 24
|
||||
theme (quo.theme/use-theme)}}
|
||||
logo-component]
|
||||
[rn/view {:style (style/tag-container size)}
|
||||
logo-component
|
||||
[rn/view {:style (style/tag-spacing size)}
|
||||
[text/text
|
||||
{:style (style/text theme)
|
||||
:weight :medium
|
||||
:size (if (= size 24) :paragraph-2 :paragraph-1)}
|
||||
text]]])
|
||||
|
||||
(defn- communities-tag
|
||||
[{:keys [size community-logo community-name blur? channel? channel-name]}]
|
||||
@@ -81,95 +83,100 @@
|
||||
context]]]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type size state blur? customization-color profile-picture full-name users
|
||||
[{:keys [type theme size state blur? customization-color profile-picture full-name users
|
||||
group-name amount token network-logo network-name networks
|
||||
account-name emoji collectible collectible-name collectible-number duration container-style]
|
||||
account-name emoji collectible collectible-name collectible-number
|
||||
dapp-name dapp-logo duration container-style]
|
||||
:or {customization-color :blue
|
||||
type :default
|
||||
state :default}
|
||||
state :default
|
||||
theme (quo.theme/use-theme)}
|
||||
:as props}]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[rn/view {:style (merge {:align-items :flex-start} container-style)}
|
||||
[rn/view
|
||||
{:style (style/container {:theme theme
|
||||
:type type
|
||||
:size size
|
||||
:state state
|
||||
:blur? blur?
|
||||
:customization-color customization-color})
|
||||
:accessibility-label :context-tag}
|
||||
(case type
|
||||
:default
|
||||
[tag-skeleton {:theme theme :size size :text full-name}
|
||||
[user-avatar/user-avatar
|
||||
{:full-name full-name
|
||||
:profile-picture profile-picture
|
||||
:size (if (= size 24) :xxs 28)
|
||||
:status-indicator? false
|
||||
:ring? false
|
||||
:customization-color customization-color}]]
|
||||
[rn/view {:style (merge {:align-items :flex-start} container-style)}
|
||||
[rn/view
|
||||
{:style (style/container {:theme theme
|
||||
:type type
|
||||
:size size
|
||||
:state state
|
||||
:blur? blur?
|
||||
:customization-color customization-color})
|
||||
:accessibility-label :context-tag}
|
||||
(case type
|
||||
:default
|
||||
[tag-skeleton {:theme theme :size size :text full-name}
|
||||
[user-avatar/user-avatar
|
||||
{:full-name full-name
|
||||
:profile-picture profile-picture
|
||||
:size (if (= size 24) :xxs 28)
|
||||
:status-indicator? false
|
||||
:ring? false
|
||||
:customization-color customization-color}]]
|
||||
|
||||
:multiuser
|
||||
[preview-list/view {:type :user :size :size-20}
|
||||
users]
|
||||
:multiuser
|
||||
[preview-list/view {:type :user :size :size-20}
|
||||
users]
|
||||
|
||||
:multinetwork
|
||||
[preview-list/view {:type :network :size :size-20}
|
||||
networks]
|
||||
:multinetwork
|
||||
[preview-list/view {:type :network :size :size-20}
|
||||
networks]
|
||||
|
||||
:audio
|
||||
[tag-skeleton {:theme theme :text (str duration)}
|
||||
[rn/view {:style (style/audio-tag-icon-container customization-color theme)}
|
||||
[icons/icon :i/play {:color style/audio-tag-icon-color :size 12}]]]
|
||||
:audio
|
||||
[tag-skeleton {:theme theme :text (str duration)}
|
||||
[rn/view {:style (style/audio-tag-icon-container customization-color theme)}
|
||||
[icons/icon :i/play {:color style/audio-tag-icon-color :size 12}]]]
|
||||
|
||||
:group
|
||||
[tag-skeleton {:theme theme :size size :text group-name}
|
||||
[group-avatar/view
|
||||
{:icon-name :i/members
|
||||
:size (if (= size 24) :size-20 :size-28)
|
||||
:customization-color (colors/custom-color customization-color 50)}]]
|
||||
:group
|
||||
[tag-skeleton {:theme theme :size size :text group-name}
|
||||
[group-avatar/view
|
||||
{:icon-name :i/members
|
||||
:size (if (= size 24) :size-20 :size-28)
|
||||
:customization-color (colors/custom-color customization-color 50)}]]
|
||||
|
||||
(:channel :community)
|
||||
[communities-tag (assoc props :channel? (= type :channel))]
|
||||
(:channel :community)
|
||||
[communities-tag (assoc props :channel? (= type :channel))]
|
||||
|
||||
:token
|
||||
[tag-skeleton {:theme theme :size size :text (str amount " " token)}
|
||||
[token/view
|
||||
{:style (style/token-logo size)
|
||||
:token token
|
||||
:size (if (= size 24) :size-20 :size-28)}]]
|
||||
:token
|
||||
[tag-skeleton {:theme theme :size size :text (str amount " " token)}
|
||||
[token/view
|
||||
{:style (style/token-logo size)
|
||||
:token token
|
||||
:size (if (= size 24) :size-20 :size-28)}]]
|
||||
|
||||
:network
|
||||
[tag-skeleton {:theme theme :size size :text network-name}
|
||||
[rn/image {:style (style/circle-logo size) :source network-logo}]]
|
||||
:network
|
||||
[tag-skeleton {:theme theme :size size :text network-name}
|
||||
[rn/image {:style (style/circle-logo size) :source network-logo}]]
|
||||
|
||||
:collectible
|
||||
[tag-skeleton
|
||||
{:theme theme
|
||||
:size size
|
||||
:text (str collectible-name " #" collectible-number)}
|
||||
[rn/image {:style (style/rounded-logo size) :source collectible}]]
|
||||
:collectible
|
||||
[tag-skeleton
|
||||
{:theme theme
|
||||
:size size
|
||||
:text (str collectible-name " #" collectible-number)}
|
||||
[rn/image {:style (style/rounded-logo size) :source collectible}]]
|
||||
|
||||
:account
|
||||
[tag-skeleton {:theme theme :size size :text account-name}
|
||||
[account-avatar/view
|
||||
{:customization-color customization-color
|
||||
:emoji emoji
|
||||
:size (if (= size 24) 20 28)}]]
|
||||
:account
|
||||
[tag-skeleton {:theme theme :size size :text account-name}
|
||||
[account-avatar/view
|
||||
{:customization-color customization-color
|
||||
:emoji emoji
|
||||
:size (if (= size 24) 20 28)}]]
|
||||
|
||||
:address
|
||||
[address-tag props]
|
||||
:address
|
||||
[address-tag props]
|
||||
|
||||
:icon
|
||||
[icon-tag props]
|
||||
:icon
|
||||
[icon-tag props]
|
||||
|
||||
:wallet-user
|
||||
[tag-skeleton {:theme theme :size size :text full-name}
|
||||
[wallet-user-avatar/wallet-user-avatar
|
||||
{:full-name full-name
|
||||
:size (if (= size 24) :size-20 :size-24)
|
||||
:customization-color customization-color}]]
|
||||
:wallet-user
|
||||
[tag-skeleton {:theme theme :size size :text full-name}
|
||||
[wallet-user-avatar/wallet-user-avatar
|
||||
{:full-name full-name
|
||||
:size (if (= size 24) :size-20 :size-24)
|
||||
:customization-color customization-color}]]
|
||||
|
||||
nil)]]))
|
||||
:dapp
|
||||
[tag-skeleton {:theme theme :size size :text dapp-name}
|
||||
[rn/image {:style (style/circle-logo size) :source dapp-logo}]]
|
||||
|
||||
nil)]])
|
||||
|
||||
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -24,12 +24,13 @@
|
||||
(get ui k))
|
||||
|
||||
(def dapps
|
||||
{:coingecko (js/require "../resources/images/dapps/CoinGecko.png")
|
||||
:1inch (js/require "../resources/images/dapps/1inch.png")
|
||||
:aave (js/require "../resources/images/dapps/Aave.png")
|
||||
:uniswap (js/require "../resources/images/dapps/Uniswap.png")
|
||||
:zapper (js/require "../resources/images/dapps/Zapper.png")
|
||||
:zerion (js/require "../resources/images/dapps/Zerion.png")})
|
||||
{:coingecko (js/require "../resources/images/dapps/CoinGecko.png")
|
||||
:1inch (js/require "../resources/images/dapps/1inch.png")
|
||||
:aave (js/require "../resources/images/dapps/Aave.png")
|
||||
:uniswap (js/require "../resources/images/dapps/Uniswap.png")
|
||||
:zapper (js/require "../resources/images/dapps/Zapper.png")
|
||||
:zerion (js/require "../resources/images/dapps/Zerion.png")
|
||||
:wallet-connect (js/require "../resources/images/dapps/WalletConnect.png")})
|
||||
|
||||
(defn get-dapp
|
||||
[k]
|
||||
|
||||
@@ -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?}]))
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im.common.floating-button-page.floating-container.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.floating-container.style :as style]))
|
||||
@@ -9,9 +10,10 @@
|
||||
[child]
|
||||
(let [theme (quo.theme/use-theme)]
|
||||
[quo/blur
|
||||
{:blur-amount 12
|
||||
:blur-radius 12
|
||||
:blur-type theme}
|
||||
{:blur-amount 52
|
||||
:blur-radius 20
|
||||
:blur-type :transparent
|
||||
:blur-overlay-color (colors/theme-colors colors/white-70-blur colors/neutral-95-opa-70-blur theme)}
|
||||
[rn/view {:style style/blur-inner-container}
|
||||
child]]))
|
||||
|
||||
|
||||
@@ -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
|
||||
[]
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
:verifyENSURL config/verify-ens-url
|
||||
:verifyENSContractAddress config/verify-ens-contract-address
|
||||
:verifyTransactionChainID config/verify-transaction-chain-id
|
||||
:wakuV2LightClient false
|
||||
:wakuV2LightClient true
|
||||
:previewPrivacy config/blank-preview?
|
||||
:testNetworksEnabled config/test-networks-enabled?})))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -83,8 +83,7 @@
|
||||
[[:profile.settings/switch-theme-fx
|
||||
[(or (:appearance settings)
|
||||
constants/theme-type-dark)
|
||||
:shell-stack
|
||||
false]]
|
||||
:shell-stack]]
|
||||
[:dispatch [:init-root :shell-stack]]
|
||||
[:dispatch [:profile/show-testnet-mode-banner-if-enabled]]]))})))
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
[react-native.platform :as platform]
|
||||
[status-im.common.theme.core :as theme]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.setup.hot-reload :as hot-reload]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
@@ -20,7 +19,7 @@
|
||||
|
||||
(re-frame/reg-fx
|
||||
:profile.settings/switch-theme-fx
|
||||
(fn [[theme-type view-id reload-ui?]]
|
||||
(fn [[theme-type view-id]]
|
||||
(let [theme (if (or (= theme-type constants/theme-type-dark)
|
||||
(and (= theme-type constants/theme-type-system)
|
||||
(theme/device-theme-dark?)))
|
||||
@@ -28,8 +27,4 @@
|
||||
:light)]
|
||||
(theme/set-legacy-theme theme)
|
||||
(rf/dispatch [:theme/switch theme])
|
||||
(rf/dispatch [:reload-status-nav-color view-id])
|
||||
(when reload-ui?
|
||||
(re-frame/dispatch [:dismiss-all-overlays])
|
||||
(when js/goog.DEBUG
|
||||
(hot-reload/reload))))))
|
||||
(rf/dispatch [:reload-status-nav-color view-id]))))
|
||||
|
||||
@@ -95,14 +95,14 @@
|
||||
(rf/reg-event-fx :profile.settings/change-appearance
|
||||
(fn [_ [theme]]
|
||||
{:fx [[:dispatch [:profile.settings/profile-update :appearance theme]]
|
||||
[:profile.settings/switch-theme-fx [theme :appearance true]]]}))
|
||||
[:profile.settings/switch-theme-fx [theme :appearance]]]}))
|
||||
|
||||
(rf/reg-event-fx :profile.settings/switch-theme
|
||||
(fn [{:keys [db]} [theme view-id]]
|
||||
(let [theme (or theme
|
||||
(get-in db [:profile/profile :appearance])
|
||||
constants/theme-type-dark)]
|
||||
{:fx [[:profile.settings/switch-theme-fx [theme view-id false]]]})))
|
||||
{:fx [[:profile.settings/switch-theme-fx [theme view-id]]]})))
|
||||
|
||||
(rf/reg-fx :profile.settings/get-profile-picture
|
||||
(fn [key-uid]
|
||||
|
||||
@@ -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])]]))
|
||||
|
||||
|
||||
+9
-5
@@ -36,8 +36,10 @@
|
||||
(defn- address-input
|
||||
[{:keys [input-value on-change-text paste-into-input clear-input]}]
|
||||
(let [empty-input? (string/blank? input-value)
|
||||
on-scan-address (rn/use-callback #(rf/dispatch [:open-modal :screen/wallet.scan-address
|
||||
{:on-result on-change-text}]))]
|
||||
on-scan-address (rn/use-callback (fn []
|
||||
(rf/dispatch [:wallet/clean-scanned-address])
|
||||
(rf/dispatch [:open-modal :screen/wallet.scan-address
|
||||
{:on-result on-change-text}])))]
|
||||
[rn/view {:style style/input-container}
|
||||
[quo/input
|
||||
{:accessibility-label :add-address-to-save
|
||||
@@ -85,8 +87,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
|
||||
@@ -161,7 +163,9 @@
|
||||
(rf/dispatch
|
||||
[:open-modal :screen/settings.save-address]))
|
||||
[address ens-name? address-or-ens])]
|
||||
(rn/use-unmount #(rf/dispatch [:wallet/clear-address-to-save]))
|
||||
(rn/use-mount (fn []
|
||||
(rf/dispatch [:wallet/clean-scanned-address])
|
||||
(rf/dispatch [:wallet/clear-address-to-save])))
|
||||
[quo/overlay {:type :shell}
|
||||
[floating-button-page/view
|
||||
{:footer-container-padding 0
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- on-collectible-press
|
||||
[{:keys [id]}]
|
||||
(rf/dispatch [:wallet/get-collectible-details id]))
|
||||
(def on-collectible-press #(rf/dispatch [:wallet/navigate-to-collectible-details %]))
|
||||
|
||||
(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
|
||||
|
||||
@@ -71,7 +71,7 @@
|
||||
|
||||
(rf/reg-event-fx :wallet/seed-phrase-entered seed-phrase-entered)
|
||||
|
||||
(defn store-account-generated
|
||||
(defn store-account-generated-with-mnemonic
|
||||
[{:keys [db]} [{:keys [new-account-data keypair-name]}]]
|
||||
(let [new-account (update new-account-data :mnemonic security/mask-data)]
|
||||
{:db (-> db
|
||||
@@ -85,20 +85,21 @@
|
||||
:random-phrase))
|
||||
:fx [[:dispatch [:navigate-back-to :screen/wallet.create-account]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/store-account-generated store-account-generated)
|
||||
(rf/reg-event-fx :wallet/store-account-generated-with-mnemonic store-account-generated-with-mnemonic)
|
||||
|
||||
(defn generate-account-for-keypair
|
||||
(defn generate-account-for-keypair-with-mnemonic
|
||||
[{:keys [db]} [{:keys [keypair-name]}]]
|
||||
(let [seed-phrase (-> db :wallet :ui :create-account :new-keypair :seed-phrase)]
|
||||
{:fx [[:effects.wallet/create-account-from-mnemonic
|
||||
{:mnemonic-phrase (security/safe-unmask-data seed-phrase)
|
||||
:paths [constants/path-default-wallet]
|
||||
:on-success (fn [new-account-data]
|
||||
(rf/dispatch [:wallet/store-account-generated
|
||||
(rf/dispatch [:wallet/store-account-generated-with-mnemonic
|
||||
{:new-account-data new-account-data
|
||||
:keypair-name keypair-name}]))}]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/generate-account-for-keypair generate-account-for-keypair)
|
||||
(rf/reg-event-fx :wallet/generate-account-for-keypair-with-mnemonic
|
||||
generate-account-for-keypair-with-mnemonic)
|
||||
|
||||
(defn clear-create-account-data
|
||||
[{:keys [db]}]
|
||||
@@ -159,14 +160,19 @@
|
||||
(rf/reg-event-fx
|
||||
:wallet/create-keypair-with-account
|
||||
(fn [{db :db} [password account-preferences]]
|
||||
(let [{:keys [keypair-name
|
||||
(let [{:keys [workflow
|
||||
keypair-name
|
||||
new-account-data]} (-> db :wallet :ui :create-account :new-keypair)
|
||||
keypair-type (if (= workflow :workflow/new-keypair.import-private-key)
|
||||
:key
|
||||
:seed)
|
||||
keypair-with-account (create-account.utils/prepare-new-account
|
||||
{:keypair-name keypair-name
|
||||
:keypair-type keypair-type
|
||||
:account-data new-account-data
|
||||
:account-preferences account-preferences})
|
||||
new-address (some-> new-account-data
|
||||
(create-account.utils/first-derived-account)
|
||||
(create-account.utils/first-derived-account keypair-type)
|
||||
(:address)
|
||||
(string/lower-case))
|
||||
unmasked-password (security/safe-unmask-data password)]
|
||||
@@ -176,7 +182,7 @@
|
||||
:on-success [:wallet/add-account-success new-address]
|
||||
:on-error #(log/error "Failed to add Keypair and create account" %)}]]]})))
|
||||
|
||||
(defn import-and-create-keypair-with-account
|
||||
(defn import-mnemonic-and-create-keypair-with-account
|
||||
[{db :db} [{:keys [password account-preferences]}]]
|
||||
(let [account-data (-> db :wallet :ui :create-account :new-keypair :new-account-data)
|
||||
unmasked-mnemonic (security/safe-unmask-data (:mnemonic account-data))
|
||||
@@ -187,7 +193,8 @@
|
||||
:on-success #(rf/dispatch
|
||||
[:wallet/create-keypair-with-account password account-preferences])}]]]}))
|
||||
|
||||
(rf/reg-event-fx :wallet/import-and-create-keypair-with-account import-and-create-keypair-with-account)
|
||||
(rf/reg-event-fx :wallet/import-mnemonic-and-create-keypair-with-account
|
||||
import-mnemonic-and-create-keypair-with-account)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/derive-address-and-add-account
|
||||
@@ -206,3 +213,49 @@
|
||||
:on-error [:wallet/log-rpc-error
|
||||
{:event :wallet/derive-address-and-add-account
|
||||
:params [derived-from-address [derivation-path]]}]}]]]}))
|
||||
|
||||
(defn import-private-key-and-create-keypair-with-account
|
||||
[{:keys [db]} [{:keys [password account-preferences]}]]
|
||||
(let [private-key (get-in db
|
||||
[:wallet :ui :create-account :new-keypair
|
||||
:new-account-data :private-key])
|
||||
unmasked-private-key (security/safe-unmask-data private-key)
|
||||
unmasked-password (security/safe-unmask-data password)]
|
||||
{:json-rpc/call
|
||||
[{:method "accounts_importPrivateKey"
|
||||
:params [unmasked-private-key unmasked-password]
|
||||
:on-success [:wallet/create-keypair-with-account password account-preferences]
|
||||
:on-error #(log/error "Failed to import private key" %)}]}))
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/import-private-key-and-create-keypair-with-account
|
||||
import-private-key-and-create-keypair-with-account)
|
||||
|
||||
(defn store-account-generated-with-private-key
|
||||
[{:keys [db]} [{:keys [new-account-data keypair-name]}]]
|
||||
{:db (-> db
|
||||
(update-in [:wallet :ui :create-account :new-keypair]
|
||||
assoc
|
||||
:new-account-data new-account-data
|
||||
:keypair-name keypair-name)
|
||||
(update-in [:wallet :ui :create-account :new-keypair]
|
||||
dissoc
|
||||
:private-key))
|
||||
:fx [[:dispatch [:navigate-back-to :screen/wallet.create-account]]]})
|
||||
|
||||
(rf/reg-event-fx :wallet/store-account-generated-with-private-key
|
||||
store-account-generated-with-private-key)
|
||||
|
||||
(rf/reg-event-fx
|
||||
:wallet/import-private-key-and-generate-account-for-keypair
|
||||
(fn [{:keys [db]} [{:keys [keypair-name]}]]
|
||||
(let [private-key (get-in db [:wallet :ui :create-account :private-key])]
|
||||
{:db (assoc-in db
|
||||
[:wallet :ui :create-account :new-keypair :workflow]
|
||||
:workflow/new-keypair.import-private-key)
|
||||
:fx [[:effects.wallet/create-account-from-private-key
|
||||
{:private-key private-key
|
||||
:on-success (fn [new-account-data]
|
||||
(rf/dispatch [:wallet/store-account-generated-with-private-key
|
||||
{:keypair-name keypair-name
|
||||
:new-account-data new-account-data}]))}]]})))
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
{:new-account-data {"test" "data"
|
||||
:mnemonic masked-mnemonic}
|
||||
:keypair-name "new-keypair-name"}}}}}
|
||||
effects (events/store-account-generated {:db db} props)
|
||||
effects (events/store-account-generated-with-mnemonic {:db db} props)
|
||||
result-db (:db effects)
|
||||
remove-mnemonic #(update-in %
|
||||
[:wallet :ui :create-account :new-keypair :new-account-data]
|
||||
@@ -61,7 +61,7 @@
|
||||
expected-effects [[:effects.wallet/create-account-from-mnemonic
|
||||
{:mnemonic-phrase "test-secret"
|
||||
:paths [constants/path-default-wallet]}]]
|
||||
effects (events/generate-account-for-keypair {:db db} props)]
|
||||
effects (events/generate-account-for-keypair-with-mnemonic {:db db} props)]
|
||||
(is (match?
|
||||
(update-in effects [:fx 0 1] dissoc :on-success)
|
||||
{:fx expected-effects}))
|
||||
|
||||
+7
-7
@@ -63,31 +63,31 @@
|
||||
(let [{:keys [message] :as props}
|
||||
(case state
|
||||
:scanning
|
||||
{:type :info
|
||||
{:status :default
|
||||
:icon :i/scanning
|
||||
:message :t/scanning-for-activity}
|
||||
|
||||
:inactive-address
|
||||
{:type :warning
|
||||
{:status :warning
|
||||
:icon :i/info
|
||||
:message :t/this-account-has-no-activity}
|
||||
|
||||
:active-address
|
||||
{:type :success
|
||||
{:status :success
|
||||
:icon :i/done
|
||||
:message :t/this-address-has-activity}
|
||||
|
||||
:invalid-private-key
|
||||
{:type :error
|
||||
{:status :error
|
||||
:icon :i/info
|
||||
:message :t/invalid-private-key}
|
||||
|
||||
nil)]
|
||||
(when props
|
||||
[quo/info-message
|
||||
(assoc props
|
||||
:size :default
|
||||
:style style/indicator)
|
||||
(-> props
|
||||
(assoc :size :default :container-style style/indicator)
|
||||
(dissoc :message))
|
||||
(i18n/label message)])))
|
||||
|
||||
(defn on-unmount
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user