Compare commits

..
156 changed files with 1065 additions and 2916 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
/* 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 { s5cmd.upload(it) }
def urls = apks.collect { s3.uploadArtifact(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. */
+3 -24
View File
@@ -1,7 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
import groovy.json.JsonBuilder
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label 'linux' }
@@ -74,7 +72,7 @@ pipeline {
iOS: utils.pkgUrl(ios),
Diawi: utils.getEnv(ios, 'DIAWI_URL'),
/* upload the sha256 checksums file too */
SHA: s5cmd.upload(sha),
SHA: s3.uploadArtifact(sha),
]
/* add URLs to the build description */
jenkins.setBuildDesc(urls)
@@ -85,7 +83,7 @@ pipeline {
steps { script {
switch (utils.getBuildType()) {
case 'nightly': /* Create JSON file with newest build URLs */
updateBucketJSON(urls, 'latest.json');
s3.updateBucketJSON(urls, 'latest.json');
break;
case 'release':
github.publishReleaseFiles(repo: 'status-mobile');
@@ -116,22 +114,3 @@ 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 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+2 -2
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -75,7 +75,7 @@ pipeline {
stage('Upload') {
steps {
script {
env.PKG_URL = s5cmd.upload(LOG_FILE)
env.PKG_URL = s3.uploadArtifact(LOG_FILE)
}
}
}
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label params.AGENT_LABEL }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.9.1'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent {
+3 -5
View File
@@ -32,16 +32,14 @@ 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, merge the status-go PR first.
4) Once merged, tag the merged commit with the new version and push the tag:
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:
```
git checkout develop
git pull develop
make tag-version
git tag vx.y.z
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.
+2 -2
View File
@@ -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)
theme (theme/use-theme-value)
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)` hook can be used directly in the components
- `theme/with-theme` wrapper is not needed anymore, `(theme/use-theme-value)` 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
View File
@@ -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" "15.4"];
versions = ["15.1" "15.2" "15.3"];
};
go = super.go_1_21;
clang = super.clang_15;
+2 -3
View File
@@ -20,10 +20,9 @@
"@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.11.2",
"@walletconnect/web3wallet": "1.10.2",
"@walletconnect/react-native-compat": "^2.12.2",
"@walletconnect/web3wallet": "^1.11.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.

Before

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

+1 -1
View File
@@ -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 :peer-stats/count :peer-stats/count)
(reg-root-key-sub :peers-count :peers-count)
(reg-root-key-sub :peers-summary :peers-summary)
(reg-root-key-sub :web3-node-version :web3-node-version)
@@ -1,9 +1,14 @@
(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.react :as react])
(:require-macros [legacy.status-im.utils.views :as views]))
[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]]))
(defn easing
[direction n]
@@ -67,3 +72,112 @@
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,21 +1,17 @@
(ns legacy.status-im.ui.screens.peers-stats
(:require
[react-native.core :as rn]
[react-native.core :as react-native.core]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
[utils.re-frame :as re-frame]))
(defn peers-stats
[]
(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
(let [peers-count (re-frame/sub [:peers-count])]
[react-native.core/view
{:flex 1
:margin-horizontal 8}
[react-native.core/view
{:style {:flex-direction :row
:margin-vertical 8
:justify-content :space-between}}
[rn/text (str (i18n/label :t/peers-count) ": " peers-count)]]]))
[react-native.core/text (str (i18n/label :t/peers-count) ": " peers-count)]]]))
@@ -128,6 +128,7 @@
: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)
(pos? (:peer-stats/count db)))
(> (:peers-count db) 0))
;; 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.view :as info-message]
[quo.components.info.info-message :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/view
{:icon :i/info
:size :default
:status :error}
[info-message/info-message
{:icon :i/info
:size :default
:type :error}
text]
:info
[info-message/view
(merge {:icon :i/info
:size :default
:status (if (= type :error) :error :default)}
[info-message/info-message
(merge {:icon :i/info
:size :default
:type (if (= type :error) :error :default)}
(when blur?
{:text-color colors/white-opa-70
:icon-color colors/white-opa-40}))
@@ -26,8 +26,7 @@
(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)]
@@ -55,10 +54,9 @@
on-track-layout (rn/use-callback
#(set-track-width (oops/oget % "nativeEvent.layout.width")))
reset-fn (rn/use-callback
(fn [keep-at-end-after-slide?]
(fn []
(set-sliding-complete false)
(when-not keep-at-end-after-slide?
(animations/reset-track-position x-pos))))
(animations/reset-track-position x-pos)))
dimensions (rn/use-callback
(partial utils/get-dimensions
(or track-width constants/default-width)
+48
View File
@@ -0,0 +1,48 @@
(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]]))
@@ -1,32 +0,0 @@
(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))))
@@ -1,6 +0,0 @@
(ns quo.components.info.info-message.style)
(def container
{:flex-direction :row
:gap 4
:align-items :center})
@@ -1,53 +0,0 @@
(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,14 +44,13 @@
[: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 container-style state customization-color]
[{:keys [on-press state customization-color]
:as props
:or {customization-color :blue}}]
(let [theme (quo.theme/use-theme)
@@ -60,8 +59,7 @@
on-press-out (rn/use-callback #(set-pressed false))
internal-state (if pressed? :pressed state)]
[rn/pressable
{:style (merge (style/container internal-state customization-color theme)
container-style)
{:style (style/container internal-state customization-color theme)
: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)
+3 -3
View File
@@ -8,7 +8,7 @@
[quo.foundations.colors :as colors]
[react-native.core :as rn]))
(def container
(def container-style
{: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? container-style]}]
allow-multiple-presses? disabled?]}]
[rn/touchable-highlight
{:style (merge container container-style)
{:style container-style
:underlay-color (colors/resolve-color customization-color theme 5)
:allow-multiple-presses? allow-multiple-presses?
:accessibility-label :user-list
@@ -34,12 +34,6 @@
(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 []
@@ -153,7 +147,6 @@
[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
@@ -204,7 +197,6 @@
[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
@@ -227,13 +219,12 @@
(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-aspect-ratio nil
:image-error? false
:avatar-loaded? false})
(let [[state set-state] (rn/use-state {:image-loaded? false
:image-error? false
:avatar-loaded? false})
collectible-ready? (or (:image-loaded? state) (not supported-file?))]
[rn/pressable
{:on-press (when collectible-ready? #(on-press (:image-aspect-ratio state)))
{:on-press (when collectible-ready? on-press)
:on-long-press (when collectible-ready? on-long-press)
:accessibility-label :collectible-list-item
:style container-style}
@@ -1,13 +1,10 @@
(ns quo.components.profile.expanded-collectible.style
(:require [quo.foundations.colors :as colors]))
(defn container
[aspect-ratio]
(cond-> {:align-items :center
:justify-content :center
:border-radius 16}
aspect-ratio (assoc :width "100%"
:aspect-ratio aspect-ratio)))
(def container
{:align-items :center
:justify-content :center
:border-radius 16})
(defn image
[square? aspect-ratio theme]
@@ -28,43 +25,18 @@
:border-color (colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)})
(defn fallback
([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}))
[{: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})
(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,53 +1,17 @@
(ns quo.components.profile.expanded-collectible.view
(:require
[clojure.string :as string]
[promesa.core :as promesa]
[quo.components.counter.collectible-counter.view :as collectible-counter]
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.profile.expanded-collectible.style :as style]
[quo.foundations.colors :as colors]
[quo.foundations.gradients :as gradients]
[quo.theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[schema.core :as schema]
[utils.datetime :as datetime]
[utils.i18n :as i18n]))
(def timing-options-out 650)
(def timing-options-in 1000)
(def first-load-time 500)
(def cached-load-time 200)
(def error-wait-time 800)
(defn on-load-end
[{:keys [load-time set-state loader-opacity image-opacity]}]
(reanimated/animate loader-opacity 0 timing-options-out)
(reanimated/animate image-opacity 1 timing-options-in)
(if (> load-time cached-load-time)
(js/setTimeout
(fn []
(set-state (fn [prev-state]
(assoc prev-state :image-loaded? true))))
first-load-time)
(set-state (fn [prev-state]
(assoc prev-state :image-loaded? true)))))
(defn on-load-error
[set-state]
(js/setTimeout (fn []
(set-state (fn [prev-state] (assoc prev-state :image-error? true))))
error-wait-time))
(defn- loading-image
[{:keys [theme gradient-color-index loader-opacity aspect-ratio]}]
[reanimated/view
{:style (style/loading-image-with-opacity loader-opacity)}
[gradients/view
{:theme theme
:container-style (style/gradient-view aspect-ratio)
:color-index gradient-color-index}]])
(defn- counter-view
[counter]
[collectible-counter/view
@@ -57,7 +21,7 @@
(defn- fallback-view
[{:keys [label theme counter on-mount]}]
(rn/use-mount on-mount)
[rn/view {:style (style/fallback theme)}
[rn/view {:style (style/fallback {:theme theme})}
[counter-view counter]
[rn/view
[icon/icon :i/sad {:color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)}]]
@@ -69,57 +33,45 @@
(defn view-internal
[{:keys [container-style square? on-press counter image-src native-ID supported-file?
on-collectible-load aspect-ratio]}]
(let [theme (quo.theme/use-theme)
loader-opacity (reanimated/use-shared-value
(if supported-file? 1 0))
image-opacity (reanimated/use-shared-value
(if supported-file? 0 1))
[load-time set-load-time] (rn/use-state (datetime/now))
[state set-state] (rn/use-state {:image-loaded? false
:image-error? (or (nil? image-src)
(string/blank?
image-src))})]
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])
[rn/pressable
{:on-press (when (and (not (:image-error? state)) supported-file?) on-press)
{:on-press (when (and (not image-error?) supported-file?) on-press)
:accessibility-label :expanded-collectible
:style (merge container-style
(style/container aspect-ratio))}
:style (merge container-style style/container)}
(cond
(not supported-file?)
[fallback-view
{:aspect-ratio aspect-ratio
:label (i18n/label :t/unsupported-file)
:counter counter
:theme theme
:on-mount on-collectible-load}]
{:label (i18n/label :t/unsupported-file)
:counter counter
:theme theme
:on-mount on-collectible-load}]
(:image-error? state)
image-error?
[fallback-view
{:label (i18n/label :t/cant-fetch-info)
:counter counter
:theme theme
:on-mount on-collectible-load}]
(not (:image-loaded? state))
[loading-image
{:aspect-ratio aspect-ratio
:loader-opacity loader-opacity
:theme theme
:gradient-color-index :gradient-5}])
(when supported-file?
[reanimated/view {:style (style/supported-file image-opacity)}
:else
[rn/view
[rn/image
{:style (style/image square? aspect-ratio theme)
:source image-src
:native-ID native-ID
:on-load-start #(set-load-time (fn [start-time] (- (datetime/now) start-time)))
:on-load-end #(on-load-end {:load-time load-time
:set-state set-state
:loader-opacity loader-opacity
:image-opacity image-opacity})
:on-error #(on-load-error set-state)
:on-load on-collectible-load}]
{: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)}]])]))
@@ -129,7 +81,6 @@
[:catn
[:props
[:map {:closed true}
[:aspect-ratio {:optional true} [:maybe number?]]
[:image-src {:optional true} [:maybe string?]]
[:supported-file? {:optional true} [:maybe boolean?]]
[:container-style {:optional true} [:maybe :map]]
@@ -12,8 +12,7 @@
[{: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 (when on-change
#(on-change (not checked?)))
{:on-press on-change
:accessibility-label :disclaimer-touchable-opacity}
[rn/view {:style (merge container-style (style/container blur? theme))}
[selectors/view
@@ -6,14 +6,8 @@
[{:keys [size card? blur? actionable? theme]}]
{:flex-direction :row
:justify-content :space-between
:padding-vertical (case size
:default 8
:large 12
nil)
:padding-horizontal (case size
:default 12
:large 16
nil)
:padding-vertical (when (= size :default) 8)
:padding-horizontal (when (= size :default) 12)
:border-radius 16
:border-width (when (and card? (not= size :small)) 1)
:background-color (if blur?
@@ -30,27 +24,15 @@
(defn loading-container
[size blur? theme]
{:width (case size
:large 132
:small 72
132)
:height (case size
:large 16
:small 10
16)
{:width (if (= size :default) 132 72)
:height (if (= size :default) 16 10)
:background-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-5
colors/neutral-90
theme))
:border-radius (case size
:large 6
:small 3
6)
:margin-vertical (case size
:large 4
:small 3
4)})
:border-radius (if (= size :default) 6 3)
:margin-vertical (if (= size :default) 4 3)})
(def subtitle-container
{:flex-direction :row
+1 -1
View File
@@ -102,7 +102,7 @@
:container-style container-style
:theme theme))
:on-press #(when (= action :selector) (on-press))
:pointer-events (when (= action :selector) :box-only)}
:pointer-events :box-only}
[rn/view {:style style/header-container}
[avatar props]
[rn/view
+2 -2
View File
@@ -68,7 +68,7 @@
quo.components.graph.wallet-graph.view
quo.components.header
quo.components.icon
quo.components.info.info-message.view
quo.components.info.info-message
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.view/view)
(def info-message quo.components.info.info-message/info-message)
(def information-box quo.components.info.information-box.view/view)
;;;; Inputs
-1
View File
@@ -41,7 +41,6 @@
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
@@ -1,24 +0,0 @@
(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})
@@ -1,74 +0,0 @@
(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,8 +6,7 @@
(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?
container-style]}
{:keys [primary-name secondary-name public-key compressed-key ens-verified added?]}
theme]
(let [photo-path (rf/sub [:chats/photo-path public-key])
online? (rf/sub [:visibility-status-updates/online? public-key])
@@ -26,5 +25,4 @@
:on-press on-press
:on-long-press on-long-press
:accessory accessory
:container-style container-style
:disabled? disabled?}]))
@@ -31,10 +31,10 @@
:on-change-text #(reset! entered-password %)}]
(when (not-empty error)
[quo/info-message
{:status :error
:size :default
:icon :i/info
:container-style {:margin-top 8}}
{:type :error
:size :default
:icon :i/info
:containstyle {:margin-top 8}}
(i18n/label :t/oops-wrong-password)])
[quo/button
{:container-style {:margin-bottom 12 :margin-top 40}
@@ -1,17 +0,0 @@
(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))}))
+4 -2
View File
@@ -195,7 +195,7 @@
true)
(defn view
[{:keys [title subtitle validate-fn on-success-scan error-message share-button?]}]
[{:keys [title subtitle validate-fn on-success-scan error-message share-button? import-keypair?]}]
(let [insets (safe-area/get-insets)
qr-code-succeed? (reagent/atom false)
qr-view-finder (reagent/atom {})
@@ -233,7 +233,9 @@
:set-qr-code-succeeded (fn [value]
(when on-success-scan
(on-success-scan value))
(rf/dispatch [:navigate-back]))
(if import-keypair?
(set-rescan-timeout)
(rf/dispatch [:navigate-back])))
:set-rescan-timeout set-rescan-timeout}])
[rn/view {:style (style/root-container (:top insets))}
[header
+13 -2
View File
@@ -10,6 +10,7 @@
[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]))
@@ -19,10 +20,17 @@
peers-count (count peers-summary)]
(rf/merge cofx
{:db (assoc db
:peers-summary peers-summary
:peer-stats/count peers-count)}
:peers-summary peers-summary
:peers-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]
@@ -38,6 +46,9 @@
"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,8 +32,9 @@
:on-cancel #(rf/dispatch [:standard-auth/authorize-with-password
args-with-biometric-btn])
:on-success (fn []
(rf/dispatch [:standard-auth/on-biometric-success on-auth-success])
(rf/dispatch [:standard-auth/close on-close]))
(when (fn? on-close)
(on-close))
(rf/dispatch [:standard-auth/on-biometric-success on-auth-success]))
:on-fail (fn [err]
(rf/dispatch [:standard-auth/authorize-with-password
args-with-biometric-btn])
@@ -47,7 +48,6 @@
[{: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,7 +74,6 @@
(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
@@ -93,7 +92,10 @@
{:fx [[:dispatch [:standard-auth/reset-login-password]]
[:dispatch
[:show-bottom-sheet
{:on-close #(rf/dispatch [:standard-auth/close on-close])
{:on-close (fn []
(rf/dispatch [:standard-auth/reset-login-password])
(when on-close
(on-close)))
:theme theme
:shell? blur?
:content #(bottom-sheet-password-view args)}]]]})
@@ -105,23 +107,3 @@
: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,7 +16,8 @@
[error]
(if (and (some? error)
(or (= error "file is not a database")
(string/starts-with? (string/lower-case error) "failed")))
(string/starts-with? error "failed to set ")
(string/starts-with? error "Failed")))
(i18n/label :t/oops-wrong-password)
error))
@@ -33,9 +34,9 @@
[theme])]
[rn/view {:style style/error-message}
[quo/info-message
{:status :error
:size :default
:icon :i/info}
{:type :error
:size :default
:icon :i/info}
error-message]
[rn/pressable
{:hit-slop {:top 6 :bottom 20 :left 0 :right 0}
@@ -16,8 +16,7 @@
on-complete (rn/use-callback
(fn [reset]
(rf/dispatch [:standard-auth/authorize
{:on-close (fn [success?]
(js/setTimeout #(reset success?) 200))
{:on-close #(js/setTimeout reset 200)
:auth-button-icon-left auth-button-icon-left
:theme theme
:blur? blur?
-12
View File
@@ -282,8 +282,6 @@
(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")
@@ -505,9 +503,6 @@
(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))
@@ -553,10 +548,3 @@
(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
{:status :error
:icon :i/info
:size :default
:container-style {:margin-top 8 :margin-left 20 :margin-bottom 16}}
{:type :error
:icon :i/info
:size :default
:style {:margin-top 8 :margin-left 20 :margin-bottom 16}}
error-message])
[quo/divider-line]
[rn/view
@@ -173,21 +173,20 @@
(defn avatar-view
[{:keys [contact chat-id full-name color muted? image]}]
[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}])])
(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]
+1 -2
View File
@@ -66,8 +66,7 @@
(chat-list-item/chat-list-item item theme))
:scroll-event-throttle 8
:content-container-style {:padding-bottom
jump-to.constants/floating-shell-button-height
:padding-top 8}
jump-to.constants/floating-shell-button-height}
:on-scroll #(common.banner/set-scroll-shared-value
{:scroll-input (oops/oget % "nativeEvent.contentOffset.y")
:shared-value scroll-shared-value})}])))
@@ -98,8 +98,9 @@
window-height
loading-indicator-page-loading-height)]
[rn/view {:padding-top top-spacing}
;; 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)]]))
;; 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?)]]))
(defn header-height
[{:keys [insets able-to-send-message? images reply edit link-previews? input-content-height]}]
@@ -21,7 +21,6 @@
[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]))
@@ -55,11 +54,8 @@
^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
@@ -181,22 +177,6 @@
(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")
@@ -219,13 +199,6 @@
(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,44 +6,32 @@
[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 _ _ {: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])]
[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)]
[contact-list-item/contact-list-item
{:on-press on-press
{:on-press #(rf/dispatch [:chat.ui/show-profile public-key])
: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?
;; 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}}
{:primary-name primary-name
:secondary-name secondary-name
:compressed-key compressed-key
:public-key public-key
:ens-verified ens-verified
:added? added?}
theme]))
(defn- footer
@@ -52,12 +40,10 @@
(defn- get-item-layout
[_ index]
#js {:length constants/contact-item-height
:offset (* constants/contact-item-height index)
:index index})
#js {:length 200 :offset (* 200 index) :index index})
(defn- members
[items theme]
[items]
[rn/section-list
{:key-fn :public-key
:content-container-style {:padding-bottom 20}
@@ -67,70 +53,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 32}])
:scroll-event-throttle 8}])
(defn view
[]
(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]]))
[_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]])))
@@ -4,7 +4,6 @@
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]
@@ -26,14 +25,6 @@
[: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
@@ -71,7 +62,7 @@
:accessibility-label :scan-sync-code-option-card
:image (resources/get-image :generate-keys)
:max-height (option-card-max-height window-height)
:on-press show-check-before-syncing}])
:on-press navigate-to-sign-in-by-syncing}])
(defn sign-in-options
[sign-in-type]
@@ -38,11 +38,14 @@
[rn/view {:style style/info-message}
(when shown
[quo/info-message
{:status status
:size :default
:icon (if (= status :success) :i/positive-state :i/info)
:color (when (= status :default)
colors/white-70-blur)}
{: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 {}}
text])]])
(defn password-inputs
@@ -158,11 +158,12 @@
:on-change-text on-change-text}}]]
[quo/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}
{: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}
info-message]
[quo/text
{:size :paragraph-2
@@ -1,6 +1,7 @@
(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]))
@@ -17,36 +18,41 @@
: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
: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?])]
(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)]
(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}
[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?))}]])))
(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"])])))
(defn view [] [:f> f-view])
@@ -1,43 +1,28 @@
(ns status-im.contexts.preview.quo.info.info-message
(:require
[quo.core :as quo]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.preview.quo.preview :as preview]))
(def descriptor
[{:key :status
[{:key :type
:type :select
:options [{:key :default}
{:key :success}
{:key :error}
{:key :warning}]}
{:key :error}]}
{: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 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)]]))
(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)]])))
@@ -65,9 +65,9 @@
:customization-color :blue}
:header [rn/view
[quo/info-message
{:status :success
:size :tiny
:icon :i/placeholder}
{:type :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,8 +55,7 @@
{:type :select
:key :size
:options [{:key :default}
{:key :small}
{:key :large}]}])
{:key :small}]}])
(defn view
[]
+1 -1
View File
@@ -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
:status (if-not (string/blank? error-msg) :error :default)}
{:icon :i/info
:size :default
:type (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
{:status :error
:size :default
:icon :i/info}
{:type :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
{:status :error
:size :default
:icon :i/info}
{:type :error
:size :default
:icon :i/info}
@error-msg])]
[rn/view {:style style/button-wrapper}
[quo/button
@@ -5,7 +5,6 @@
[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]
@@ -42,17 +41,6 @@
: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
@@ -67,7 +55,9 @@
:accessibility-label :create-new-profile}
{:icon :i/multi-profile
:label (i18n/label :t/add-existing-status-profile)
:on-press show-check-before-syncing
:on-press #(debounce/throttle-and-dispatch
[:open-modal :screen/onboarding.sign-in]
1000)
:accessibility-label :multi-profile}]]])
(defn show-new-account-options
@@ -61,14 +61,7 @@
:image :icon
:blur? true
:action :arrow})]
[(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)
[{:title (i18n/label :t/syncing)
:on-press #(rf/dispatch [:open-modal :settings-syncing])
:image-props :i/syncing
:image :icon
@@ -24,11 +24,12 @@
[rn/view {:style style/info-message}
(when shown?
[quo/info-message
(cond-> {:status status
:size :default}
(cond-> {:type status
:size :default}
(not= :success status) (assoc :icon :i/info)
(= :success status) (assoc :icon :i/positive-state)
(= :default status) (assoc :color colors/white-70-blur))
(= :default status) (assoc :text-color colors/white-70-blur
:icon-color colors/white-70-blur))
text])]])
(defn- calc-password-strength
@@ -43,9 +43,9 @@
{:style style/error-container}
(when error
[quo/info-message
{:status :error
:size :default
:icon :i/info}
{:type :error
:size :default
:icon :i/info}
(i18n/label :t/oops-wrong-password)])]
[quo/information-box
{:type :error
@@ -1,6 +1,5 @@
(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]))
@@ -18,10 +17,6 @@
[: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
@@ -1,11 +0,0 @@
(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})
@@ -1,42 +0,0 @@
(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]}]]
[{:keys [db]} [{:keys [sha3-pwd keypairs-key-uids connection-string on-success]}]]
(let [key-uid (get-in db [:profile/profile :key-uid])]
{:fx [[:effects.syncing/import-keypairs-keystores
{:key-uid key-uid
@@ -100,6 +100,7 @@
: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"
@@ -112,7 +113,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]]
[_ [connection-string keypairs-key-uids on-import-success]]
{:fx [[:dispatch
[:standard-auth/authorize-with-password
{:blur? true
@@ -124,7 +125,8 @@
[:wallet/connection-string-for-import-keypair
{:connection-string connection-string
:keypairs-key-uids keypairs-key-uids
:sha3-pwd password}]))}]]]})
:sha3-pwd password
:on-success on-import-success}]))}]]]})
(rf/reg-event-fx :wallet/success-keypair-qr-scan success-keypair-qr-scan)
@@ -128,9 +128,9 @@
:default-value private-key}]
(when flow-state
[quo/info-message
{:status (if (= flow-state :correct-private-key) :success :error)
:size :default
:icon :i/info}
{:type (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)
@@ -13,12 +13,14 @@
on-success-scan (rn/use-callback (fn [scanned-text]
(rf/dispatch [:wallet/success-keypair-qr-scan
scanned-text
keypairs-key-uids])
keypairs-key-uids
[:navigate-back]])
[keypairs-key-uids]))]
[scan-qr-code/view
{:title (i18n/label :t/scan-key-pairs-qr-code)
:subtitle (i18n/label :t/find-it-in-setting)
:share-button? false
:import-keypair? true
:validate-fn sync-utils/valid-connection-string?
:error-message (i18n/label :t/invalid-key-pair-qr)
:on-success-scan on-success-scan}]))
@@ -94,8 +94,9 @@
:error? (not (string/blank? error-msg))}]
(when-not (string/blank? error-msg)
[quo/info-message
{:status :error
{:type :error
:size :default
:icon :i/info
:container-style style/error-container}
error-msg])]]))
@@ -85,8 +85,8 @@
{:accessibility-label :error-message
:size :default
:icon :i/alert
:status :error
:container-style style/info-message}
:type :error
:style style/info-message}
error-msg])))
(defn- existing-saved-address
@@ -23,29 +23,15 @@
(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
[_ [raw-saved-addresses]]
(let [saved-addresses (data-store/rpc->saved-addresses raw-saved-addresses)]
{:fx [[:dispatch [:wallet/reconcile-saved-addresses saved-addresses]]]}))
[{: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)}))
(rf/reg-event-fx :wallet/get-saved-addresses-success get-saved-addresses-success)
@@ -66,17 +52,15 @@
(rf/reg-event-fx :wallet/get-saved-addresses get-saved-addresses)
(defn delete-saved-address-success
[{: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}]}]]}))
[_ [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}]}]]})
(rf/reg-event-fx :wallet/delete-saved-address-success delete-saved-address-success)
@@ -98,10 +82,7 @@
{:fx [[:json-rpc/call
[{:method "wakuext_deleteSavedAddress"
:params [address test-networks-enabled?]
:on-success [:wallet/delete-saved-address-success
{:address address
:test-networks-enabled? test-networks-enabled?
:toast-message toast-message}]
:on-success [:wallet/delete-saved-address-success toast-message]
:on-error [:wallet/delete-saved-address-failed]}]]]}))
(rf/reg-event-fx :wallet/delete-saved-address delete-saved-address)
@@ -2,8 +2,7 @@
(:require
[cljs.test :refer-macros [deftest is testing]]
matcher-combinators.test
[status-im.contexts.settings.wallet.saved-addresses.events :as events]
[status-im.contexts.wallet.data-store :as data-store]))
[status-im.contexts.settings.wallet.saved-addresses.events :as events]))
(deftest get-saved-addresses-test
(testing "get saved addresses - dispatches RPC call"
@@ -16,7 +15,7 @@
:on-error [:wallet/saved-addresses-rpc-error :get-saved-addresses]}]]]]
(is (match? expected-fx result-fx)))))
(def saved-address-rpc-1
(def saved-address-1
{:isTest false
:address "0x1"
:mixedcaseAddress "0x1"
@@ -27,45 +26,21 @@
: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
{: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})
{:isTest true
:address "0x2"
:mixedcaseAddress "0x2"
:chainShortNames "eth:arb1:oeth:"
:name "Bob"
:createdAt 1716826714
:ens ""
:colorId "blue"
: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/reconcile-saved-addresses cofx nil)
effects (events/get-saved-addresses-success cofx nil)
result-db (:db effects)
expected-db {:wallet {:saved-addresses {:test {}
:prod {}}}}]
@@ -73,15 +48,15 @@
(testing "one test saved address"
(let [cofx {:db {}}
effects (events/reconcile-saved-addresses cofx [[saved-address-1]])
effects (events/get-saved-addresses-success cofx [[saved-address-2]])
result-db (:db effects)
expected-db {:wallet {:saved-addresses
{:test {"0x1" {:test? true
:address "0x1"
:mixedcase-address "0x1"
:chain-short-names "eth:oeth:"
{:test {"0x2" {:test? true
:address "0x2"
:mixedcase-address "0x2"
:chain-short-names "eth:arb1:oeth:"
:ens? false
:network-preferences-names `(:mainnet :optimism)
:network-preferences-names `(:mainnet :arbitrum :optimism)
:name "Bob"
:created-at 1716826714
:ens ""
@@ -92,73 +67,29 @@
(testing "two saved addresses (test and prod)"
(let [cofx {:db {}}
effects (events/reconcile-saved-addresses cofx [[saved-address-1 saved-address-2]])
effects (events/get-saved-addresses-success cofx [[saved-address-1 saved-address-2]])
result-db (:db effects)
expected-db {:wallet {:saved-addresses
{:test {"0x1" {:test? true
:address "0x1"
:mixedcase-address "0x1"
:chain-short-names "eth:oeth:"
{:test {"0x2" {:test? true
:address "0x2"
:mixedcase-address "0x2"
:chain-short-names "eth:arb1:oeth:"
:network-preferences-names `(:mainnet :arbitrum :optimism)
: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"
:prod {"0x1" {:test? false
:address "0x1"
:mixedcase-address "0x1"
:chain-short-names "eth:arb1:oeth:"
:network-preferences-names `(:mainnet :arbitrum :optimism)
:ens? true
:name "Alicia Keys"
:ens? false
:name "Amy"
:created-at 1716826806
: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"
:ens ""
:customization-color :purple
:removed? false}}}}}]
(is (match? expected-db result-db)))))
@@ -210,10 +141,7 @@
expected-fx [[:json-rpc/call
[{:method "wakuext_deleteSavedAddress"
:params [address test-networks-enabled?]
:on-success [:wallet/delete-saved-address-success
{:address address
:test-networks-enabled? test-networks-enabled?
:toast-message toast-message}]
:on-success [:wallet/delete-saved-address-success toast-message]
:on-error [:wallet/delete-saved-address-failed]}]]]]
(is (match? expected-fx result-fx)))))
@@ -109,7 +109,7 @@
:on-press open-show-address-qr
:accessibility-label :show-address-qr-code}
{:icon :i/edit
:label (i18n/label :t/edit-details)
:label (i18n/label :t/edit-account)
:blur? true
:on-press open-edit-saved-address
:accessibility-label :edit-saved-address}
+1 -1
View File
@@ -34,7 +34,7 @@
:WakuV2Config {;; Temporary fix until https://github.com/status-im/status-go/issues/3024
;; is resolved
:Nameserver "8.8.8.8"
:LightClient false}
:LightClient true}
:ShhextConfig {:VerifyTransactionURL config/verify-transaction-url
:VerifyENSURL config/verify-ens-url
:VerifyENSContractAddress config/verify-ens-contract-address
@@ -3,7 +3,6 @@
[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]
@@ -14,31 +13,19 @@
(rf/dispatch [:navigate-back]))
(defn open-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])}])}]))
[]
(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])
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)]
(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)]
[quo/overlay {:type :shell :top-inset? true}
[quo/page-nav
{:type :no-title
@@ -60,7 +47,7 @@
:type :primary
:customization-color profile-color
:icon-only? true
:on-press open-setup-syncing-with-customization-color}
:on-press open-setup-syncing}
:i/add]]
[device/view (merge user-device {:this-device? true})]
(when (seq paired-devices)
@@ -12,8 +12,8 @@
[utils.re-frame :as rf]))
(defn- on-collectible-press
[{:keys [id]} aspect-ratio]
(rf/dispatch [:wallet/get-collectible-details id aspect-ratio]))
[{:keys [id]}]
(rf/dispatch [:wallet/get-collectible-details id]))
(defn- on-collectible-long-press
[{:keys [preview-url collectible-details id]}]
@@ -103,8 +103,8 @@
(when activity-state
[quo/info-message
(assoc props
:container-style style/info-message
:size :default)
:style style/info-message
:size :default)
(i18n/label message)])))
(defn view
@@ -163,7 +163,7 @@
{:accessibility-label :error-message
:size :default
:icon :i/info
:status :error
:container-style style/info-message}
:type :error
:style style/info-message}
@validation-msg]
[activity-indicator])]]))))
[activity-indicator activity-state])]]))))
@@ -117,12 +117,12 @@
{:weight :monospace}
(:address derivation-path)]]
[quo/info-message
{:status (case state
:has-activity :success
:no-activity :warning
:default)
:icon (if (= state :scanning) :i/scanning :i/done)
:style style/info}
{:type (case state
:has-activity :success
:no-activity :warning
:default)
:icon (if (= state :scanning) :i/scanning :i/done)
:style style/info}
(i18n/label (case state
:has-activity :t/address-activity
:no-activity :t/address-no-activity
@@ -91,7 +91,7 @@
:error error}]
(when error
[quo/info-message
{:status :error
{:type :error
:size :default
:icon :i/info
:container-style style/error-container}
@@ -87,7 +87,7 @@
:container-style (style/title-input-container error)}]
(when error
[quo/info-message
{:status :error
{:type :error
:size :default
:icon :i/info
:container-style {:margin-left 20
@@ -167,13 +167,12 @@
(rf/reg-event-fx
:wallet/get-collectible-details
(fn [{:keys [db]} [collectible-id aspect-ratio]]
(fn [_ [collectible-id]]
(let [request-id 0
collectible-id-converted (cske/transform-keys transforms/->PascalCaseKeyword collectible-id)
data-type (collectible-data-types :details)
request-params [request-id [collectible-id-converted] data-type]]
{:db (assoc-in db [:wallet :last-collectible-aspect-ratio] aspect-ratio)
:fx [[:json-rpc/call
{:fx [[:json-rpc/call
[{:method "wallet_getCollectiblesByUniqueIDAsync"
:params request-params
:on-error (fn [error]
@@ -198,7 +197,7 @@
(rf/reg-event-fx
:wallet/clear-last-collectible-details
(fn [{:keys [db]}]
{:db (update-in db [:wallet] dissoc :last-collectible-details :last-collectible-aspect-ratio)}))
{:db (update-in db [:wallet] dissoc :last-collectible-details)}))
(rf/reg-event-fx :wallet/trigger-share-collectible
(fn [_ [{:keys [title uri]}]]
@@ -12,8 +12,8 @@
(defn preview-container
[]
{:padding-horizontal 8
:margin-top (+ (header-height) 12)})
{:margin-horizontal 8
:margin-top (+ (header-height) 12)})
(def header
{:margin-horizontal 20
@@ -150,7 +150,6 @@
set-title-ref (rn/use-callback #(reset! title-ref %))
animation-shared-element-id (rf/sub [:animation-shared-element-id])
collectible-owner (rf/sub [:wallet/last-collectible-details-owner])
aspect-ratio (rf/sub [:wallet/last-collectible-aspect-ratio])
{:keys [id
preview-url
collection-data
@@ -181,8 +180,7 @@
[rn/view
[gradient-layer preview-uri]
[quo/expanded-collectible
{:aspect-ratio aspect-ratio
:image-src preview-uri
{:image-src preview-uri
:container-style (style/preview-container)
:counter (utils/collectible-owned-counter total-owned)
:native-ID (when (= animation-shared-element-id token-id) :shared-element)
@@ -4,7 +4,6 @@
[status-im.contexts.wallet.sheets.account-options.view :as account-options]
[status-im.contexts.wallet.sheets.network-filter.view :as network-filter]
[status-im.contexts.wallet.sheets.select-account.view :as select-account]
[status-im.feature-flags :as ff]
[utils.re-frame :as rf]))
(defn get-bottom-sheet-args
@@ -37,7 +36,7 @@
:networks networks
:align-center? true
:networks-on-press #(rf/dispatch [:show-bottom-sheet {:content network-filter/view}])
:right-side [(when (and (ff/enabled? ::wallet.wallet-connect)
:right-side [(when (and true
(not watch-only?))
{:icon-name :i/dapps
:on-press #(rf/dispatch [:navigate-to :screen/wallet.connected-dapps])})
@@ -14,7 +14,7 @@
:as collectible}
index]
(let [on-press-fn (rn/use-callback #(when on-press
(on-press collectible %)))
(on-press collectible)))
on-long-press-fn (rn/use-callback #(when on-long-press
(on-long-press collectible)))]
[quo/collectible-list-item
@@ -62,7 +62,7 @@
:container-style (style/title-input-container error)}]
(when error
[quo/info-message
{:status :error
{:type :error
:size :default
:icon :i/info
:container-style {:margin-left 20
@@ -177,7 +177,7 @@
"This function returns token values in the props of token-value (quo) component"
[{:keys [token color currency currency-symbol]}]
(let [balance (calculate-total-token-balance token)
fiat-unformatted-value (calculate-token-fiat-value
fiat-value (calculate-token-fiat-value
{:currency currency
:balance balance
:token token})
@@ -191,7 +191,7 @@
crypto-value (get-standard-crypto-format token balance)
fiat-value (get-standard-fiat-format crypto-value
currency-symbol
fiat-unformatted-value)]
fiat-value)]
{:token (:symbol token)
:token-name (:name token)
:state :default
@@ -201,11 +201,10 @@
(neg? change-pct-24hour) :negative
:else :empty)
:customization-color color
:values {:crypto-value crypto-value
:fiat-value fiat-value
:fiat-unformatted-value fiat-unformatted-value
:fiat-change formatted-token-price
:percentage-change percentage-change}}))
:values {:crypto-value crypto-value
:fiat-value fiat-value
:fiat-change formatted-token-price
:percentage-change percentage-change}}))
(defn get-multichain-address
[networks address]
+1 -28
View File
@@ -5,7 +5,6 @@
[clojure.string :as string]
[status-im.constants :as constants]
[status-im.contexts.wallet.common.utils.networks :as network-utils]
[utils.collection :as utils.collection]
[utils.money :as money]
[utils.number :as utils.number]
[utils.transforms :as transforms]))
@@ -155,35 +154,9 @@
:colorId :customization-color
:mixedcaseAddress :mixedcase-address
:removed :removed?})
(update :customization-color (comp keyword string/lower-case))
(update :customization-color keyword)
add-keys-to-saved-address))
(defn rpc->saved-addresses
[saved-addresses]
(map rpc->saved-address saved-addresses))
(defn reconcile-keypairs
[keypairs]
(let [received-keypairs (rpc->keypairs keypairs)
keypair-label #(if % :removed-keypairs :updated-keypairs)
{:keys [removed-keypairs
updated-keypairs]
:or {updated-keypairs []
removed-keypairs []}} (group-by (comp keypair-label :removed) received-keypairs)
updated-keypairs-by-id (utils.collection/index-by :key-uid updated-keypairs)
updated-accounts-by-address (transduce (comp (mapcat :accounts)
(filter (comp not :chat))
(map #(vector (:address %) %)))
conj
{}
updated-keypairs)
removed-keypairs-ids (set (map :key-uid removed-keypairs))
removed-account-addresses (transduce (comp (mapcat :accounts)
(map :address))
conj
#{}
removed-keypairs)]
{:removed-keypair-ids removed-keypairs-ids
:removed-account-addresses removed-account-addresses
:updated-keypairs-by-id updated-keypairs-by-id
:updated-accounts-by-address updated-accounts-by-address}))
@@ -1,240 +0,0 @@
(ns status-im.contexts.wallet.data-store-test
(:require
[cljs.test :refer-macros [deftest is testing]]
[matcher-combinators.matchers :as matchers]
matcher-combinators.test
[status-im.contexts.wallet.data-store :as sut]))
(def raw-account
{:path "m/44'/60'/0'/0/0"
:name "Account name"
:wallet true
:chat false
:emoji "🍙"
:colorId "blue"
:type "generated"
:createdAt 1716548742000
:prodPreferredChainIds "1:42161"
:testPreferredChainIds "11155111:421614"
:removed false
:operable "fully"})
(def account
{:path "m/44'/60'/0'/0/0"
:emoji "🍙"
:color :blue
:wallet true
:default-account? true
:name "Account name"
:type :generated
:chat false
:test-preferred-chain-ids #{11155111 421614}
:watch-only? false
:prod-preferred-chain-ids #{1 42161}
:created-at 1716548742000
:operable :fully
:removed false})
(defn make-raw-account
[overrides]
(merge raw-account overrides))
(def raw-keypair-profile
{:type "profile"
:key-uid "0x000"
:accounts [(make-raw-account {:key-uid "0x000"
:address "1x000"
:wallet false
:chat true})
(make-raw-account {:key-uid "0x000"
:address "2x000"})]})
(def raw-keypair-seed-phrase
{:type "seed"
:key-uid "0x123"
:accounts [(make-raw-account {:key-uid "0x123"
:address "1x123"})]})
(def raw-keypair-private-key
{:type "key"
:key-uid "0x456"
:accounts [(make-raw-account {:key-uid "0x456"
:address "1x456"
:operable "no"})]})
(deftest chain-ids-string->set-test
(testing "chaind-ids-string->set splits and parses chain-ids from string"
(is (match? #{1 42161}
(sut/chain-ids-string->set (:prodPreferredChainIds raw-account))))
(is (match? #{11155111 421614}
(sut/chain-ids-string->set (:testPreferredChainIds raw-account))))))
(deftest rpc->keypair-test
(testing "rpc->keypair transforms a profile keypair"
(is
(match? {:type :profile
:key-uid "0x000"
:lowest-operability :fully
:accounts [{:key-uid "0x000"
:operable :fully
:chat true
:wallet false
:address "1x000"
:path (:path raw-account)
:name (:name raw-account)
:emoji (:emoji raw-account)
:removed (:removed raw-account)
:color (keyword (:colorId raw-account))
:created-at (:createdAt raw-account)
:prod-preferred-chain-ids (sut/chain-ids-string->set
(:prodPreferredChainIds raw-account))
:test-preferred-chain-ids (sut/chain-ids-string->set
(:testPreferredChainIds raw-account))}
{:key-uid "0x000"
:operable :fully
:chat false
:wallet true
:address "2x000"
:path (:path raw-account)
:name (:name raw-account)
:emoji (:emoji raw-account)
:removed (:removed raw-account)
:color (keyword (:colorId raw-account))
:created-at (:createdAt raw-account)
:prod-preferred-chain-ids (sut/chain-ids-string->set
(:prodPreferredChainIds raw-account))
:test-preferred-chain-ids (sut/chain-ids-string->set
(:testPreferredChainIds raw-account))}]}
(sut/rpc->keypair raw-keypair-profile))))
(testing "rpc->keypair transforms a seed-phrase keypair"
(is
(match? {:type :seed
:key-uid "0x123"
:lowest-operability :fully
:accounts [{:key-uid "0x123"
:address "1x123"
:operable :fully
:path (:path raw-account)
:name (:name raw-account)
:emoji (:emoji raw-account)
:wallet (:wallet raw-account)
:removed (:removed raw-account)
:color (keyword (:colorId raw-account))
:created-at (:createdAt raw-account)
:prod-preferred-chain-ids (sut/chain-ids-string->set
(:prodPreferredChainIds raw-account))
:test-preferred-chain-ids (sut/chain-ids-string->set
(:testPreferredChainIds raw-account))}]}
(sut/rpc->keypair raw-keypair-seed-phrase))))
(testing "rpc->keypair transforms a raw private-key keypair with inoperable accounts"
(is
(match? {:type :key
:key-uid "0x456"
:lowest-operability :no
:accounts [{:key-uid "0x456"
:address "1x456"
:operable :no
:path (:path raw-account)
:name (:name raw-account)
:emoji (:emoji raw-account)
:wallet (:wallet raw-account)
:removed (:removed raw-account)
:color (keyword (:colorId raw-account))
:created-at (:createdAt raw-account)
:prod-preferred-chain-ids (sut/chain-ids-string->set
(:prodPreferredChainIds raw-account))
:test-preferred-chain-ids (sut/chain-ids-string->set
(:testPreferredChainIds
raw-account))}]}
(sut/rpc->keypair raw-keypair-private-key)))))
(deftest rpc->keypairs-test
(testing "rpc->keypairs transforms and sorts raw keypairs"
(is
(match? [(sut/rpc->keypair raw-keypair-profile)
(sut/rpc->keypair raw-keypair-seed-phrase)
(sut/rpc->keypair raw-keypair-private-key)]
(sut/rpc->keypairs [raw-keypair-seed-phrase
raw-keypair-private-key
raw-keypair-profile])))))
(deftest reconcile-keypairs-test
(testing "reconcile-keypairs represents updated key pairs and accounts"
(is
(match?
(matchers/match-with
[set? matchers/set-equals
map? matchers/equals]
{:removed-keypair-ids #{}
:removed-account-addresses #{}
:updated-accounts-by-address {"1x123" (merge account
{:key-uid "0x123"
:address "1x123"})
"1x456" (merge account
{:key-uid "0x456"
:address "1x456"
:operable :no})}
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
:type :seed
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x123"
:address "1x123"})]}
"0x456" {:key-uid "0x456"
:type :key
:lowest-operability :no
:accounts [(merge account
{:key-uid "0x456"
:address "1x456"
:operable :no})]}}})
(sut/reconcile-keypairs [raw-keypair-seed-phrase
raw-keypair-private-key]))))
(testing "reconcile-keypairs represents removed key pairs and accounts"
(is
(match?
(matchers/match-with
[set? matchers/set-equals
map? matchers/equals]
{:removed-keypair-ids #{"0x456"}
:removed-account-addresses #{"1x456"}
:updated-accounts-by-address {"1x123" (merge account
{:key-uid "0x123"
:address "1x123"})}
:updated-keypairs-by-id {"0x123" {:key-uid "0x123"
:type :seed
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x123"
:address "1x123"})]}}})
(sut/reconcile-keypairs [raw-keypair-seed-phrase
(assoc raw-keypair-private-key :removed true)]))))
(testing "reconcile-keypairs ignores chat accounts inside updated accounts"
(is
(match?
(matchers/match-with
[set? matchers/set-equals
map? matchers/equals]
{:removed-keypair-ids #{}
:removed-account-addresses #{}
:updated-accounts-by-address {"2x000" (merge account
{:key-uid "0x000"
:address "2x000"
:chat false
:wallet true
:default-account? true})}
:updated-keypairs-by-id {"0x000" {:key-uid "0x000"
:type :profile
:lowest-operability :fully
:accounts [(merge account
{:key-uid "0x000"
:address "1x000"
:chat true
:wallet false
:default-account? false})
(merge account
{:key-uid "0x000"
:address "2x000"
:chat false
:wallet true
:default-account? true})]}}})
(sut/reconcile-keypairs [raw-keypair-profile])))))
+8 -90
View File
@@ -1,7 +1,6 @@
(ns status-im.contexts.wallet.events
(:require
[camel-snake-kebab.extras :as cske]
[clojure.set]
[clojure.string :as string]
[react-native.platform :as platform]
[status-im.constants :as constants]
@@ -82,11 +81,6 @@
(rf/reg-event-fx :wallet/log-rpc-error log-rpc-error)
(def refresh-accounts-fx-dispatches
[[:dispatch [:wallet/get-wallet-token-for-all-accounts]]
[:dispatch [:wallet/request-collectibles-for-all-accounts {:new-request? true}]]
[:dispatch [:wallet/check-recent-history-for-all-accounts]]])
(rf/reg-event-fx
:wallet/get-accounts-success
(fn [{:keys [db]} [accounts]]
@@ -97,9 +91,11 @@
{:db (assoc-in db
[:wallet :accounts]
(utils.collection/index-by :address wallet-accounts))
:fx (concat refresh-accounts-fx-dispatches
[(when new-account?
[:dispatch [:wallet/navigate-to-new-account navigate-to-account]])])})))
:fx [[:dispatch [:wallet/get-wallet-token-for-all-accounts]]
[:dispatch [:wallet/request-collectibles-for-all-accounts {:new-request? true}]]
[:dispatch [:wallet/check-recent-history-for-all-accounts]]
(when new-account?
[:dispatch [:wallet/navigate-to-new-account navigate-to-account]])]})))
(rf/reg-event-fx
:wallet/get-accounts
@@ -313,7 +309,7 @@
[]
(filter #(string/starts-with? (or (:ens-name %) "") input) contacts))]
(if (and input (empty? result))
{:fx [[:dispatch [:wallet/search-ens input on-error-fn ".stateofus.eth"]]]}
(rf/dispatch [:wallet/search-ens input on-error-fn ".stateofus.eth"])
{:db (-> db
(assoc-in [:wallet :ui :search-address :local-suggestions]
(map #(assoc % :type item-types/saved-address) result))
@@ -362,15 +358,11 @@
(rf/reg-event-fx :wallet/address-validation-success
(fn [{:keys [db]}]
{:db (-> db
(assoc-in [:wallet :ui :search-address :valid-ens-or-address?] true)
(assoc-in [:wallet :ui :search-address :loading?] false))}))
{:db (assoc-in db [:wallet :ui :search-address :valid-ens-or-address?] true)}))
(rf/reg-event-fx :wallet/address-validation-failed
(fn [{:keys [db]}]
{:db (-> db
(assoc-in [:wallet :ui :search-address :valid-ens-or-address?] false)
(assoc-in [:wallet :ui :search-address :loading?] false))}))
{:db (assoc-in db [:wallet :ui :search-address :valid-ens-or-address?] false)}))
(rf/reg-event-fx :wallet/clean-local-suggestions
(fn [{:keys [db]}]
@@ -378,10 +370,6 @@
(assoc-in [:wallet :ui :search-address :local-suggestions] [])
(assoc-in [:wallet :ui :search-address :valid-ens-or-address?] false))}))
(rf/reg-event-fx :wallet/searching-address
(fn [{:keys [db]}]
{:db (assoc-in db [:wallet :ui :search-address :loading?] true)}))
(rf/reg-event-fx
:wallet/navigate-to-chain-explorer-from-bottom-sheet
(fn [_ [explorer-link address]]
@@ -557,73 +545,3 @@
:wallet/process-watch-only-account-from-backup
(fn [_ [{:keys [backedUpWatchOnlyAccount]}]]
{:fx [[:dispatch [:wallet/process-account-from-signal backedUpWatchOnlyAccount]]]}))
(defn reconcile-watch-only-accounts
[{:keys [db]} [watch-only-accounts]]
(let [existing-accounts-by-address (get-in db [:wallet :accounts])
group-label #(if % :removed-accounts :updated-accounts)
{:keys [removed-accounts
updated-accounts]} (->> watch-only-accounts
(map data-store/rpc->account)
(group-by (comp group-label :removed)))
existing-account-addresses (set (keys existing-accounts-by-address))
removed-account-addresses (set (map :address removed-accounts))
updated-account-addresses (set (map :address updated-accounts))
new-account-addresses (clojure.set/difference updated-account-addresses
existing-account-addresses)]
{:db (update-in db
[:wallet :accounts]
(fn [existing-accounts]
(merge-with merge
(apply dissoc existing-accounts removed-account-addresses)
(utils.collection/index-by :address updated-accounts))))
:fx (mapcat (fn [address]
[[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch
[:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]])
new-account-addresses)}))
(rf/reg-event-fx :wallet/reconcile-watch-only-accounts reconcile-watch-only-accounts)
(defn reconcile-keypairs
[{:keys [db]} [keypairs]]
(let [existing-keypairs-by-id (get-in db [:wallet :keypairs])
existing-accounts-by-address (get-in db [:wallet :accounts])
{:keys [removed-keypair-ids
removed-account-addresses
updated-keypairs-by-id
updated-accounts-by-address]} (data-store/reconcile-keypairs keypairs)
updated-keypair-ids (set (keys updated-keypairs-by-id))
updated-account-addresses (set (keys updated-accounts-by-address))
existing-account-addresses (set (keys existing-accounts-by-address))
new-account-addresses (clojure.set/difference updated-account-addresses
existing-account-addresses)
old-account-addresses (->> (vals existing-accounts-by-address)
(filter (fn [{:keys [address key-uid]}]
(and (contains? updated-keypair-ids key-uid)
(not (contains?
updated-accounts-by-address
address)))))
(map :address))]
(cond-> {:db (-> db
(assoc-in [:wallet :keypairs]
(-> (apply dissoc existing-keypairs-by-id removed-keypair-ids)
(merge updated-keypairs-by-id)))
(assoc-in [:wallet :accounts]
(merge-with merge
(apply dissoc
existing-accounts-by-address
(into removed-account-addresses
old-account-addresses))
updated-accounts-by-address)))}
(seq new-account-addresses)
(assoc :fx
(mapcat (fn [address]
[[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch
[:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]])
new-account-addresses)))))
(rf/reg-event-fx :wallet/reconcile-keypairs reconcile-keypairs)
@@ -1,7 +1,6 @@
(ns status-im.contexts.wallet.events-test
(:require
[cljs.test :refer-macros [is testing]]
[matcher-combinators.matchers :as matchers]
matcher-combinators.test
[re-frame.db :as rf-db]
[status-im.constants :as constants]
@@ -151,187 +150,3 @@
[:dispatch [:wallet/check-recent-history-for-account address]]]}]
(reset! rf-db/app-db {:wallet {:accounts {}}})
(is (match? expected-effects (dispatch [event-id raw-account])))))
(h/deftest-event :wallet/reconcile-keypairs
[event-id dispatch]
(let [keypair-key-uid (:key-uid raw-account)]
(testing "event adds new key pairs"
(reset! rf-db/app-db {:wallet {:accounts {}
:keypairs {}}})
(is
(match?
(matchers/match-with
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {(:address account) account}
:keypairs {keypair-key-uid {:key-uid keypair-key-uid
:type :seed
:lowest-operability :fully
:accounts [account]}}}}
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch [:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]]})
(dispatch [event-id
[{:key-uid keypair-key-uid
:type "seed"
:accounts [raw-account]}]]))))
(testing "event removes key pairs and accounts that are marked as removed"
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account}
:keypairs {keypair-key-uid
{:key-uid keypair-key-uid
:type :seed
:lowest-operability :fully
:accounts [account]}}}})
(is
(match?
(matchers/match-with
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {}
:keypairs {}}}})
(dispatch [event-id
[{:key-uid keypair-key-uid
:type "seed"
:removed true
:accounts [raw-account]}]]))))
(testing "event removes accounts not present with key pair"
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account
"1x001" (assoc account
:address "1x001"
:key-uid "0x001")}
:keypairs {keypair-key-uid
{:key-uid keypair-key-uid
:type :seed
:lowest-operability :fully
:accounts [account]}
"0x001"
{:key-uid "0x001"
:type :seed
:lowest-operability :fully
:accounts [(assoc account
:address "1x001"
:key-uid "0x001")]}}}})
(is
(match?
(matchers/match-with
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {(:address account) account}
:keypairs {keypair-key-uid
{:key-uid keypair-key-uid
:type :seed
:lowest-operability :fully
:accounts [account]}
"0x001"
{:key-uid "0x001"
:type :seed
:lowest-operability :fully
:accounts []}}}}})
(dispatch [event-id
[{:key-uid "0x001"
:type "seed"
:accounts []}]]))))
(testing "event updates existing key pairs"
(reset! rf-db/app-db {:wallet
{:accounts {(:address account)
(assoc account :operable :no)}
:keypairs {keypair-key-uid
{:key-uid keypair-key-uid
:type :seed
:lowest-operability :no
:accounts [(assoc account :operable :no)]}}}})
(is
(match?
(matchers/match-with
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {(:address account) account}
:keypairs {keypair-key-uid
{:key-uid keypair-key-uid
:type :seed
:lowest-operability :fully
:accounts [account]}}}}})
(dispatch [event-id
[{:key-uid keypair-key-uid
:type "seed"
:accounts [raw-account]}]]))))
(testing "event ignores chat accounts for key pairs"
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account}
:keypairs {keypair-key-uid
{:key-uid keypair-key-uid
:type :profile
:lowest-operability :fully
:accounts [account
(assoc account
:address "1x001"
:chat true)]}}}})
(is
(match?
(matchers/match-with
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {(:address account) account}
:keypairs {keypair-key-uid
{:key-uid keypair-key-uid
:type :profile
:lowest-operability :fully
:accounts [account
(assoc account
:address "1x001"
:chat true)]}}}}})
(dispatch [event-id
[{:key-uid keypair-key-uid
:type "profile"
:accounts [raw-account
(assoc raw-account
:address "1x001"
:chat true)]}]]))))))
(h/deftest-event :wallet/reconcile-watch-only-accounts
[event-id dispatch]
(testing "event adds new watch-only accounts"
(reset! rf-db/app-db {:wallet {:accounts {}}})
(is
(match?
(matchers/match-with
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {(:address account) account}}}
:fx [[:dispatch [:wallet/get-wallet-token-for-account address]]
[:dispatch
[:wallet/request-new-collectibles-for-account-from-signal address]]
[:dispatch [:wallet/check-recent-history-for-account address]]]})
(dispatch [event-id [raw-account]]))))
(testing "event removes watch-only accounts that are marked as removed"
(reset! rf-db/app-db {:wallet {:accounts {(:address account) account}}})
(is
(match?
(matchers/match-with
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {}}}
:fx []})
(dispatch [event-id [(assoc raw-account :removed true)]]))))
(testing "event updates existing watch-only accounts"
(reset! rf-db/app-db {:wallet
{:accounts {address account}}})
(is
(match?
(matchers/match-with
[set? matchers/set-equals
vector? matchers/equals
map? matchers/equals]
{:db {:wallet {:accounts {address (assoc account :name "Test")}}}
:fx []})
(dispatch [event-id
[(assoc raw-account
:address address
:name "Test")]])))))
(cljs.test/run-tests)

Some files were not shown because too many files have changed in this diff Show More