Compare commits
56
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a8408b4fff | ||
|
|
55a99da2f5 | ||
|
|
6093d56c90 | ||
|
|
9cf4556b9d | ||
|
|
536ebf56cb | ||
|
|
3ad345519b | ||
|
|
dc587e493f | ||
|
|
f692ae2222 | ||
|
|
aa89ebdb93 | ||
|
|
198a4d74a5 | ||
|
|
3b5fe36717 | ||
|
|
03444ae4ff | ||
|
|
390bbdb6ec | ||
|
|
2bc7b62324 | ||
|
|
4376ee8908 | ||
|
|
195f0cfa40 | ||
|
|
ab61d8d5c0 | ||
|
|
aaf0b8e423 | ||
|
|
7e14846f0b | ||
|
|
5ebd133c63 | ||
|
|
563f1c588d | ||
|
|
6b612588c4 | ||
|
|
6ef113e821 | ||
|
|
c25f44c2a0 | ||
|
|
d039864dca | ||
|
|
a4f1f23d3c | ||
|
|
fe20fa4e99 | ||
|
|
5c30fd847a | ||
|
|
64de325678 | ||
|
|
489557c1a3 | ||
|
|
439fdfa12c | ||
|
|
f695dbf115 | ||
|
|
7c45b1e075 | ||
|
|
64453716b0 | ||
|
|
56d135f1f8 | ||
|
|
a7178a4950 | ||
|
|
3cd302b271 | ||
|
|
1e797273b6 | ||
|
|
8ff67bf344 | ||
|
|
3fee21c73a | ||
|
|
f9f328107d | ||
|
|
04dee8be45 | ||
|
|
52f7fc59ee | ||
|
|
b5202b4d28 | ||
|
|
210cf64ce0 | ||
|
|
ed270b2162 | ||
|
|
d412fa3c63 | ||
|
|
b7f675aa5c | ||
|
|
bfa23c182f | ||
|
|
6b721265af | ||
|
|
589a581298 | ||
|
|
0546a87e9a | ||
|
|
e5ce7fed3a | ||
|
|
58d5c3d7a5 | ||
|
|
6ccea1ddb2 | ||
|
|
a9a17aaae8 |
@@ -95,7 +95,6 @@ react-native.fs/unlink
|
||||
react-native.fs/file-exists?
|
||||
status-im.ui.components.colors/white
|
||||
status-im.ui.components.colors/black
|
||||
status-im.transport.core-test/messages
|
||||
status-im.ui.components.core/animated-header
|
||||
status-im.ui.components.core/safe-area-provider
|
||||
status-im.ui.components.core/safe-area-consumer
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
{:linters
|
||||
{:unresolved-symbol
|
||||
{:exclude [(cljs.test/is [match? thrown-match?])
|
||||
(clojure.test/is [match? thrown-match?])]}}}
|
||||
@@ -32,6 +32,7 @@
|
||||
"letsubs" :binding
|
||||
"with-let" "let"
|
||||
"reg-event-fx" :arg1-pair
|
||||
"reg-fx" :arg1-pair
|
||||
"testing" :arg1-body
|
||||
"deftest-sub" :arg1-body
|
||||
"wait-for" :arg1-body
|
||||
|
||||
@@ -27,18 +27,23 @@ class StatusOkHttpClientFactory implements OkHttpClientFactory {
|
||||
X509Certificate cert = null;
|
||||
HandshakeCertificates clientCertificates;
|
||||
String certPem = "";
|
||||
// Get TLS PEM certificate from status-go
|
||||
try {
|
||||
// induce half second sleep because sometimes a cert is not immediately available
|
||||
// TODO : remove sleep if App no longer crashes on Android 10 devices with
|
||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||
Thread.sleep(500);
|
||||
certPem = getCertificatePem();
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "Could not getImageTLSCert",e);
|
||||
}
|
||||
|
||||
// Get TLS PEM certificate from status-go
|
||||
try {
|
||||
// induce half second sleep because sometimes a cert is not immediately available
|
||||
// TODO : remove sleep if App no longer crashes on Android 10 devices with
|
||||
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
|
||||
Thread.sleep(500);
|
||||
certPem = StatusPackage.getImageTLSCert();
|
||||
} catch(Exception e) {
|
||||
Log.e(TAG, "Could not getImageTLSCert",e);
|
||||
}
|
||||
// Convert PEM certificate string to X509Certificate object
|
||||
if (certPem.isEmpty()) {
|
||||
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Convert PEM certificate string to X509Certificate object
|
||||
try {
|
||||
// induce half second sleep because sometimes a cert is not immediately available
|
||||
// TODO : remove sleep if App no longer crashes on Android 10 devices
|
||||
@@ -74,4 +79,17 @@ class StatusOkHttpClientFactory implements OkHttpClientFactory {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
private String getCertificatePem() {
|
||||
try {
|
||||
String certPem = StatusPackage.getImageTLSCert();
|
||||
if (certPem == null || certPem.trim().isEmpty()) {
|
||||
Log.e(TAG, "Certificate PEM string is null or empty");
|
||||
return "";
|
||||
}
|
||||
return certPem;
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not getImageTLSCert", e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,6 @@ pipeline {
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
when { expression { !utils.isReleaseBuild() } }
|
||||
steps { script {
|
||||
env.DIAWI_URL = ios.uploadToDiawi()
|
||||
env.PKG_URL = env.DIAWI_URL
|
||||
|
||||
+21
-1
@@ -641,6 +641,26 @@ keywords and concatenating them into a single string.
|
||||
```
|
||||
|
||||
### Tests
|
||||
#### Prefer `match?` over `=` when comparing data structures
|
||||
|
||||
Prefer the `match?` directive over `=` when comparing data structures, otherwise
|
||||
when the check fails the output can be too difficult to read. `match?` is
|
||||
defined by library https://github.com/nubank/matcher-combinators.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(deftest some-test
|
||||
(let [expected {...}
|
||||
actual {...}]
|
||||
(is (= expected actual))))
|
||||
|
||||
;; good
|
||||
(deftest some-test
|
||||
(let [expected {...}
|
||||
actual {...}]
|
||||
(is (match? expected actual))))
|
||||
```
|
||||
|
||||
#### Subscription tests
|
||||
|
||||
Test [layer-3 subscriptions](https://day8.github.io/re-frame/subscriptions/) by
|
||||
@@ -716,7 +736,7 @@ src
|
||||
|
||||
- `src/js`: Raw Javascript files, e.g. React Native Reanimated worklets.
|
||||
- `src/mocks`: Plumbing configuration to be able to run tests.
|
||||
- `src/quo/`: The component library for Status Mobile.
|
||||
- `src/quo/`: The component library for Status Mobile. [Read more...](../src/quo/README.md)
|
||||
- `src/react_native/`: Contains only low-level constructs to help React Native
|
||||
work in tandem with Clojure(Script).
|
||||
- `src/status_im2/`: Directory where we try to be as strict as possible about
|
||||
|
||||
@@ -602,6 +602,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "4c94bd510f0c18a20191e46dd6becedebc640bbd",
|
||||
"sha256": "0wpla2hx0s4mda58ndyd8938zmnz1gyhgfr6pzfphy27xfbvsssl"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/ant/ant/1.10.11/ant-1.10.11",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -746,6 +755,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "aa95d25ea98bfe1152ea540f6e58a303c8cacc86",
|
||||
"sha256": "0qvdsr5ryjmrpz622ivpyq5aayn42y4bk531vbasyj2yj7gcg35h"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
|
||||
@@ -65,6 +65,7 @@ net/cgrand/macrovich/0.2.1/macrovich-0.2.1.jar
|
||||
net/java/dev/jna/jna/5.12.1/jna-5.12.1.jar
|
||||
nrepl/bencode/1.1.0/bencode-1.1.0.jar
|
||||
nrepl/nrepl/1.0.0/nrepl-1.0.0.jar
|
||||
nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8.jar
|
||||
org/apache/ant/ant/1.10.11/ant-1.10.11.jar
|
||||
org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11.jar
|
||||
org/babashka/sci/0.7.38/sci-0.7.38.jar
|
||||
@@ -81,6 +82,7 @@ org/clojure/data.json/2.4.0/data.json-2.4.0.jar
|
||||
org/clojure/data.priority-map/1.1.0/data.priority-map-1.1.0.jar
|
||||
org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar
|
||||
org/clojure/google-closure-library-third-party/0.0-20230227-c7c0a541/google-closure-library-third-party-0.0-20230227-c7c0a541.jar
|
||||
org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0.jar
|
||||
org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar
|
||||
org/clojure/test.check/1.1.1/test.check-1.1.1.jar
|
||||
org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0.jar
|
||||
|
||||
@@ -14,6 +14,7 @@ stdenv.mkDerivation {
|
||||
"patchJavaPhase"
|
||||
"patchReactNativePhase"
|
||||
"patchPodPhase"
|
||||
"patchGlogPhase"
|
||||
"installPhase"
|
||||
];
|
||||
|
||||
@@ -98,6 +99,14 @@ stdenv.mkDerivation {
|
||||
'[RCTConvert UIColor:options.tintColor() ? @(*options.tintColor()) : nil];'
|
||||
'';
|
||||
|
||||
# Fix pod issue after upgrading to MacOS Sonoma and Xcode 15
|
||||
# https://github.com/status-im/status-mobile/issues/17682
|
||||
patchGlogPhase = ''
|
||||
substituteInPlace ./node_modules/react-native/scripts/ios-configure-glog.sh \
|
||||
--replace 'export CC="' '#export CC="' \
|
||||
--replace 'export CXX="' '#export CXX="'
|
||||
'';
|
||||
|
||||
# The ELF types are incompatible with the host platform, so let's not even try
|
||||
# TODO: Use Android NDK to strip binaries manually
|
||||
dontPatchELF = true;
|
||||
|
||||
@@ -73,6 +73,7 @@ in {
|
||||
allowHigher = true;
|
||||
};
|
||||
go = super.go_1_19;
|
||||
clang = super.clang_15;
|
||||
buildGoPackage = super.buildGo119Package;
|
||||
buildGoModule = super.buildGo119Module;
|
||||
gomobile = (super.gomobile.overrideAttrs (old: {
|
||||
|
||||
+1
-1
@@ -94,7 +94,7 @@
|
||||
"process": "0.11.10",
|
||||
"react-test-renderer": "18.0.0",
|
||||
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#refs/tags/v2.0.2-status",
|
||||
"shadow-cljs": "2.25.0"
|
||||
"shadow-cljs": "2.26.2"
|
||||
},
|
||||
"binary": {
|
||||
"module_name": "status_nodejs_addon",
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 851 B |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.1 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
+4
-2
@@ -12,10 +12,12 @@
|
||||
[metosin/malli "0.13.0"]
|
||||
|
||||
;; Dev dependencies
|
||||
[refactor-nrepl "2.5.0"]
|
||||
[cider/cider-nrepl "0.25.3"]
|
||||
[refactor-nrepl "3.9.1"]
|
||||
[cider/cider-nrepl "0.31.0"]
|
||||
[cider/piggieback "0.4.1"]
|
||||
[org.slf4j/slf4j-nop "2.0.9"]
|
||||
[re-frisk-remote "1.6.0"]
|
||||
[nubank/matcher-combinators "3.8.8"]
|
||||
|
||||
;; Use the same version specified in the Nix dependency.
|
||||
[clj-kondo/clj-kondo "2023.09.07"]
|
||||
|
||||
@@ -40,23 +40,6 @@
|
||||
config
|
||||
#(callback (types/json->clj %))))
|
||||
|
||||
(defn save-account-and-login
|
||||
"NOTE: beware, the password has to be sha3 hashed"
|
||||
[key-uid multiaccount-data hashed-password settings config accounts-data]
|
||||
(log/debug "[native-module] save-account-and-login"
|
||||
"multiaccount-data"
|
||||
multiaccount-data)
|
||||
(clear-web-data)
|
||||
(init-keystore
|
||||
key-uid
|
||||
#(.saveAccountAndLogin
|
||||
^js (status)
|
||||
multiaccount-data
|
||||
hashed-password
|
||||
settings
|
||||
config
|
||||
accounts-data)))
|
||||
|
||||
(defn save-multiaccount-and-login-with-keycard
|
||||
"NOTE: chat-key is a whisper private key sent from keycard"
|
||||
[key-uid multiaccount-data password settings config accounts-data chat-key]
|
||||
|
||||
@@ -116,6 +116,17 @@ rendered. We use [React Native Testing Library](https://callstack.github.io/reac
|
||||
There are dozens of examples in the repository, so use them as a reference. A
|
||||
good and complete example is [quo.components.avatars.user-avatar.component-spec](/src/quo/components/avatars/user_avatar/component_spec.cljs)
|
||||
|
||||
### No-props test
|
||||
|
||||
When writing tests for the component that has props, please add one test that covers situation when props aren't passed. Because even if component not showing anything meaningful without props, it shouldn't crash.
|
||||
|
||||
```clojure
|
||||
(h/describe "Transaction Progress"
|
||||
(h/test "component renders without props"
|
||||
(h/render [quo/transaction-progress {}])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
```
|
||||
|
||||
## Do not couple the library with re-frame
|
||||
|
||||
Don't use re-frame inside this library (e.g. dispatch & subscribe). If a
|
||||
|
||||
@@ -30,6 +30,6 @@
|
||||
{:accessibility-label :account-emoji
|
||||
:adjusts-font-size-to-fit true
|
||||
:style {:font-size emoji-size}}
|
||||
(string/trim emoji)]]))
|
||||
(when emoji (string/trim emoji))]]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -67,7 +67,7 @@
|
||||
[rn/text
|
||||
{:style (style/emoji-size size)
|
||||
:accessibility-label :emoji}
|
||||
(string/trim emoji)])
|
||||
(when emoji (string/trim emoji))])
|
||||
[lock locked? size theme]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -56,6 +56,6 @@
|
||||
:size (:font-size (size properties))
|
||||
:weight (if monospace? :monospace (:font-weight (size properties)))
|
||||
:style (style/text customization-color neutral? theme)}
|
||||
(if lowercase? (string/lower-case initials) initials)]]))
|
||||
(if (and initials lowercase?) (string/lower-case initials) initials)]]))
|
||||
|
||||
(def wallet-user-avatar (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
(ns quo.components.dropdowns.dropdown-input.component-spec
|
||||
(:require
|
||||
[quo.components.dropdowns.dropdown-input.view :as dropdown-input]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Dropdown Input"
|
||||
|
||||
(h/test "default render"
|
||||
(let [header-label "Label"
|
||||
label "Dropdown"]
|
||||
(h/render [dropdown-input/view
|
||||
{:label? true
|
||||
:header-label
|
||||
header-label} label])
|
||||
(h/is-truthy (h/get-by-label-text :dropdown))
|
||||
(h/is-truthy (h/get-by-text header-label))
|
||||
(h/is-truthy (h/get-by-text label))))
|
||||
|
||||
(h/test "render with icon"
|
||||
(let [label "Dropdown"]
|
||||
(h/render [dropdown-input/view
|
||||
{:icon? true
|
||||
:icon-name
|
||||
:i/wallet
|
||||
:label? true}
|
||||
label])
|
||||
(h/is-truthy (h/get-by-label-text :dropdown))
|
||||
(h/is-truthy (h/get-by-label-text :left-icon))
|
||||
(h/is-truthy (h/get-by-text label))))
|
||||
|
||||
(h/test "render in active state"
|
||||
(let [label "Dropdown"]
|
||||
(h/render [dropdown-input/view
|
||||
{:state :active
|
||||
:label?
|
||||
true} label])
|
||||
(h/is-truthy (h/get-by-label-text :dropdown))
|
||||
(h/is-truthy (h/get-by-label-text :right-icon "Expecting active state icon"))))
|
||||
|
||||
(h/test "render in disabled state"
|
||||
(let [label "Dropdown"]
|
||||
(h/render [dropdown-input/view
|
||||
{:state :disabled
|
||||
:label? true} label])
|
||||
(h/is-truthy (h/get-by-label-text :dropdown))
|
||||
(h/is-disabled (h/get-by-text label "Dropdown should be disabled in disabled state"))))
|
||||
|
||||
(h/test "on-press"
|
||||
(let [event (h/mock-fn)
|
||||
label "Dropdown"]
|
||||
(h/render [dropdown-input/view
|
||||
{:on-press event
|
||||
:label?
|
||||
true} label])
|
||||
(h/fire-event :press (h/get-by-text label))
|
||||
(h/was-called event))))
|
||||
@@ -0,0 +1,49 @@
|
||||
(ns quo.components.dropdowns.dropdown-input.properties
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def icon-size 20)
|
||||
|
||||
(defn- grey-blur
|
||||
[theme active?]
|
||||
{:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
|
||||
:right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if active?
|
||||
(colors/theme-colors colors/neutral-80-opa-20
|
||||
colors/white-opa-40
|
||||
theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-10
|
||||
colors/white-opa-10
|
||||
theme))})
|
||||
|
||||
(defn- outline
|
||||
[theme active?]
|
||||
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if active?
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))})
|
||||
|
||||
(defn- grey
|
||||
[theme active?]
|
||||
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:border-color (if active?
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
(colors/theme-colors colors/neutral-20
|
||||
colors/neutral-60
|
||||
theme))})
|
||||
|
||||
(defn get-colors
|
||||
[{:keys [theme state blur?]}]
|
||||
(let [active? (= state :active)]
|
||||
(cond
|
||||
blur? (grey-blur theme active?)
|
||||
(= theme :dark) (outline theme active?)
|
||||
(= theme :light) (grey theme active?))))
|
||||
@@ -0,0 +1,62 @@
|
||||
(ns quo.components.dropdowns.dropdown-input.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(def gap 8)
|
||||
|
||||
(def blur-view
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0})
|
||||
|
||||
(def left-icon
|
||||
{:margin-right gap})
|
||||
|
||||
(defn right-icon
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:margin-right gap})
|
||||
|
||||
(defn header-label
|
||||
[theme blur?]
|
||||
{:color (if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40
|
||||
colors/white-opa-70
|
||||
theme)
|
||||
(colors/theme-colors colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme))
|
||||
:margin-bottom gap})
|
||||
|
||||
(def root-container
|
||||
{:width "100%"
|
||||
:height 40})
|
||||
|
||||
(defn container
|
||||
[{:keys [background-color border-color]}
|
||||
{:keys [icon? state]}]
|
||||
(cond-> {:align-items :center
|
||||
:justify-content :space-between
|
||||
:flex-direction :row
|
||||
:padding-vertical 9
|
||||
:padding-left 16
|
||||
:padding-right 12
|
||||
:overflow :hidden
|
||||
:background-color background-color
|
||||
:border-radius 12}
|
||||
|
||||
icon?
|
||||
(assoc :padding-left 12)
|
||||
|
||||
border-color
|
||||
(assoc :border-color border-color
|
||||
:border-width 1)
|
||||
|
||||
(= state :disabled)
|
||||
(assoc :opacity 0.3)))
|
||||
|
||||
(def right-half-container
|
||||
{:flex-direction :row
|
||||
:align-items :center})
|
||||
@@ -0,0 +1,68 @@
|
||||
(ns quo.components.dropdowns.dropdown-input.view
|
||||
(:require
|
||||
[quo.components.dropdowns.dropdown-input.properties :as properties]
|
||||
[quo.components.dropdowns.dropdown-input.style :as style]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [state theme on-press icon?
|
||||
label? blur?
|
||||
accessibility-label header-label]
|
||||
:or {state :default
|
||||
icon? true
|
||||
label? true
|
||||
blur? false
|
||||
header-label "Label"}
|
||||
:as props}
|
||||
label]
|
||||
(let [{:keys [left-icon-color right-icon-color right-icon-color-2]
|
||||
:as colors} (properties/get-colors props)
|
||||
right-icon (if (= state :active) :i/pullup :i/dropdown)]
|
||||
[rn/view
|
||||
{:style style/root-container}
|
||||
(when label?
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:align :left
|
||||
:style (style/header-label theme blur?)} header-label])
|
||||
[rn/pressable
|
||||
{:accessibility-label (or accessibility-label :dropdown)
|
||||
:disabled (= state :disabled)
|
||||
:on-press on-press
|
||||
:style (style/container colors props)}
|
||||
[rn/view
|
||||
{:style style/right-half-container}
|
||||
(when icon?
|
||||
[icon/icon
|
||||
:i/placeholder
|
||||
{:accessibility-label :left-icon
|
||||
:color left-icon-color
|
||||
:size properties/icon-size
|
||||
:container-style style/left-icon}])
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight :regular
|
||||
:number-of-lines 1
|
||||
:style (style/right-icon theme)}
|
||||
label]]
|
||||
[icon/icon
|
||||
right-icon
|
||||
{:size properties/icon-size
|
||||
:accessibility-label :right-icon
|
||||
:color right-icon-color
|
||||
:color-2 right-icon-color-2}]]]))
|
||||
|
||||
(def view
|
||||
"Props:
|
||||
- state: :default (default) | :active | :disabled
|
||||
- label: string
|
||||
- header-label: string
|
||||
- icon?: boolean
|
||||
- label?: boolean
|
||||
- blur?: boolean
|
||||
- on-press: function"
|
||||
(theme/with-theme view-internal))
|
||||
@@ -11,6 +11,7 @@
|
||||
(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 view-internal
|
||||
|
||||
@@ -61,14 +61,10 @@
|
||||
value (reagent/atom "")
|
||||
focused? (atom false)]
|
||||
(fn [{:keys [scanned-value theme blur? on-change-text on-blur on-focus on-clear on-scan on-detect-ens
|
||||
on-detect-address
|
||||
ens-regex address-regex
|
||||
valid-ens-or-address?]}]
|
||||
on-detect-address address-regex valid-ens-or-address?]}]
|
||||
(let [on-change (fn [text]
|
||||
(when (not= @value text)
|
||||
(let [ens? (when ens-regex
|
||||
(boolean (re-matches ens-regex text)))
|
||||
address? (when address-regex
|
||||
(let [address? (when address-regex
|
||||
(boolean (re-matches address-regex text)))]
|
||||
(if (> (count text) 0)
|
||||
(reset! status :typing)
|
||||
@@ -76,9 +72,9 @@
|
||||
(reset! value text)
|
||||
(when on-change-text
|
||||
(on-change-text text))
|
||||
(when (and ens? on-detect-ens)
|
||||
(when (and on-detect-ens (> (count text) 0))
|
||||
(reset! status :loading)
|
||||
(on-detect-ens text))
|
||||
(on-detect-ens text #(reset! status :typing)))
|
||||
(when (and address? on-detect-address)
|
||||
(reset! status :loading)
|
||||
(on-detect-address text)))))
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
(ns quo.components.ios.drawer-bar.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as theme]))
|
||||
|
||||
(def handle-container
|
||||
{:padding-vertical 8
|
||||
:height 20
|
||||
:align-items :center})
|
||||
|
||||
(defn handle
|
||||
[{:keys [theme]}]
|
||||
{:width 32
|
||||
:height 4
|
||||
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:opacity (theme/theme-value 0.05 0.1 theme)
|
||||
:border-radius 100})
|
||||
@@ -0,0 +1,12 @@
|
||||
(ns quo.components.ios.drawer-bar.view
|
||||
(:require
|
||||
[quo.components.ios.drawer-bar.style :as style]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- view-internal
|
||||
[props]
|
||||
[rn/view {:style style/handle-container}
|
||||
[rn/view {:style (style/handle props)}]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -13,7 +13,7 @@
|
||||
(h/render [account/view])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/custom-color :blue 50 5)})))
|
||||
{:backgroundColor (colors/resolve-color :blue :light 5)})))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed with blur? enabled"
|
||||
(h/render [account/view {:blur? true}])
|
||||
@@ -21,31 +21,26 @@
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor colors/white-opa-5})))
|
||||
|
||||
(h/test "on-press-out changes state to :active"
|
||||
(h/render [account/view])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press-out (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/custom-color :blue 50 10)})))
|
||||
(h/test "render with state :active"
|
||||
(h/render [account/view {:state :active}])
|
||||
(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/resolve-color :blue :light 10)}))
|
||||
|
||||
(h/test "on-press-out changes state to :active with blur? enabled"
|
||||
(h/render [account/view {:blur? true}])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press-out (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor colors/white-opa-10})))
|
||||
(h/test "render with state :active and blur? enabled"
|
||||
(h/render [account/view
|
||||
{:blur? true
|
||||
:state :active}])
|
||||
(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor colors/white-opa-10}))
|
||||
|
||||
(h/test "on-press-out changes state to :selected"
|
||||
(h/render [account/view {:selectable? true}])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press-out (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/is-truthy (h/query-by-label-text :check-icon))))
|
||||
(h/test "render with state :selected"
|
||||
(h/render [account/view {:state :selected}])
|
||||
(h/is-truthy (h/query-by-label-text :check-icon)))
|
||||
|
||||
(h/test "on-press-out calls on-press"
|
||||
(h/test "calls on-press"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render [account/view {:on-press on-press}])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press-out (h/get-by-label-text :container))
|
||||
(h/fire-event :on-press (h/get-by-label-text :container))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "renders token props if type :tag"
|
||||
|
||||
@@ -3,12 +3,12 @@
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn- background-color
|
||||
[{:keys [state blur? customization-color]}]
|
||||
(cond (or (= state :pressed) (= state :selected))
|
||||
(if blur? colors/white-opa-5 (colors/custom-color customization-color 50 5))
|
||||
[{:keys [state pressed? blur? customization-color]}]
|
||||
(cond (or pressed? (= state :selected))
|
||||
(if blur? colors/white-opa-5 (colors/resolve-color customization-color :light 5))
|
||||
(= state :active)
|
||||
(if blur? colors/white-opa-10 (colors/custom-color customization-color 50 10))
|
||||
(and (= state :pressed) blur?) colors/white-opa-10
|
||||
(if blur? colors/white-opa-10 (colors/resolve-color customization-color :light 10))
|
||||
(and pressed? blur?) colors/white-opa-10
|
||||
:else :transparent))
|
||||
|
||||
(defn container
|
||||
|
||||
@@ -94,62 +94,42 @@
|
||||
[icon/icon :i/check
|
||||
{:color (if blur?
|
||||
colors/white
|
||||
(colors/theme-colors (colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
theme))}]])
|
||||
|
||||
(defn- f-internal-view
|
||||
[]
|
||||
(let [state (reagent/atom :default)
|
||||
active-or-selected? (atom false)
|
||||
timer (atom nil)
|
||||
on-press-in (fn []
|
||||
(when-not (= @state :selected)
|
||||
(reset! timer (js/setTimeout #(reset! state :pressed) 100))))]
|
||||
(fn [{:keys [type selectable? blur? customization-color on-press]
|
||||
:or {customization-color :blue
|
||||
type :default
|
||||
blur? false}
|
||||
:as props}]
|
||||
(let [on-press-out (fn []
|
||||
(let [new-state (if @active-or-selected?
|
||||
:default
|
||||
(if (and (= type :default) selectable?)
|
||||
:selected
|
||||
:active))]
|
||||
(when @timer (js/clearTimeout @timer))
|
||||
(reset! timer nil)
|
||||
(reset! active-or-selected? (or (= new-state :active)
|
||||
(= new-state :selected)))
|
||||
(reset! state new-state)
|
||||
(when on-press
|
||||
(on-press))))]
|
||||
(rn/use-effect
|
||||
#(cond (and selectable? (= type :default) (= @state :active)) (reset! state :selected)
|
||||
(and (not selectable?) (= type :default) (= @state :selected)) (reset! state :active))
|
||||
[selectable?])
|
||||
[rn/pressable
|
||||
{:style (style/container
|
||||
{:state @state :blur? blur? :customization-color customization-color})
|
||||
:on-press-in on-press-in
|
||||
:on-press-out on-press-out
|
||||
:accessibility-label :container}
|
||||
[account-view props]
|
||||
[rn/view {:style (when (= type :tag) style/token-tag-container)}
|
||||
(when (or (= type :balance-neutral)
|
||||
(= type :balance-negative)
|
||||
(= type :balance-positive))
|
||||
[balance-view props])
|
||||
(when (= type :tag)
|
||||
[token-tag props])
|
||||
(when (= type :action)
|
||||
[options-button props])
|
||||
(when (and (= type :default)
|
||||
(= @state :selected))
|
||||
[check-icon props])]]))))
|
||||
(colors/resolve-color customization-color theme))}]])
|
||||
|
||||
(defn- internal-view
|
||||
[props]
|
||||
[:f> f-internal-view props])
|
||||
[_]
|
||||
(let [pressed? (reagent/atom false)
|
||||
on-press-in #(reset! pressed? true)
|
||||
on-press-out #(reset! pressed? false)]
|
||||
(fn [{:keys [type state blur? customization-color on-press]
|
||||
:or {customization-color :blue
|
||||
type :default
|
||||
state :default
|
||||
blur? false}
|
||||
:as props}]
|
||||
[rn/pressable
|
||||
{:style (style/container
|
||||
{:state state
|
||||
:blur? blur?
|
||||
:customization-color customization-color
|
||||
:pressed? @pressed?})
|
||||
:on-press-in on-press-in
|
||||
:on-press on-press
|
||||
:on-press-out on-press-out
|
||||
:accessibility-label :container}
|
||||
[account-view props]
|
||||
[rn/view {:style (when (= type :tag) style/token-tag-container)}
|
||||
(cond
|
||||
(#{:balance-neutral :balance-negative :balance-positive} type)
|
||||
[balance-view props]
|
||||
|
||||
(= type :tag)
|
||||
[token-tag props]
|
||||
|
||||
(= type :action)
|
||||
[options-button props]
|
||||
|
||||
(and (= type :default) (= state :selected))
|
||||
[check-icon props])]])))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
:blur? false
|
||||
:type :digit} 1])
|
||||
(h/is-truthy (h/query-by-label-text :text-label))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "Is not pressable when disabled is true"
|
||||
@@ -47,5 +47,5 @@
|
||||
:blur? false
|
||||
:type :digit} 1])
|
||||
(h/is-truthy (h/query-by-label-text :text-label))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key))
|
||||
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
|
||||
(h/was-not-called on-press))))
|
||||
|
||||
@@ -7,6 +7,11 @@
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- label->accessibility-label
|
||||
[label]
|
||||
(let [label-name (if (keyword? label) (name label) label)]
|
||||
(keyword (str "keyboard-key-" label-name))))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
@@ -14,9 +19,11 @@
|
||||
(let [label-color (style/get-label-color disabled? theme blur?)
|
||||
background-color (style/toggle-background-color @pressed? blur? theme)]
|
||||
[rn/pressable
|
||||
{:accessibility-label :keyboard-key
|
||||
{:accessibility-label (label->accessibility-label label)
|
||||
:disabled (or disabled? (not label))
|
||||
:on-press (fn [] (on-press label))
|
||||
:on-press (fn []
|
||||
(when on-press
|
||||
(on-press label)))
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? false)
|
||||
:style (style/container background-color)}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns quo.components.numbered-keyboard.numbered-keyboard.style)
|
||||
|
||||
(def container
|
||||
{:flex 1
|
||||
{:display :flex
|
||||
:padding-top 8
|
||||
:padding-horizontal 48})
|
||||
|
||||
|
||||
@@ -17,13 +17,17 @@
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press]}]
|
||||
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press on-delete
|
||||
container-style]
|
||||
:or {left-action :none}}]
|
||||
[rn/view
|
||||
{:style style/container}
|
||||
{:style (merge style/container
|
||||
container-style)}
|
||||
(for [row-index (range 1 4)]
|
||||
^{:key row-index}
|
||||
[rn/view {:style style/row-container}
|
||||
(for [column-index (range 1 4)]
|
||||
^{:key (str row-index column-index)}
|
||||
[keyboard-item
|
||||
{:item (+ (* (dec row-index) 3) column-index)
|
||||
:type :digit
|
||||
@@ -58,10 +62,10 @@
|
||||
:theme theme}]
|
||||
(if delete-key?
|
||||
[keyboard-item
|
||||
{:item :i/delete
|
||||
{:item :i/backspace
|
||||
:type :key
|
||||
:disabled? disabled?
|
||||
:on-press on-press
|
||||
:on-press on-delete
|
||||
:blur? blur?
|
||||
:theme theme}]
|
||||
[keyboard-item])]]))
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
(ns quo.components.overlay.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(defn overlay-background
|
||||
[type]
|
||||
(let [background-color (case type
|
||||
:shell colors/neutral-80-opa-80-blur
|
||||
:drawer colors/neutral-100-opa-70-blur
|
||||
nil)]
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 0
|
||||
:background-color background-color}))
|
||||
|
||||
(def container
|
||||
{:flex 1})
|
||||
|
||||
(def blur-container
|
||||
{:flex 1
|
||||
:background-color :transparent})
|
||||
@@ -0,0 +1,20 @@
|
||||
(ns quo.components.overlay.view
|
||||
(:require
|
||||
[quo.components.overlay.style :as style]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn view
|
||||
[{:keys [type]} & children]
|
||||
[rn/view {:style (style/overlay-background type)}
|
||||
(if (= type :shell)
|
||||
[blur/view
|
||||
{:blur-amount 20
|
||||
:blur-radius 25
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent
|
||||
:style style/container}
|
||||
[rn/view {:style style/blur-container}
|
||||
children]]
|
||||
[rn/view {:style style/container}
|
||||
children])])
|
||||
@@ -10,14 +10,14 @@
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :account
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
@@ -27,14 +27,14 @@
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? false
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :account
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
@@ -45,14 +45,14 @@
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :small
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :account
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
@@ -63,14 +63,14 @@
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :account
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
@@ -81,31 +81,31 @@
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :account
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/get-by-text "Description")))
|
||||
(h/is-truthy (h/get-by-text "Subtitle")))
|
||||
|
||||
(h/test "right icon is not visible when icon-right? is false"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? false
|
||||
:card? true
|
||||
:label :none
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :account
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
@@ -115,7 +115,6 @@
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? true
|
||||
:right-icon :i/chevron-right
|
||||
:card? true
|
||||
@@ -123,17 +122,17 @@
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :account
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/query-by-label-text :icon-right)))
|
||||
|
||||
(h/test "description icon is visible when description is icon"
|
||||
(h/test "icon is visible when subtitle type is icon"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :icon
|
||||
:icon-right? true
|
||||
:right-icon :i/chevron-right
|
||||
:card? true
|
||||
@@ -141,17 +140,17 @@
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :icon
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
(h/is-truthy (h/query-by-label-text :description-icon)))
|
||||
(h/is-truthy (h/query-by-label-text :subtitle-type-icon)))
|
||||
|
||||
(h/test "description image is visible when description is network"
|
||||
(h/test "image is visible when subtitle type is network"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :network
|
||||
:icon-right? true
|
||||
:right-icon :i/chevron-right
|
||||
:card? true
|
||||
@@ -159,18 +158,18 @@
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :network
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow
|
||||
:network-image (quo.resources/get-network :ethereum)}])
|
||||
(h/is-truthy (h/query-by-label-text :description-image)))
|
||||
(h/is-truthy (h/query-by-label-text :subtitle-type-image)))
|
||||
|
||||
(h/test "description emoji is visible when description is account"
|
||||
(h/test "emoji is visible when subtitle type is account"
|
||||
(h/render [quo/data-item
|
||||
{:on-press (h/mock-fn)
|
||||
:blur? false
|
||||
:description :account
|
||||
:icon-right? true
|
||||
:right-icon :i/chevron-right
|
||||
:card? true
|
||||
@@ -178,7 +177,8 @@
|
||||
:status :default
|
||||
:size :default
|
||||
:title "Label"
|
||||
:subtitle "Description"
|
||||
:subtitle "Subtitle"
|
||||
:subtitle-type :account
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
|
||||
@@ -37,8 +37,8 @@
|
||||
:align-items :center})
|
||||
|
||||
(defn subtitle-icon-container
|
||||
[description]
|
||||
{:margin-right (when (not= :default description) 4)
|
||||
[subtitle-type]
|
||||
{:margin-right (when (not= :default subtitle-type) 4)
|
||||
:justify-content :center})
|
||||
|
||||
(defn title
|
||||
|
||||
@@ -16,14 +16,15 @@
|
||||
[rn/view {:style (style/loading-container size blur? theme)}])
|
||||
|
||||
(defn- left-subtitle
|
||||
[{:keys [theme size description icon icon-color blur? subtitle customization-color emoji
|
||||
network-image]}]
|
||||
[{:keys [theme size subtitle-type icon icon-color blur? subtitle customization-color emoji
|
||||
network-image]
|
||||
:or {subtitle-type :default}}]
|
||||
[rn/view {:style style/subtitle-container}
|
||||
(when (not= :small size)
|
||||
[rn/view {:style (style/subtitle-icon-container description)}
|
||||
(case description
|
||||
[rn/view {:style (style/subtitle-icon-container subtitle-type)}
|
||||
(case subtitle-type
|
||||
:icon [icons/icon icon
|
||||
{:accessibility-label :description-icon
|
||||
{:accessibility-label :subtitle-type-icon
|
||||
:size 16
|
||||
:color icon-color}]
|
||||
:account [account-avatar/view
|
||||
@@ -32,7 +33,7 @@
|
||||
:emoji emoji
|
||||
:type :default}]
|
||||
:network [rn/image
|
||||
{:accessibility-label :description-image
|
||||
{:accessibility-label :subtitle-type-image
|
||||
:source network-image
|
||||
:style style/image}]
|
||||
nil)])
|
||||
@@ -58,10 +59,9 @@
|
||||
(i18n/label :t/days)])])
|
||||
|
||||
(defn- left-side
|
||||
"The description can either be given as a string `description` or a component `custom-subtitle`"
|
||||
[{:keys [theme title status size blur? description custom-subtitle icon subtitle label icon-color
|
||||
customization-color network-image
|
||||
emoji]
|
||||
"The description can either be given as a string `subtitle-type` or a component `custom-subtitle`"
|
||||
[{:keys [theme title status size blur? custom-subtitle icon subtitle subtitle-type label icon-color
|
||||
customization-color network-image emoji]
|
||||
:as props}]
|
||||
[rn/view {:style style/left-side}
|
||||
[left-title
|
||||
@@ -79,7 +79,7 @@
|
||||
[left-subtitle
|
||||
{:theme theme
|
||||
:size size
|
||||
:description description
|
||||
:subtitle-type subtitle-type
|
||||
:icon icon
|
||||
:icon-color icon-color
|
||||
:blur? blur?
|
||||
|
||||
@@ -17,30 +17,21 @@
|
||||
{:width size})))
|
||||
|
||||
(defn base-tag
|
||||
[_]
|
||||
(fn
|
||||
[{:keys [id
|
||||
size
|
||||
disabled?
|
||||
border-color
|
||||
border-width
|
||||
background-color
|
||||
on-press
|
||||
accessibility-label
|
||||
type
|
||||
labelled?]
|
||||
:or {size 32}} children]
|
||||
[rn/touchable-without-feedback
|
||||
(merge {:disabled disabled?
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-press
|
||||
{:on-press #(on-press id)}))
|
||||
[rn/view
|
||||
{:style (merge (style-container size
|
||||
disabled?
|
||||
border-color
|
||||
border-width
|
||||
background-color
|
||||
labelled?
|
||||
type))}
|
||||
children]]))
|
||||
[{:keys [id size disabled? border-color border-width background-color on-press
|
||||
accessibility-label type labelled?]
|
||||
:or {size 32}}
|
||||
children]
|
||||
[rn/touchable-without-feedback
|
||||
(merge {:disabled disabled?
|
||||
:accessibility-label accessibility-label}
|
||||
(when on-press
|
||||
{:on-press #(on-press id)}))
|
||||
[rn/view
|
||||
{:style (merge (style-container size
|
||||
disabled?
|
||||
border-color
|
||||
border-width
|
||||
background-color
|
||||
labelled?
|
||||
type))}
|
||||
children]])
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.base-tag :as base-tag]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as theme]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def themes
|
||||
@@ -66,54 +66,45 @@
|
||||
text-color)
|
||||
label])])
|
||||
|
||||
(defn tag
|
||||
(defn tag-internal
|
||||
"opts
|
||||
{:type :icon/:emoji/:label
|
||||
:label string
|
||||
:size 32/24
|
||||
:on-press fn
|
||||
:blurred? true/false
|
||||
:blurred? true/false
|
||||
:resource icon/image
|
||||
:labelled? true/false
|
||||
:disabled? true/false}
|
||||
|
||||
|
||||
opts
|
||||
- `blurred` boolean: use to determine border color if the background is blurred
|
||||
- `type` can be icon or emoji with or without a tag label
|
||||
- `labelled` boolean: is true if tag has label else false"
|
||||
[_ _]
|
||||
(fn
|
||||
[{:keys [id
|
||||
on-press
|
||||
disabled?
|
||||
size
|
||||
active
|
||||
accessibility-label
|
||||
label
|
||||
resource
|
||||
type
|
||||
labelled?
|
||||
blurred?
|
||||
icon-color
|
||||
override-theme]
|
||||
:or {size 32}}]
|
||||
(let [state (cond disabled? :disabled
|
||||
active :active
|
||||
:else :default)
|
||||
{:keys [border-color blurred-border-color text-color]}
|
||||
(get-in themes [(or override-theme (theme/get-theme)) state])]
|
||||
[rn/view {:style {:align-items :center}}
|
||||
[base-tag/base-tag
|
||||
{:id id
|
||||
:size size
|
||||
:border-width 1
|
||||
:border-color (if blurred?
|
||||
blurred-border-color
|
||||
border-color)
|
||||
:on-press on-press
|
||||
:accessibility-label accessibility-label
|
||||
:disabled? disabled?
|
||||
:type type
|
||||
:labelled? (if (= type :label) true labelled?)}
|
||||
[tag-resources size type resource icon-color label text-color labelled?]]])))
|
||||
[{:keys [id on-press disabled? size active accessibility-label label resource type
|
||||
labelled? blurred? icon-color theme]
|
||||
:or {size 32}}]
|
||||
(let [state (cond
|
||||
disabled? :disabled
|
||||
active :active
|
||||
:else :default)
|
||||
{:keys [border-color
|
||||
blurred-border-color
|
||||
text-color]} (get-in themes [theme state])]
|
||||
[rn/view {:style {:align-items :center}}
|
||||
[base-tag/base-tag
|
||||
{:id id
|
||||
:size size
|
||||
:border-width 1
|
||||
:border-color (if blurred?
|
||||
blurred-border-color
|
||||
border-color)
|
||||
:on-press on-press
|
||||
:accessibility-label accessibility-label
|
||||
:disabled? disabled?
|
||||
:type type
|
||||
:labelled? (if (= type :label) true labelled?)}
|
||||
[tag-resources size type resource icon-color label text-color labelled?]]]))
|
||||
|
||||
(def tag (quo.theme/with-theme tag-internal))
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
(ns quo.components.text-combinations.standard-title.component-spec
|
||||
(:require [quo.components.text-combinations.standard-title.view :as standard-title]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Text combinations - Standard title"
|
||||
(h/test "Default render"
|
||||
(h/render [standard-title/view {:title "This is a title"}])
|
||||
(h/is-truthy (h/get-by-text "This is a title")))
|
||||
|
||||
(h/test "Counter variant"
|
||||
(h/render [standard-title/view
|
||||
{:title "This is a title"
|
||||
:right :counter
|
||||
:counter-left 50
|
||||
:counter-right 100}])
|
||||
(h/is-truthy (h/get-by-text "50/100")))
|
||||
|
||||
(h/describe "Action variant"
|
||||
(h/test "Default render"
|
||||
(let [on-press-fn (h/mock-fn)]
|
||||
(h/render [standard-title/view
|
||||
{:title "This is a title"
|
||||
:right :action
|
||||
:on-press on-press-fn}])
|
||||
(h/is-truthy (h/get-by-text "This is a title"))))
|
||||
|
||||
(h/test "Action fired"
|
||||
(let [on-press-fn (h/mock-fn)]
|
||||
(h/render [standard-title/view
|
||||
{:title "This is a title"
|
||||
:right :action
|
||||
:on-press on-press-fn}])
|
||||
|
||||
(h/fire-event :on-press (h/get-by-label-text :standard-title-action))
|
||||
(h/was-called-times on-press-fn 1))))
|
||||
|
||||
(h/describe "Tag variant"
|
||||
(h/test "Default render"
|
||||
(h/render [standard-title/view
|
||||
{:title "This is a title"
|
||||
:right :tag}])
|
||||
(h/is-truthy (h/get-by-text "This is a title")))
|
||||
|
||||
(h/test "Tag callback fired"
|
||||
(let [on-press-fn (h/mock-fn)]
|
||||
(h/render [standard-title/view
|
||||
{:title "This is a title"
|
||||
:right :tag
|
||||
:on-press on-press-fn}])
|
||||
(h/fire-event :on-press (h/get-by-label-text :standard-title-tag))
|
||||
(h/was-called-times on-press-fn 1)))))
|
||||
@@ -0,0 +1,24 @@
|
||||
(ns quo.components.text-combinations.standard-title.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def container
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between})
|
||||
|
||||
(def right-container {:margin-left 20})
|
||||
|
||||
(def right-counter
|
||||
{:padding-top 12
|
||||
:padding-bottom 2})
|
||||
|
||||
(defn right-counter-text
|
||||
[blur? theme]
|
||||
{:color (if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))})
|
||||
|
||||
(defn right-tag-icon-color
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
@@ -0,0 +1,68 @@
|
||||
(ns quo.components.text-combinations.standard-title.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.components.buttons.button.view :as button]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.tag :as tag]
|
||||
[quo.components.text-combinations.standard-title.style :as style]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[utils.number]))
|
||||
|
||||
(defn- get-counter-number
|
||||
[n]
|
||||
(let [parsed-number (utils.number/parse-int n)]
|
||||
(if (< n 10)
|
||||
(str "0" parsed-number)
|
||||
parsed-number)))
|
||||
|
||||
(defn- right-counter
|
||||
[{:keys [blur? theme counter-left counter-right]}]
|
||||
[rn/view {:style style/right-counter}
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style (style/right-counter-text blur? theme)}
|
||||
(str (get-counter-number counter-left)
|
||||
"/"
|
||||
(get-counter-number counter-right))]])
|
||||
|
||||
(defn- right-action
|
||||
[{:keys [customization-color on-press icon]
|
||||
:or {icon :i/placeholder}}]
|
||||
[button/button
|
||||
{:accessibility-label :standard-title-action
|
||||
:size 32
|
||||
:icon-only? true
|
||||
:customization-color customization-color
|
||||
:on-press on-press}
|
||||
icon])
|
||||
|
||||
(defn- right-tag
|
||||
[{:keys [theme blur? on-press icon label]
|
||||
:or {icon :i/placeholder}}]
|
||||
(let [labelled? (not (string/blank? label))]
|
||||
[tag/tag
|
||||
{:accessibility-label :standard-title-tag
|
||||
:size 32
|
||||
:type :icon
|
||||
:resource icon
|
||||
:on-press on-press
|
||||
:labelled? labelled?
|
||||
:label (when labelled? label)
|
||||
:blurred? blur?
|
||||
:icon-color (style/right-tag-icon-color blur? theme)}]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [title right] :as props}]
|
||||
[rn/view {:style style/container}
|
||||
[text/text {:size :heading-1 :weight :semi-bold}
|
||||
title]
|
||||
(when right
|
||||
[rn/view {:style style/right-container}
|
||||
(case right
|
||||
:counter [right-counter props]
|
||||
:action [right-action props]
|
||||
:tag [right-tag props]
|
||||
nil)])])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -9,3 +9,8 @@
|
||||
|
||||
(def description-description-text
|
||||
{:margin-top 8})
|
||||
|
||||
(def emoji-hash
|
||||
{:margin-top 8
|
||||
:letter-spacing 0.5
|
||||
:line-height 20.5})
|
||||
|
||||
@@ -27,7 +27,8 @@
|
||||
description-accessibility-label
|
||||
button-icon
|
||||
button-on-press
|
||||
customization-color]}]
|
||||
customization-color
|
||||
emoji-hash]}]
|
||||
[rn/view {:style container-style}
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
@@ -55,6 +56,11 @@
|
||||
:weight :regular
|
||||
:size :paragraph-1
|
||||
:style style/description-description-text}
|
||||
description])])
|
||||
description])
|
||||
(when emoji-hash
|
||||
[text/text
|
||||
{:number-of-lines 1
|
||||
:style style/emoji-hash}
|
||||
emoji-hash])])
|
||||
|
||||
(def view (theme/with-theme view-internal))
|
||||
|
||||
@@ -20,12 +20,13 @@
|
||||
(i18n/label :t/trip-accounts))])
|
||||
|
||||
(defn- row-icon
|
||||
[profile-picture type secondary-color]
|
||||
[customization-color profile-picture type secondary-color]
|
||||
(case type
|
||||
:default-keypair [user-avatar/user-avatar
|
||||
{:size :xxs
|
||||
:ring? false
|
||||
:profile-picture profile-picture}]
|
||||
{:size :xxs
|
||||
:ring? false
|
||||
:customization-color customization-color
|
||||
:profile-picture profile-picture}]
|
||||
:recovery-phrase [icons/icon
|
||||
:i/seed
|
||||
{:accessibility-label :recovery-phrase-icon
|
||||
@@ -41,10 +42,11 @@
|
||||
nil))
|
||||
|
||||
(defn- row-view
|
||||
[{:keys [type theme secondary-color profile-picture title stored subtitle on-press]}]
|
||||
[{:keys [type theme secondary-color customization-color profile-picture title stored subtitle
|
||||
on-press]}]
|
||||
[rn/view {:style (style/row-container type theme)}
|
||||
[rn/view {:style style/icon-container}
|
||||
[row-icon profile-picture type secondary-color]]
|
||||
[row-icon customization-color profile-picture type secondary-color]]
|
||||
[rn/view
|
||||
{:style style/row-content-container}
|
||||
[row-title type title]
|
||||
@@ -68,18 +70,19 @@
|
||||
{:color secondary-color}]])])
|
||||
|
||||
(defn- list-view
|
||||
[{:keys [type stored profile-picture user-name theme secondary-color]}]
|
||||
[{:keys [type stored customization-color profile-picture user-name theme secondary-color]}]
|
||||
(let [stored-name (if (= :on-device stored)
|
||||
(i18n/label :t/on-device)
|
||||
(i18n/label :t/on-keycard))]
|
||||
[row-view
|
||||
{:type type
|
||||
:stored stored
|
||||
:profile-picture profile-picture
|
||||
:title user-name
|
||||
:subtitle stored-name
|
||||
:theme theme
|
||||
:secondary-color secondary-color}]))
|
||||
{:type type
|
||||
:stored stored
|
||||
:customization-color customization-color
|
||||
:profile-picture profile-picture
|
||||
:title user-name
|
||||
:subtitle stored-name
|
||||
:theme theme
|
||||
:secondary-color secondary-color}]))
|
||||
|
||||
(defn- card-view
|
||||
[theme derivation-path secondary-color on-press]
|
||||
@@ -105,12 +108,13 @@
|
||||
|
||||
(def view
|
||||
"Create an account-origin UI component.
|
||||
| key | values |
|
||||
| ------------------|------------------------------------------------|
|
||||
| :type | :default-keypair :recovery-phrase :private-key
|
||||
| :stored | :on-device :on-keycard
|
||||
| :profile-picture | image source
|
||||
| :derivation-path | string
|
||||
| :user-name | string
|
||||
| :on-press | function"
|
||||
| key | values |
|
||||
| ----------------------|------------------------------------------------|
|
||||
| :type | :default-keypair :recovery-phrase :private-key
|
||||
| :stored | :on-device :on-keycard
|
||||
| :profile-picture | image source
|
||||
| :customization-color | profile color
|
||||
| :derivation-path | string
|
||||
| :user-name | string
|
||||
| :on-press | function"
|
||||
(quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
| key | description |
|
||||
| -------------|-------------|
|
||||
| `:account-name` | A value representing the account name (default `nil`)
|
||||
| `:account` | A value that represents if the account is a `:watched-account` or a `:default` account. (default `nil`)
|
||||
| `:account` | A value that represents if the account is a `:watched-address` or a `:default` account. (default `nil`)
|
||||
| `:time-frame` | A value that represents the type of the timeframe, Can be from a preset of time frames. `[:1-week :1-month :3-months :1-year :custom]` (default `nil`) if custom is set, We expect a start time and if there's a space between two times that are in `time-frame-string` we'll split them with an arrow to the right icon
|
||||
| `:loading?` | A value that indicates that component is loading data. (default `nil`)
|
||||
| `:metrics` | A value that indicates if the account value have increased can be `:positive` or `:negative` (default `nil`)
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
(ns quo.components.wallet.confirmation-progress.component-spec
|
||||
(:require [quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn- get-test-data
|
||||
[{:keys [state network]
|
||||
:or {state :pending network :mainnet}}]
|
||||
{:counter (reagent/atom 0)
|
||||
:total-box 85
|
||||
:progress-value "10"
|
||||
:network network
|
||||
:state state
|
||||
:customization-color :blue})
|
||||
|
||||
(h/describe "Confirmation Progress"
|
||||
(h/test "component renders when state is sending and network is optimism"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :sending
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is confirmed and network is optimism"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :confirmed
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is finalising and network is optimism"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :finalising
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is finalized and network is optimism"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :finalized
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is error and network is optimism"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :error
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is sending and network is arbitrum"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :sending
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is confirmed and network is arbitrum"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :confirmed
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is finalising and network is arbitrum"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :finalising
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is finalized and network is arbitrum"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :finalized
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is error and network is arbitrum"
|
||||
(h/render [quo/confirmation-propgress
|
||||
(get-test-data {:state :error
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :progress-box)))
|
||||
|
||||
(h/test "component renders when state is pending and network is mainnet"
|
||||
(h/render [quo/confirmation-propgress (get-test-data {})])
|
||||
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
|
||||
|
||||
(h/test "component renders when state is sending and network is mainnet"
|
||||
(h/render [quo/confirmation-propgress (get-test-data {:state :sending})])
|
||||
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
|
||||
|
||||
(h/test "component renders when state is confirmed and network is mainnet"
|
||||
(h/render [quo/confirmation-propgress (get-test-data {:state :confirmed})])
|
||||
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
|
||||
|
||||
(h/test "component renders when state is finalising and network is mainnet"
|
||||
(h/render [quo/confirmation-propgress (get-test-data {:state :finalising})])
|
||||
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
|
||||
|
||||
(h/test "component renders when state is finalized and network is mainnet"
|
||||
(h/render [quo/confirmation-propgress (get-test-data {:state :finalized})])
|
||||
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
|
||||
|
||||
(h/test "component renders when state is error and network is mainnet"
|
||||
(h/render [quo/confirmation-propgress (get-test-data {:state :error})])
|
||||
(h/is-truthy (h/get-by-label-text :mainnet-progress-box))))
|
||||
@@ -0,0 +1,9 @@
|
||||
(ns quo.components.wallet.confirmation-progress.style)
|
||||
|
||||
(def progress-box-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:padding-horizontal 12
|
||||
:padding-bottom 10
|
||||
:padding-top 4
|
||||
:flex-wrap :wrap})
|
||||
@@ -0,0 +1,69 @@
|
||||
(ns quo.components.wallet.confirmation-progress.view
|
||||
(:require [quo.components.wallet.confirmation-progress.style :as style]
|
||||
[quo.components.wallet.progress-bar.view :as progress-box]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def ^:private max-progress 100)
|
||||
(def ^:private min-progress 0)
|
||||
|
||||
(defn- calculate-box-state
|
||||
[state counter index]
|
||||
(cond
|
||||
(and (= state :sending) (>= counter index) (< index 3)) :confirmed
|
||||
(and (= state :confirmed) (>= counter index) (< index 5)) :confirmed
|
||||
(and (= state :finalising) (>= counter index) (< index 5)) :confirmed
|
||||
(and (= state :finalising) (>= counter index) (> index 4) (< index 20)) :finalized
|
||||
(and (= state :finalized) (>= counter index) (< index 5)) :confirmed
|
||||
(and (= state :finalized) (>= counter index) (> index 4)) :finalized
|
||||
(and (= state :error) (>= counter index) (< index 2)) :error
|
||||
:else :pending))
|
||||
|
||||
(defn- calculate-box-state-sidenet
|
||||
[state]
|
||||
(case state
|
||||
:error :error
|
||||
(:confirmed :finalising :finalized) :finalized
|
||||
:pending))
|
||||
|
||||
(defn- calculate-progressed-value
|
||||
[state progress-value]
|
||||
(case state
|
||||
:finalising progress-value
|
||||
:finalized max-progress
|
||||
min-progress))
|
||||
|
||||
(defn- progress-boxes-mainnet
|
||||
[{:keys [state counter total-box]}]
|
||||
[rn/view
|
||||
{:accessibility-label :mainnet-progress-box
|
||||
:style style/progress-box-container}
|
||||
(let [numbers (range 1 total-box)]
|
||||
(doall (for [n numbers]
|
||||
[progress-box/view
|
||||
{:state (calculate-box-state state counter n)
|
||||
:customization-color :blue
|
||||
:key n}])))])
|
||||
|
||||
(defn- progress-boxes-sidenet
|
||||
[{:keys [state progress-value]}]
|
||||
[rn/view
|
||||
{:accessibility-label :progress-box
|
||||
:style style/progress-box-container}
|
||||
[progress-box/view
|
||||
{:state (calculate-box-state-sidenet state)
|
||||
:customization-color :success}]
|
||||
[progress-box/view
|
||||
{:state (calculate-box-state-sidenet state)
|
||||
:full-width? true
|
||||
:progressed-value (calculate-progressed-value state progress-value)
|
||||
:customization-color :blue}]])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [network] :as props}]
|
||||
(case network
|
||||
:mainnet [progress-boxes-mainnet props]
|
||||
(:arbitrum :optimism) [progress-boxes-sidenet props]
|
||||
nil))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -39,7 +39,7 @@
|
||||
:width 8
|
||||
:borderRadius 3
|
||||
:borderColor colors/neutral-80-opa-5
|
||||
:backgroundColor (colors/custom-color (:customization-color props) 50)})))
|
||||
:backgroundColor (colors/resolve-color (:customization-color props) theme)})))
|
||||
|
||||
(h/test "finalized state with customtization-color blue in dark mode"
|
||||
(let [theme :dark
|
||||
@@ -51,7 +51,7 @@
|
||||
:width 8
|
||||
:borderRadius 3
|
||||
:borderColor colors/neutral-80-opa-5
|
||||
:backgroundColor (colors/custom-color (:customization-color props) 60)})))
|
||||
:backgroundColor (colors/resolve-color (:customization-color props) theme)})))
|
||||
|
||||
(h/test "finalized state with customtization-color army in light mode"
|
||||
(let [theme :light
|
||||
@@ -63,7 +63,7 @@
|
||||
:width 8
|
||||
:borderRadius 3
|
||||
:borderColor colors/neutral-80-opa-5
|
||||
:backgroundColor (colors/custom-color (:customization-color props) 50)})))
|
||||
:backgroundColor (colors/resolve-color (:customization-color props) theme)})))
|
||||
|
||||
(h/test "confirmed state in light mode"
|
||||
(let [theme :light
|
||||
@@ -75,7 +75,7 @@
|
||||
:width 8
|
||||
:borderRadius 3
|
||||
:borderColor colors/neutral-80-opa-5
|
||||
:backgroundColor colors/success-50})))
|
||||
:backgroundColor (colors/resolve-color :success theme)})))
|
||||
|
||||
(h/test "confirmed state in dark mode"
|
||||
(let [theme :dark
|
||||
@@ -99,7 +99,7 @@
|
||||
:width 8
|
||||
:borderRadius 3
|
||||
:borderColor colors/neutral-80-opa-5
|
||||
:backgroundColor colors/danger-50})))
|
||||
:backgroundColor (colors/resolve-color :danger theme)})))
|
||||
|
||||
(h/test "error state in dark mode"
|
||||
(let [theme :dark
|
||||
@@ -111,4 +111,4 @@
|
||||
:width 8
|
||||
:borderRadius 3
|
||||
:borderColor colors/white-opa-5
|
||||
:backgroundColor colors/danger-60}))))
|
||||
:backgroundColor (colors/resolve-color :danger theme)}))))
|
||||
|
||||
@@ -3,31 +3,48 @@
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn- border-and-background-color
|
||||
[customization-color]
|
||||
[customization-color theme]
|
||||
{:light {:pending {:border-color colors/neutral-80-opa-5
|
||||
:background-color colors/neutral-5}
|
||||
:confirmed {:border-color colors/neutral-80-opa-5
|
||||
:background-color (colors/custom-color :success 50)}
|
||||
:background-color (colors/resolve-color :success theme)}
|
||||
:finalized {:border-color colors/neutral-80-opa-5
|
||||
:background-color (colors/custom-color customization-color 50)}
|
||||
:background-color (colors/resolve-color customization-color theme)}
|
||||
:error {:border-color colors/neutral-80-opa-5
|
||||
:background-color (colors/custom-color :danger 50)}}
|
||||
:background-color (colors/resolve-color :danger theme)}}
|
||||
:dark {:pending {:border-color colors/neutral-70
|
||||
:background-color colors/neutral-80}
|
||||
:confirmed {:border-color colors/white-opa-5
|
||||
:background-color (colors/custom-color :success 60)}
|
||||
:background-color (colors/resolve-color :success theme)}
|
||||
:finalized {:border-color colors/neutral-80-opa-5
|
||||
:background-color (colors/custom-color customization-color 60)}
|
||||
:background-color (colors/resolve-color customization-color theme)}
|
||||
:error {:border-color colors/white-opa-5
|
||||
:background-color (colors/custom-color :danger 60)}}})
|
||||
:background-color (colors/resolve-color :danger theme)}}})
|
||||
|
||||
(def max-value 100)
|
||||
|
||||
(defn root-container
|
||||
[{:keys [customization-color state theme]}]
|
||||
(let [{:keys [background-color border-color]} (get-in (border-and-background-color customization-color)
|
||||
[theme state])]
|
||||
[{:keys [customization-color state theme full-width?]}]
|
||||
(let [{:keys [background-color border-color]} (get-in (border-and-background-color customization-color
|
||||
theme)
|
||||
[theme (if full-width? :pending state)])]
|
||||
{:height 12
|
||||
:flex (when full-width? 1)
|
||||
:width (when (not full-width?) 8)
|
||||
:border-radius 3
|
||||
:border-width 1
|
||||
:border-color border-color
|
||||
:background-color background-color
|
||||
:margin-horizontal 1
|
||||
:margin-vertical 2}))
|
||||
|
||||
(defn progressed-bar
|
||||
[{:keys [customization-color state theme progressed-value]}]
|
||||
(let [{:keys [background-color]} (get-in (border-and-background-color customization-color theme)
|
||||
[theme state])
|
||||
progress (if (> progressed-value max-value) max-value progressed-value)]
|
||||
{:height 12
|
||||
:width 8
|
||||
:margin-top -1
|
||||
:width (str progress "%")
|
||||
:border-radius 3
|
||||
:border-width 1
|
||||
:border-color border-color
|
||||
:background-color background-color}))
|
||||
|
||||
@@ -5,9 +5,11 @@
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- view-internal
|
||||
[props]
|
||||
[{:keys [full-width?] :as props}]
|
||||
[rn/view
|
||||
{:accessibility-label :progress-bar
|
||||
:style (style/root-container props)}])
|
||||
:style (style/root-container props)}
|
||||
(when full-width?
|
||||
[rn/view {:style (style/progressed-bar props)}])])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
(defn container
|
||||
[networks? theme]
|
||||
{:width 335
|
||||
{:width "100%"
|
||||
:height (if networks? 90 56)
|
||||
:border-radius 16
|
||||
:border-width 1
|
||||
|
||||
@@ -15,18 +15,26 @@
|
||||
|
||||
(defn calc-value
|
||||
[crypto? currency token value conversion]
|
||||
(if crypto?
|
||||
(str (get common/currency-label currency) (.toFixed (* value conversion) 2))
|
||||
(str (.toFixed (/ value conversion) 2) " " (string/upper-case (clj->js token)))))
|
||||
(let [num-value (if (string? value) (parse-double (or value "0")) value)]
|
||||
(if crypto?
|
||||
(str (get common/currency-label currency) (.toFixed (* num-value conversion) 2))
|
||||
(str (.toFixed (/ num-value conversion) 2) " " (string/upper-case (or (clj->js token) ""))))))
|
||||
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [width (:width (rn/get-window))
|
||||
value (reagent/atom 0)
|
||||
crypto? (reagent/atom true)
|
||||
input-ref (atom nil)]
|
||||
(fn [{:keys [theme token currency conversion networks title customization-color]}]
|
||||
[rn/view {:style (style/main-container width)}
|
||||
[{external-value :value}]
|
||||
(let [width (:width (rn/get-window))
|
||||
value (reagent/atom nil)
|
||||
crypto? (reagent/atom true)
|
||||
input-ref (atom nil)
|
||||
controlled-input? (some? external-value)]
|
||||
(fn [{:keys [theme token currency conversion networks title customization-color
|
||||
on-change-text on-swap container-style show-keyboard?]
|
||||
:or {show-keyboard? true}
|
||||
external-value :value}]
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/main-container width)
|
||||
container-style)}
|
||||
[rn/view {:style style/amount-container}
|
||||
[rn/pressable
|
||||
{:on-press #(when @input-ref (.focus ^js @input-ref))
|
||||
@@ -37,27 +45,39 @@
|
||||
{:style style/token
|
||||
:source (resources/get-token token)}]
|
||||
[rn/text-input
|
||||
{:ref #(reset! input-ref %)
|
||||
:placeholder "0"
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)
|
||||
:keyboard-type :numeric
|
||||
:max-length 12
|
||||
:default-value @value
|
||||
:on-change-text #(reset! value %)
|
||||
:style (style/text-input theme)
|
||||
:selection-color customization-color}]
|
||||
(cond-> {:auto-focus true
|
||||
:ref #(reset! input-ref %)
|
||||
:placeholder "0"
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40
|
||||
colors/neutral-50
|
||||
theme)
|
||||
:keyboard-type :numeric
|
||||
:max-length 12
|
||||
:on-change-text (fn [v]
|
||||
(when-not controlled-input?
|
||||
(reset! value v))
|
||||
(when on-change-text
|
||||
(on-change-text v)))
|
||||
:style (style/text-input theme)
|
||||
:selection-color customization-color
|
||||
:show-soft-input-on-focus show-keyboard?}
|
||||
controlled-input? (assoc :value external-value)
|
||||
(not controlled-input?) (assoc :default-value @value))]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :semi-bold
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:margin-right 8
|
||||
:padding-bottom 2}}
|
||||
(string/upper-case (clj->js (if @crypto? token currency)))]]
|
||||
(string/upper-case (or (clj->js (if @crypto? token currency)) ""))]]
|
||||
[button/button
|
||||
{:icon true
|
||||
:icon-only? true
|
||||
:size 32
|
||||
:on-press #(swap! crypto? not)
|
||||
:on-press (fn []
|
||||
(swap! crypto? not)
|
||||
(when on-swap
|
||||
(on-swap @crypto?)))
|
||||
:type :outline
|
||||
:accessibility-label :reorder}
|
||||
:i/reorder]]
|
||||
@@ -68,6 +88,6 @@
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
|
||||
(calc-value @crypto? currency token @value conversion)]]])))
|
||||
(calc-value @crypto? currency token (or external-value @value) conversion)]]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -0,0 +1,200 @@
|
||||
(ns quo.components.wallet.transaction-progress.component-spec
|
||||
(:require [quo.core :as quo]
|
||||
[reagent.core :as reagent]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn- get-test-data
|
||||
[{:keys [state network]
|
||||
:or {state :pending network :mainnet}}]
|
||||
{:title "Title"
|
||||
:tag-name "Doodle"
|
||||
:tag-number "120"
|
||||
:network network
|
||||
:customization-color :blue
|
||||
:networks [{:network :mainnet
|
||||
:state state
|
||||
:counter (reagent/atom 0)
|
||||
:total-box 85
|
||||
:progress 30
|
||||
:epoch-number "123"}
|
||||
{:network :optimism
|
||||
:state state
|
||||
:progress "50"
|
||||
:epoch-number "123"}
|
||||
{:network :arbitrum
|
||||
:state state
|
||||
:progress "30"
|
||||
:epoch-number "123"}]
|
||||
:on-press (fn []
|
||||
(js/alert "Transaction progress item pressed"))})
|
||||
|
||||
(h/describe "Transaction Progress"
|
||||
(h/test "component renders without props"
|
||||
(h/render [quo/transaction-progress])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is pending and network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is sending and network is optimism-arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :sending
|
||||
:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is confirmed and network is optimism-arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :confirmed
|
||||
:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is finalising and network is optimism-arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :finalising
|
||||
:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is finalized and network is optimism-arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :finalized
|
||||
:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is error and network is optimism-arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :error
|
||||
:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is sending and network is optimism"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :sending
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is confirmed and network is optimism"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :confirmed
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is finalising and network is optimism"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :finalising
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is finalized and network is optimism"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :finalized
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is error and network is optimism"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :error
|
||||
:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is sending and network is arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :sending
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is confirmed and network is arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :confirmed
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is finalising and network is arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :finalising
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is finalized and network is arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :finalized
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is error and network is arbitrum"
|
||||
(h/render [quo/transaction-progress
|
||||
(get-test-data {:state :error
|
||||
:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is pending and network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is sending and network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {:state :sending})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is confirmed and network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {:state :confirmed})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is finalising and network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {:state :finalising})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is finalized and network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {:state :finalized})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "component renders when state is error and network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {:state :error})])
|
||||
(h/is-truthy (h/get-by-label-text :transaction-progress)))
|
||||
|
||||
(h/test "mainnet progress box is visible network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {})])
|
||||
(h/is-truthy (h/get-by-label-text :mainnet-progress-box)))
|
||||
|
||||
(h/test "arbitrum-optimism progress box is visible network is optimism-arbitrum"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-all-by-label-text :progress-box)))
|
||||
|
||||
(h/test "arbitrum progress box is visible network is arbitrum"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :arbitrum})])
|
||||
(h/is-truthy (h/get-all-by-label-text :progress-box)))
|
||||
|
||||
(h/test "optimism progress box is visible network is optimism"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :optimism})])
|
||||
(h/is-truthy (h/get-all-by-label-text :progress-box)))
|
||||
|
||||
(h/test "title is visible network is optimism-arbitrum"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-by-text "Title")))
|
||||
|
||||
(h/test "title is visible network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {})])
|
||||
(h/is-truthy (h/get-by-text "Title")))
|
||||
|
||||
(h/test "title is visible network is optimism"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :optimism})])
|
||||
(h/is-truthy (h/get-by-text "Title")))
|
||||
|
||||
(h/test "title is visible network is arbitrum"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-text "Title")))
|
||||
|
||||
(h/test "context tag is visible network is optimism-arbitrum"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :optimism-arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :context-tag)))
|
||||
|
||||
(h/test "context tag is visible network is mainnet"
|
||||
(h/render [quo/transaction-progress (get-test-data {})])
|
||||
(h/is-truthy (h/get-by-label-text :context-tag)))
|
||||
|
||||
(h/test "context tag is visible network is optimism"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :optimism})])
|
||||
(h/is-truthy (h/get-by-label-text :context-tag)))
|
||||
|
||||
(h/test "context tag is visible network is optimism"
|
||||
(h/render [quo/transaction-progress (get-test-data {:network :arbitrum})])
|
||||
(h/is-truthy (h/get-by-label-text :context-tag))))
|
||||
@@ -0,0 +1,38 @@
|
||||
(ns quo.components.wallet.transaction-progress.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def title-text-container
|
||||
{:flex 1})
|
||||
|
||||
(def icon
|
||||
{:margin-right 4})
|
||||
|
||||
(defn box-style
|
||||
[theme]
|
||||
{:border-radius 16
|
||||
:border-width 1
|
||||
:border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)})
|
||||
|
||||
(def title-container
|
||||
{:align-items :center
|
||||
:flex-direction :row
|
||||
:padding-left 12
|
||||
:padding-top 8
|
||||
:padding-right 8
|
||||
:padding-bottom 4})
|
||||
|
||||
(def status-row-container
|
||||
{:flex-direction :row
|
||||
:align-items :center
|
||||
:flex 1
|
||||
:padding-horizontal 12
|
||||
:padding-top 8
|
||||
:padding-bottom 4})
|
||||
|
||||
(defn context-tag-container
|
||||
[theme]
|
||||
{:padding-horizontal 12
|
||||
:padding-bottom 8
|
||||
:flex-direction :row
|
||||
:border-bottom-width 1
|
||||
:border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)})
|
||||
@@ -0,0 +1,187 @@
|
||||
(ns quo.components.wallet.transaction-progress.view
|
||||
(:require [quo.components.buttons.button.view :as button]
|
||||
[quo.components.icon :as icons]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.context-tag.view :as context-tag]
|
||||
[quo.components.wallet.confirmation-progress.view :as confirmation-progress]
|
||||
[quo.components.wallet.transaction-progress.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(def ^:private max-mainnet-verifications 4)
|
||||
(def ^:private max-sidenet-verifications 1)
|
||||
|
||||
(defn- icon-internal
|
||||
([icon]
|
||||
(icon-internal icon nil 20))
|
||||
([icon color]
|
||||
(icon-internal icon color 20))
|
||||
([icon color size]
|
||||
[rn/view {:style style/icon}
|
||||
[icons/icon
|
||||
icon
|
||||
{:color color
|
||||
:size size
|
||||
:no-color (when (not color) true)}]]))
|
||||
|
||||
(defn- text-internal
|
||||
[{:keys [weight size accessibility-label color]
|
||||
:or {weight :semi-bold
|
||||
size :paragraph-1}}
|
||||
title]
|
||||
[text/text
|
||||
{:accessibility-label accessibility-label
|
||||
:ellipsize-mode :tail
|
||||
:number-of-lines 1
|
||||
:weight weight
|
||||
:size size
|
||||
:style {:color color}}
|
||||
title])
|
||||
|
||||
(defn- network-type-text
|
||||
[state]
|
||||
(case state
|
||||
(:sending :pending) (i18n/label :t/pending-on)
|
||||
(:confirmed :finalising) (i18n/label :t/confirmed-on)
|
||||
:finalized (i18n/label :t/finalized-on)
|
||||
:error (i18n/label :t/failed-on)
|
||||
nil))
|
||||
|
||||
(defn- calculate-counter
|
||||
[counter]
|
||||
(if (< counter 4) counter max-mainnet-verifications))
|
||||
|
||||
(defn mainnet-label
|
||||
[counter]
|
||||
(str counter "/" max-mainnet-verifications))
|
||||
|
||||
(defn subnet-label
|
||||
[counter]
|
||||
(str counter "/" max-sidenet-verifications))
|
||||
|
||||
(defn- text-steps
|
||||
[network state epoch-number counter]
|
||||
(let [steps (case network
|
||||
:mainnet
|
||||
{:pending (mainnet-label 0)
|
||||
:sending (mainnet-label (calculate-counter counter))
|
||||
:confirmed (mainnet-label (calculate-counter counter))
|
||||
:finalising (mainnet-label (calculate-counter counter))
|
||||
:finalized (i18n/label :t/epoch-number {:number epoch-number})
|
||||
:error (mainnet-label 0)}
|
||||
(or :optimism :arbitrum)
|
||||
{:pending (subnet-label 0)
|
||||
:sending (subnet-label 0)
|
||||
:confirmed (subnet-label 0)
|
||||
:finalising (subnet-label 1)
|
||||
:finalized (i18n/label :t/epoch-number {:number epoch-number})
|
||||
:error (subnet-label 0)}
|
||||
nil)]
|
||||
(get steps state)))
|
||||
|
||||
(defn- get-status-icon
|
||||
[theme state]
|
||||
(case state
|
||||
(:pending :sending) {:icon :i/pending-state
|
||||
:color (colors/theme-colors colors/neutral-50
|
||||
colors/neutral-40
|
||||
theme)}
|
||||
(:confirmed :finalising) {:icon :i/positive-state
|
||||
:color (colors/resolve-color :success theme)}
|
||||
:finalized {:icon :i/diamond}
|
||||
:error {:icon :i/negative-state
|
||||
:color (colors/resolve-color :danger theme)}
|
||||
nil))
|
||||
|
||||
(defn- get-network
|
||||
[networks network]
|
||||
(some #(when (= (:network %) network) %)
|
||||
networks))
|
||||
|
||||
(defn- calculate-error-state
|
||||
[networks]
|
||||
(some #(= (:state %) :error) networks))
|
||||
|
||||
(defn- title-internal
|
||||
[{:keys [title theme networks]}]
|
||||
[rn/view {:style style/title-container}
|
||||
[icon-internal :i/placeholder (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)]
|
||||
[rn/view {:style style/title-text-container}
|
||||
[text-internal nil title]]
|
||||
(when (calculate-error-state networks)
|
||||
[button/button
|
||||
{:size 24
|
||||
:icon-left :i/refresh}
|
||||
(i18n/label :t/retry)])])
|
||||
|
||||
(defn- tag-internal
|
||||
[tag-photo tag-name tag-number theme]
|
||||
[rn/view {:style (style/context-tag-container theme)}
|
||||
[context-tag/view
|
||||
{:size 24
|
||||
:collectible tag-photo
|
||||
:collectible-name tag-name
|
||||
:collectible-number tag-number
|
||||
:type :collectible}]])
|
||||
|
||||
(defn- get-network-text
|
||||
[network]
|
||||
(case network
|
||||
:arbitrum (i18n/label :t/arbitrum)
|
||||
:mainnet (i18n/label :t/mainnet)
|
||||
:optimism (i18n/label :t/optimism)
|
||||
nil))
|
||||
|
||||
(defn- status-row
|
||||
[{:keys [theme state network epoch-number counter]}]
|
||||
(let [{:keys [icon color]} (get-status-icon theme state)]
|
||||
[rn/view {:style style/status-row-container}
|
||||
[icon-internal icon color 16]
|
||||
[rn/view {:style style/title-text-container}
|
||||
[text-internal
|
||||
{:weight :regular
|
||||
:size :paragraph-2}
|
||||
(str (network-type-text state) " " (get-network-text network))]]
|
||||
[rn/view
|
||||
[text-internal
|
||||
{:weight :regular
|
||||
:size :paragraph-2
|
||||
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}
|
||||
(text-steps network state epoch-number counter)]]]))
|
||||
|
||||
(defn- view-network
|
||||
[{:keys [theme state epoch-number counter total-box progress network]}]
|
||||
[:<>
|
||||
[status-row
|
||||
{:theme theme
|
||||
:state state
|
||||
:network network
|
||||
:epoch-number epoch-number
|
||||
:counter counter}]
|
||||
[confirmation-progress/view
|
||||
{:state state
|
||||
:network network
|
||||
:counter counter
|
||||
:total-box total-box
|
||||
:progress-value progress}]])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [title on-press accessibility-label theme tag-photo tag-name tag-number networks]
|
||||
:or {accessibility-label :transaction-progress}}]
|
||||
[rn/touchable-without-feedback
|
||||
{:on-press on-press
|
||||
:accessibility-label accessibility-label}
|
||||
[rn/view {:style (style/box-style theme)}
|
||||
[title-internal
|
||||
{:title title
|
||||
:theme theme
|
||||
:networks networks}]
|
||||
[tag-internal tag-photo tag-name tag-number theme]
|
||||
(for [network networks]
|
||||
^{:key (:network network)}
|
||||
(let [assoc-props #(get-network networks %)]
|
||||
[view-network (assoc-props (:network network))]))]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
+17
-1
@@ -48,6 +48,7 @@
|
||||
quo.components.drawers.drawer-buttons.view
|
||||
quo.components.drawers.drawer-top.view
|
||||
quo.components.drawers.permission-context.view
|
||||
quo.components.dropdowns.dropdown-input.view
|
||||
quo.components.dropdowns.dropdown.view
|
||||
quo.components.dropdowns.network-dropdown.view
|
||||
quo.components.empty-state.empty-state.view
|
||||
@@ -65,6 +66,7 @@
|
||||
quo.components.inputs.recovery-phrase.view
|
||||
quo.components.inputs.search-input.view
|
||||
quo.components.inputs.title-input.view
|
||||
quo.components.ios.drawer-bar.view
|
||||
quo.components.keycard.view
|
||||
quo.components.links.link-preview.view
|
||||
quo.components.links.url-preview-list.view
|
||||
@@ -100,6 +102,7 @@
|
||||
quo.components.numbered-keyboard.keyboard-key.view
|
||||
quo.components.numbered-keyboard.numbered-keyboard.view
|
||||
quo.components.onboarding.small-option-card.view
|
||||
quo.components.overlay.view
|
||||
quo.components.password.tips.view
|
||||
quo.components.profile.collectible.view
|
||||
quo.components.profile.profile-card.view
|
||||
@@ -137,11 +140,13 @@
|
||||
quo.components.tags.tiny-tag.view
|
||||
quo.components.tags.token-tag.view
|
||||
quo.components.text-combinations.channel-name.view
|
||||
quo.components.text-combinations.standard-title.view
|
||||
quo.components.text-combinations.view
|
||||
quo.components.wallet.account-card.view
|
||||
quo.components.wallet.account-origin.view
|
||||
quo.components.wallet.account-overview.view
|
||||
quo.components.wallet.address-text.view
|
||||
quo.components.wallet.confirmation-progress.view
|
||||
quo.components.wallet.keypair.view
|
||||
quo.components.wallet.network-amount.view
|
||||
quo.components.wallet.network-bridge.view
|
||||
@@ -150,6 +155,7 @@
|
||||
quo.components.wallet.progress-bar.view
|
||||
quo.components.wallet.summary-info.view
|
||||
quo.components.wallet.token-input.view
|
||||
quo.components.wallet.transaction-progress.view
|
||||
quo.components.wallet.transaction-summary.view
|
||||
quo.components.wallet.wallet-activity.view
|
||||
quo.components.wallet.wallet-overview.view))
|
||||
@@ -232,6 +238,7 @@
|
||||
|
||||
;;;; Dropdowns
|
||||
(def dropdown quo.components.dropdowns.dropdown.view/view)
|
||||
(def dropdown-input quo.components.dropdowns.dropdown-input.view/view)
|
||||
(def network-dropdown quo.components.dropdowns.network-dropdown.view/view)
|
||||
|
||||
;;;; Empty State
|
||||
@@ -264,6 +271,9 @@
|
||||
(def search-input quo.components.inputs.search-input.view/search-input)
|
||||
(def title-input quo.components.inputs.title-input.view/view)
|
||||
|
||||
;;;; iOS
|
||||
(def drawer-bar quo.components.ios.drawer-bar.view/view)
|
||||
|
||||
;;;; Numbered Keyboard
|
||||
(def keyboard-key quo.components.numbered-keyboard.keyboard-key.view/view)
|
||||
(def numbered-keyboard quo.components.numbered-keyboard.numbered-keyboard.view/view)
|
||||
@@ -314,6 +324,9 @@
|
||||
(def notification quo.components.notifications.notification.view/notification)
|
||||
(def toast quo.components.notifications.toast.view/toast)
|
||||
|
||||
;;;; Overlay
|
||||
(def overlay quo.components.overlay.view/view)
|
||||
|
||||
;;;; Password
|
||||
(def tips quo.components.password.tips.view/view)
|
||||
|
||||
@@ -369,14 +382,16 @@
|
||||
(def token-tag quo.components.tags.token-tag.view/view)
|
||||
|
||||
;;;; Text combinations
|
||||
(def text-combinations quo.components.text-combinations.view/view)
|
||||
(def channel-name quo.components.text-combinations.channel-name.view/view)
|
||||
(def standard-title quo.components.text-combinations.standard-title.view/view)
|
||||
(def text-combinations quo.components.text-combinations.view/view)
|
||||
|
||||
;;;; Wallet
|
||||
(def account-card quo.components.wallet.account-card.view/view)
|
||||
(def account-origin quo.components.wallet.account-origin.view/view)
|
||||
(def account-overview quo.components.wallet.account-overview.view/view)
|
||||
(def address-text quo.components.wallet.address-text.view/view)
|
||||
(def confirmation-propgress quo.components.wallet.confirmation-progress.view/view)
|
||||
(def keypair quo.components.wallet.keypair.view/view)
|
||||
(def network-amount quo.components.wallet.network-amount.view/view)
|
||||
(def network-bridge quo.components.wallet.network-bridge.view/view)
|
||||
@@ -387,4 +402,5 @@
|
||||
(def token-input quo.components.wallet.token-input.view/view)
|
||||
(def wallet-overview quo.components.wallet.wallet-overview.view/view)
|
||||
(def wallet-activity quo.components.wallet.wallet-activity.view/view)
|
||||
(def transaction-progress quo.components.wallet.transaction-progress.view/view)
|
||||
(def transaction-summary quo.components.wallet.transaction-summary.view/view)
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
[quo.components.drawers.drawer-buttons.component-spec]
|
||||
[quo.components.drawers.drawer-top.component-spec]
|
||||
[quo.components.drawers.permission-context.component-spec]
|
||||
[quo.components.dropdowns.dropdown-input.component-spec]
|
||||
[quo.components.dropdowns.dropdown.component-spec]
|
||||
[quo.components.dropdowns.network-dropdown.component-spec]
|
||||
[quo.components.gradient.gradient-cover.component-spec]
|
||||
@@ -79,6 +80,7 @@
|
||||
[quo.components.wallet.account-card.component-spec]
|
||||
[quo.components.wallet.account-origin.component-spec]
|
||||
[quo.components.wallet.account-overview.component-spec]
|
||||
[quo.components.wallet.confirmation-progress.component-spec]
|
||||
[quo.components.wallet.keypair.component-spec]
|
||||
[quo.components.wallet.network-amount.component-spec]
|
||||
[quo.components.wallet.network-bridge.component-spec]
|
||||
@@ -86,6 +88,7 @@
|
||||
[quo.components.wallet.progress-bar.component-spec]
|
||||
[quo.components.wallet.summary-info.component-spec]
|
||||
[quo.components.wallet.token-input.component-spec]
|
||||
[quo.components.wallet.transaction-progress.component-spec]
|
||||
[quo.components.wallet.transaction-summary.component-spec]
|
||||
[quo.components.wallet.wallet-activity.component-spec]
|
||||
[quo.components.wallet.wallet-overview.component-spec]))
|
||||
|
||||
@@ -148,7 +148,9 @@
|
||||
(def black-opa-30 (alpha black 0.3))
|
||||
(def black-opa-60 (alpha black 0.6))
|
||||
(def onboarding-header-black "#000716")
|
||||
|
||||
(def border-avatar-light
|
||||
"Simulates a blurred, transparent border for avatars in light mode"
|
||||
"#475060")
|
||||
;;;;Primary
|
||||
|
||||
;;Solid
|
||||
@@ -201,6 +203,16 @@
|
||||
(def danger-50-opa-30 (alpha danger-50 0.3))
|
||||
(def danger-50-opa-40 (alpha danger-50 0.4))
|
||||
|
||||
;;;;Warning
|
||||
(def warning-50 "#FF7D46")
|
||||
(def warning-60 "#CC6438")
|
||||
|
||||
;;50 with transparency
|
||||
(def warning-50-opa-5 (alpha warning-50 0.05))
|
||||
(def warning-50-opa-10 (alpha warning-50 0.1))
|
||||
(def warning-50-opa-20 (alpha warning-50 0.2))
|
||||
(def warning-50-opa-30 (alpha warning-50 0.3))
|
||||
(def warning-50-opa-40 (alpha warning-50 0.4))
|
||||
|
||||
;; Colors for customizing users account
|
||||
(def customization
|
||||
@@ -254,7 +266,9 @@
|
||||
:danger {50 danger-50
|
||||
60 danger-60}
|
||||
:success {50 success-50
|
||||
60 success-60}}
|
||||
60 success-60}
|
||||
:warning {50 warning-50
|
||||
60 warning-60}}
|
||||
customization
|
||||
networks))
|
||||
|
||||
|
||||
@@ -58,14 +58,16 @@
|
||||
|
||||
(defn save-credentials
|
||||
"Stores the credentials for the address to the Keychain"
|
||||
[server username password callback]
|
||||
(-> (.setInternetCredentials ^js react-native-keychain
|
||||
(string/lower-case server)
|
||||
username
|
||||
password
|
||||
keychain-secure-hardware
|
||||
keychain-restricted-availability)
|
||||
(.then callback)))
|
||||
([server username password]
|
||||
(save-credentials server username password identity))
|
||||
([server username password callback]
|
||||
(-> (.setInternetCredentials ^js react-native-keychain
|
||||
(string/lower-case server)
|
||||
username
|
||||
password
|
||||
keychain-secure-hardware
|
||||
keychain-restricted-availability)
|
||||
(.then callback))))
|
||||
|
||||
(defn get-credentials
|
||||
"Gets the credentials for a specified server from the Keychain"
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
[goog.object :as object]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.chat.models.mentions :as mentions]
|
||||
[status-im.chat.models.message :as chat.message]
|
||||
[status-im.chat.models.message-content :as message-content]
|
||||
[status-im.data-store.messages :as data-store-messages]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.composer.link-preview.events :as link-preview]
|
||||
[status-im2.contexts.chat.messages.transport.events :as messages.transport]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
@@ -205,7 +205,7 @@
|
||||
(rf/merge cofx
|
||||
(clean-input (:current-chat-id db))
|
||||
(link-preview/reset-unfurled)
|
||||
(chat.message/send-messages messages)))))
|
||||
(messages.transport/send-chat-messages messages)))))
|
||||
|
||||
(rf/defn send-audio-message
|
||||
[{:keys [db] :as cofx} audio-path duration current-chat-id]
|
||||
@@ -214,25 +214,26 @@
|
||||
(when-not (string/blank? audio-path)
|
||||
(rf/merge
|
||||
{:db (assoc-in db [:chat/inputs current-chat-id :metadata :responding-to-message] nil)}
|
||||
(chat.message/send-message
|
||||
(merge
|
||||
{:chat-id current-chat-id
|
||||
:content-type constants/content-type-audio
|
||||
:audio-path audio-path
|
||||
:audio-duration-ms duration
|
||||
:text (i18n/label :t/update-to-listen-audio {"locale" "en"})}
|
||||
(when message-id
|
||||
{:response-to message-id})))))))
|
||||
(messages.transport/send-chat-messages
|
||||
[(merge
|
||||
{:chat-id current-chat-id
|
||||
:content-type constants/content-type-audio
|
||||
:audio-path audio-path
|
||||
:audio-duration-ms duration
|
||||
:text (i18n/label :t/update-to-listen-audio {"locale" "en"})}
|
||||
(when message-id
|
||||
{:response-to message-id}))])))))
|
||||
|
||||
(rf/defn send-sticker-message
|
||||
[cofx {:keys [hash packID pack]} current-chat-id]
|
||||
(when-not (or (string/blank? hash) (and (string/blank? packID) (string/blank? pack)))
|
||||
(chat.message/send-message cofx
|
||||
{:chat-id current-chat-id
|
||||
:content-type constants/content-type-sticker
|
||||
:sticker {:hash hash
|
||||
:pack (int (if (string/blank? packID) pack packID))}
|
||||
:text (i18n/label :t/update-to-see-sticker {"locale" "en"})})))
|
||||
(messages.transport/send-chat-messages
|
||||
cofx
|
||||
[{:chat-id current-chat-id
|
||||
:content-type constants/content-type-sticker
|
||||
:sticker {:hash hash
|
||||
:pack (int (if (string/blank? packID) pack packID))}
|
||||
:text (i18n/label :t/update-to-see-sticker {"locale" "en"})}])))
|
||||
|
||||
(rf/defn send-edited-message
|
||||
[{:keys [db]
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
{:db (update-in db [:chats chat-id] merge chat)}))
|
||||
|
||||
(rf/defn load-chat
|
||||
{:events [:chats-list/load-chat]}
|
||||
[_ chat-id]
|
||||
{:json-rpc/call [{:method "wakuext_chat"
|
||||
:params [chat-id]
|
||||
@@ -76,9 +77,9 @@
|
||||
|
||||
(rf/defn handle-mark-all-read-in-community-successful
|
||||
{:events [::mark-all-read-in-community-successful]}
|
||||
[{:keys [db] :as cofx} chat-ids]
|
||||
[{:keys [db] :as cofx} {:keys [chats] :as _messenger-response}]
|
||||
(rf/merge cofx
|
||||
{:db (reduce mark-chat-all-read db chat-ids)
|
||||
{:db (reduce mark-chat-all-read db (map :id chats))
|
||||
:dispatch [:activity-center.notifications/fetch-unread-count]}))
|
||||
|
||||
(rf/defn handle-mark-all-read
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
[react-native.platform :as platform]
|
||||
[status-im.chat.models.loading :as chat.loading]
|
||||
[status-im.data-store.messages :as data-store.messages]
|
||||
[status-im.transport.message.protocol :as protocol]
|
||||
[status-im.utils.deprecated-types :as types]
|
||||
[status-im2.contexts.chat.messages.delete-message.events :as delete-message]
|
||||
[status-im2.contexts.chat.messages.list.events :as message-list]
|
||||
@@ -21,12 +20,6 @@
|
||||
[db chat-id clock-value]
|
||||
(>= (get-in db [:chats chat-id :deleted-at-clock-value]) clock-value))
|
||||
|
||||
(defn add-timeline-message
|
||||
[acc chat-id message-id message]
|
||||
(-> acc
|
||||
(update-in [:db :messages chat-id] assoc message-id message)
|
||||
(update-in [:db :message-lists chat-id] message-list/add message)))
|
||||
|
||||
(defn hide-message
|
||||
"Hide chat message, rebuild message-list"
|
||||
[{:keys [db]} chat-id message-id]
|
||||
@@ -145,14 +138,6 @@
|
||||
:on-error #(log/error "failed to re-send message" %)}]}
|
||||
(update-message-status chat-id message-id :sending)))
|
||||
|
||||
(rf/defn send-message
|
||||
[cofx message]
|
||||
(protocol/send-chat-messages cofx [message]))
|
||||
|
||||
(rf/defn send-messages
|
||||
[cofx messages]
|
||||
(protocol/send-chat-messages cofx messages))
|
||||
|
||||
(rf/defn handle-removed-messages
|
||||
{:events [::handle-removed-messages]}
|
||||
[{:keys [db] :as cofx} removed-messages]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.data-store.reactions :as data-store.reactions]
|
||||
[status-im.transport.message.protocol :as message.protocol]
|
||||
[status-im2.constants :as constants]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]
|
||||
@@ -63,23 +62,6 @@
|
||||
(let [reactions-w-chat-id (map #(assoc % :chat-id chat-id) reactions)]
|
||||
{:db (update db :reactions (process-reactions (:chats db)) reactions-w-chat-id)})))
|
||||
|
||||
|
||||
;; Send reactions
|
||||
|
||||
|
||||
(rf/defn send-emoji-reaction
|
||||
{:events [:models.reactions/send-emoji-reaction]}
|
||||
[{{:keys [current-chat-id]} :db :as cofx} reaction]
|
||||
(message.protocol/send-reaction cofx
|
||||
(update reaction :chat-id #(or % current-chat-id))))
|
||||
|
||||
(rf/defn send-retract-emoji-reaction
|
||||
{:events [:models.reactions/send-emoji-reaction-retraction]}
|
||||
[{{:keys [current-chat-id]} :db :as cofx} reaction]
|
||||
(message.protocol/send-retract-reaction cofx
|
||||
(update reaction :chat-id #(or % current-chat-id))))
|
||||
|
||||
|
||||
(defn message-reactions
|
||||
[current-public-key reactions]
|
||||
(reduce
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
(ns status-im.commands.core
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.wallet.utils :as wallet.utils]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn handle-prepare-accept-request-address-for-transaction
|
||||
{:events [::prepare-accept-request-address-for-transaction]}
|
||||
[{:keys [db]} message]
|
||||
{:db (assoc db
|
||||
:commands/select-account
|
||||
{:message message
|
||||
:from (wallet.utils/get-default-account (:profile/wallet-accounts
|
||||
db))})
|
||||
:show-select-acc-sheet nil})
|
||||
|
||||
(rf/defn set-selected-account
|
||||
{:events [::set-selected-account]}
|
||||
[{:keys [db]} _ account]
|
||||
{:db (-> (assoc-in db [:commands/select-account :from] account)
|
||||
(assoc :bottom-sheet/show? false))})
|
||||
|
||||
(rf/defn handle-accept-request-address-for-transaction
|
||||
{:events [::accept-request-address-for-transaction]}
|
||||
[{:keys [db]} message-id address]
|
||||
{:db (dissoc db :commands/select-account)
|
||||
:json-rpc/call [{:method "wakuext_acceptRequestAddressForTransaction"
|
||||
:params [message-id address]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent %])}]})
|
||||
|
||||
(rf/defn handle-decline-request-address-for-transaction
|
||||
{:events [::decline-request-address-for-transaction]}
|
||||
[_ message-id]
|
||||
{:json-rpc/call [{:method "wakuext_declineRequestAddressForTransaction"
|
||||
:params [message-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent %])}]})
|
||||
|
||||
(rf/defn handle-decline-request-transaction
|
||||
{:events [::decline-request-transaction]}
|
||||
[cofx message-id]
|
||||
{:json-rpc/call [{:method "wakuext_declineRequestTransaction"
|
||||
:params [message-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent %])}]})
|
||||
@@ -74,6 +74,7 @@
|
||||
:adminSettings :admin-settings
|
||||
:tokenPermissions :token-permissions
|
||||
:communityTokensMetadata :tokens-metadata
|
||||
:introMessage :intro-message
|
||||
:muteTill :muted-till})
|
||||
(update :admin-settings
|
||||
set/rename-keys
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
(ns status-im.contact.chat
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im2.contexts.contacts.events :as contact]
|
||||
[status-im2.navigation.events :as navigation]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn contact-code-submitted
|
||||
{:events [:contact.ui/contact-code-submitted]
|
||||
:interceptors [(re-frame/inject-cofx :random-id-generator)]}
|
||||
[{{:contacts/keys [new-identity]} :db :as cofx} new-contact? nickname]
|
||||
(let [{:keys [public-key ens-name]} new-identity]
|
||||
(rf/merge cofx
|
||||
#(if new-contact?
|
||||
(contact/send-contact-request % public-key)
|
||||
{:dispatch [:chat.ui/start-chat public-key ens-name]})
|
||||
#(when new-contact?
|
||||
(navigation/navigate-back %)))))
|
||||
@@ -1,13 +0,0 @@
|
||||
(ns status-im.contact.core
|
||||
(:require
|
||||
[status-im2.navigation.events :as navigation]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn open-contact-toggle-list
|
||||
{:events [:contact.ui/start-group-chat-pressed]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db
|
||||
:group/selected-contacts #{}
|
||||
:new-chat-name "")}
|
||||
(navigation/navigate-to :contact-toggle-list nil)))
|
||||
@@ -85,12 +85,3 @@
|
||||
(assoc acc public-key (enrich-contact contact profile-pictures-visibility own-public-key)))
|
||||
{}
|
||||
contacts))
|
||||
|
||||
(defn get-blocked-contacts
|
||||
[contacts]
|
||||
(reduce (fn [acc {:keys [public-key] :as contact}]
|
||||
(if (:blocked? contact)
|
||||
(conj acc public-key)
|
||||
acc))
|
||||
#{}
|
||||
contacts))
|
||||
|
||||
+19
-14
@@ -91,11 +91,11 @@
|
||||
{:chainId :chain-id
|
||||
:removed :removed?})
|
||||
name-details)]
|
||||
{:db (reduce (fn [db {:keys [username removed?] :as name-detail}]
|
||||
{:db (reduce (fn [db {:keys [username removed? chain-id] :as name-detail}]
|
||||
(if removed?
|
||||
(update-in db [:ens/names] dissoc username)
|
||||
(let [old (get-in db [:ens/names username])]
|
||||
(assoc-in db [:ens/names username] (merge old name-detail)))))
|
||||
(update-in db [:ens/names chain-id] dissoc username)
|
||||
(let [old (get-in db [:ens/names chain-id username])]
|
||||
(assoc-in db [:ens/names chain-id username] (merge old name-detail)))))
|
||||
db
|
||||
name-details)}))
|
||||
|
||||
@@ -103,8 +103,8 @@
|
||||
{:events [:ens/save-username]}
|
||||
[{:keys [db] :as cofx} custom-domain? username redirect-to-summary? connected?]
|
||||
(let [name (fullname custom-domain? username)
|
||||
names (get-in db [:ens/names] [])
|
||||
chain-id (chain/chain-id db)]
|
||||
chain-id (chain/chain-id db)
|
||||
names (get-in db [:ens/names chain-id] [])]
|
||||
(rf/merge cofx
|
||||
(cond-> {:dispatch-n [[:ens/update-usernames [{:username name :chain-id chain-id}]]]}
|
||||
connected? (assoc :json-rpc/call
|
||||
@@ -240,7 +240,8 @@
|
||||
{:events [::set-username-candidate]}
|
||||
[{:keys [db]} username]
|
||||
(let [{:keys [custom-domain?]} (:ens/registration db)
|
||||
usernames (into #{} (keys (get-in db [:ens/names])))
|
||||
chain-id (chain/chain-id db)
|
||||
usernames (into #{} (keys (get-in db [:ens/names chain-id])))
|
||||
state (state custom-domain? username usernames)]
|
||||
(reset! resolve-last-id (random/id))
|
||||
(merge
|
||||
@@ -310,20 +311,23 @@
|
||||
(rf/defn store-name-address
|
||||
{:events [::address-resolved]}
|
||||
[{:keys [db]} username address]
|
||||
{:db (assoc-in db [:ens/names username :address] address)})
|
||||
(let [chain-id (chain/chain-id db)]
|
||||
{:db (assoc-in db [:ens/names chain-id username :address] address)}))
|
||||
|
||||
(rf/defn store-name-public-key
|
||||
{:events [::public-key-resolved]}
|
||||
[{:keys [db]} username public-key]
|
||||
{:db (assoc-in db [:ens/names username :public-key] public-key)})
|
||||
(let [chain-id (chain/chain-id db)]
|
||||
{:db (assoc-in db [:ens/names chain-id username :public-key] public-key)}))
|
||||
|
||||
(rf/defn store-expiration-date
|
||||
{:events [::get-expiration-time-success]}
|
||||
[{:keys [now db]} username timestamp]
|
||||
{:db (-> db
|
||||
(assoc-in [:ens/names username :expiration-date]
|
||||
(datetime/timestamp->year-month-day-date timestamp))
|
||||
(assoc-in [:ens/names username :releasable?] (<= timestamp now)))})
|
||||
(let [chain-id (chain/chain-id db)]
|
||||
{:db (-> db
|
||||
(assoc-in [:ens/names chain-id username :expiration-date]
|
||||
(datetime/timestamp->year-month-day-date timestamp))
|
||||
(assoc-in [:ens/names chain-id username :releasable?] (<= timestamp now)))}))
|
||||
|
||||
(rf/defn navigate-to-name
|
||||
{:events [::navigate-to-name]}
|
||||
@@ -352,7 +356,8 @@
|
||||
(rf/defn remove-username
|
||||
{:events [::remove-username]}
|
||||
[{:keys [db] :as cofx} name]
|
||||
(let [names (get-in db [:ens/names] [])
|
||||
(let [chain-id (chain/chain-id db)
|
||||
names (get-in db [:ens/names chain-id] [])
|
||||
preferred-name (get-in db [:profile/profile :preferred-name])
|
||||
new-names (remove #(= name %) (keys names))
|
||||
{:keys [chain-id username]} (get-in names [name])]
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
status-im.chat.models.input
|
||||
status-im.chat.models.loading
|
||||
status-im.contact.block
|
||||
status-im.contact.chat
|
||||
status-im.contact.core
|
||||
status-im.currency.core
|
||||
status-im.ethereum.subscriptions
|
||||
status-im.fleet.core
|
||||
@@ -32,9 +30,7 @@
|
||||
status-im.pairing.core
|
||||
status-im.profile.core
|
||||
status-im.search.core
|
||||
status-im.signals.core
|
||||
status-im.stickers.core
|
||||
status-im.transport.core
|
||||
status-im.ui.components.invite.events
|
||||
[status-im.ui.components.react :as react]
|
||||
status-im.ui.screens.notifications-settings.events
|
||||
@@ -45,12 +41,12 @@
|
||||
status-im.visibility-status-popover.core
|
||||
status-im.visibility-status-updates.core
|
||||
status-im.waku.core
|
||||
status-im.wallet-connect.core
|
||||
status-im.wallet.accounts.core
|
||||
status-im.wallet.choose-recipient.core
|
||||
[status-im.wallet.core :as wallet]
|
||||
status-im.wallet.custom-tokens.core
|
||||
[status-im2.common.biometric.events :as biometric]
|
||||
status-im2.common.standard-authentication.events
|
||||
[status-im2.common.theme.core :as theme]
|
||||
[status-im2.common.universal-links :as universal-links]
|
||||
[status-im2.constants :as constants]
|
||||
@@ -136,7 +132,7 @@
|
||||
|
||||
(rf/defn on-return-from-background
|
||||
[{:keys [db now] :as cofx}]
|
||||
(let [new-account? (get db :onboarding-2/new-account?)
|
||||
(let [new-account? (get db :onboarding/new-account?)
|
||||
app-in-background-since (get db :app-in-background-since)
|
||||
signed-up? (get-in db [:profile/profile :signed-up?])
|
||||
requires-bio-auth (and
|
||||
@@ -194,9 +190,9 @@
|
||||
(rf/merge cofx
|
||||
(cond
|
||||
(= :chat view-id)
|
||||
{:async-storage-set {:chat-id (get-in cofx [:db :current-chat-id])
|
||||
:key-uid (get-in cofx [:db :profile/profile :key-uid])}
|
||||
:db (assoc db :screens/was-focused-once? true)}
|
||||
{:effects.async-storage/set {:chat-id (get-in cofx [:db :current-chat-id])
|
||||
:key-uid (get-in cofx [:db :profile/profile :key-uid])}
|
||||
:db (assoc db :screens/was-focused-once? true)}
|
||||
|
||||
(not (get db :screens/was-focused-once?))
|
||||
{:db (assoc db :screens/was-focused-once? true)})
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.node.core :as node]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -78,10 +77,9 @@
|
||||
[{:keys [db now] :as cofx} fleet]
|
||||
(let [old-fleet (get-in db [:profile/profile :fleet])]
|
||||
(when (not= fleet old-fleet)
|
||||
(rf/merge
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
(multiaccounts.update/multiaccount-update :fleet fleet {})
|
||||
(node/prepare-new-config
|
||||
{:on-success
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.update.callback/save-settings-success])})))))
|
||||
:fleet
|
||||
fleet
|
||||
{:on-success
|
||||
#(re-frame/dispatch [:logout])}))))
|
||||
|
||||
@@ -141,14 +141,14 @@
|
||||
(let [pin (get-in db [:keycard :pin :original])
|
||||
puk-restore? (get-in db [:keycard :pin :puk-restore?])]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:login pin
|
||||
:confirmation []
|
||||
:error-label nil})
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/pin-changed)}}
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:login pin
|
||||
:confirmation []
|
||||
:error-label nil})
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/pin-changed)}}
|
||||
(common/hide-connection-sheet)
|
||||
(if puk-restore?
|
||||
(navigation/navigate-to :multiaccounts nil)
|
||||
@@ -160,14 +160,14 @@
|
||||
{:events [:keycard.callback/on-change-puk-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:puk-original []
|
||||
:puk-confirmation []
|
||||
:error-label nil})
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/puk-changed)}}
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:puk-original []
|
||||
:puk-confirmation []
|
||||
:error-label nil})
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/puk-changed)}}
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
|
||||
|
||||
@@ -175,13 +175,13 @@
|
||||
{:events [:keycard.callback/on-change-pairing-success]}
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:pairing-code nil
|
||||
:error-label nil})
|
||||
:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/pairing-changed)}}
|
||||
{:db (assoc-in db
|
||||
[:keycard :pin]
|
||||
{:status nil
|
||||
:pairing-code nil
|
||||
:error-label nil})
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/pairing-changed)}}
|
||||
(common/hide-connection-sheet)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
|
||||
|
||||
|
||||
@@ -293,14 +293,14 @@
|
||||
(rf/defn show-wrong-keycard-alert
|
||||
[_]
|
||||
(log/debug "show-wrong-keycard-alert")
|
||||
{:utils/show-popup {:title (i18n/label :t/wrong-card)
|
||||
:content (i18n/label :t/wrong-card-text)}})
|
||||
{:effects.utils/show-popup {:title (i18n/label :t/wrong-card)
|
||||
:content (i18n/label :t/wrong-card-text)}})
|
||||
|
||||
(rf/defn unauthorized-operation
|
||||
[cofx]
|
||||
(rf/merge cofx
|
||||
{:utils/show-popup {:title ""
|
||||
:content (i18n/label :t/keycard-unauthorized-operation)}}
|
||||
{:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/keycard-unauthorized-operation)}}
|
||||
(clear-on-card-connected)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])))
|
||||
|
||||
|
||||
@@ -24,12 +24,12 @@
|
||||
(rf/defn show-keycard-has-multiaccount-alert
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db (assoc-in db [:keycard :setup-step] nil)
|
||||
:utils/show-confirmation {:title nil
|
||||
:content (i18n/label
|
||||
:t/keycard-has-multiaccount-on-it)
|
||||
:cancel-button-text ""
|
||||
:confirm-button-text :t/okay}}))
|
||||
{:db (assoc-in db [:keycard :setup-step] nil)
|
||||
:effects.utils/show-confirmation {:title nil
|
||||
:content (i18n/label
|
||||
:t/keycard-has-multiaccount-on-it)
|
||||
:cancel-button-text ""
|
||||
:confirm-button-text :t/okay}}))
|
||||
|
||||
(rf/defn load-pin-screen
|
||||
[{:keys [db] :as cofx}]
|
||||
@@ -548,10 +548,11 @@
|
||||
|
||||
(rf/defn show-no-keycard-applet-alert
|
||||
[_]
|
||||
{:utils/show-confirmation {:title (i18n/label :t/no-keycard-applet-on-card)
|
||||
:content (i18n/label :t/keycard-applet-install-instructions)
|
||||
:cancel-button-text ""
|
||||
:confirm-button-text :t/okay}})
|
||||
{:effects.utils/show-confirmation {:title (i18n/label :t/no-keycard-applet-on-card)
|
||||
:content (i18n/label
|
||||
:t/keycard-applet-install-instructions)
|
||||
:cancel-button-text ""
|
||||
:confirm-button-text :t/okay}})
|
||||
|
||||
;; NOTE: Maybe replaced by multiple events based on on flow to make it easier to maintain.
|
||||
;; Because there are many execution paths it is harder to follow all possible states.
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
(do
|
||||
(log/debug (str "Cannot start keycard installation from state: " card-state))
|
||||
(rf/merge cofx
|
||||
{:utils/show-popup {:title (i18n/label :t/error)
|
||||
:content (i18n/label :t/something-went-wrong)}}
|
||||
{:effects.utils/show-popup {:title (i18n/label :t/error)
|
||||
:content (i18n/label :t/something-went-wrong)}}
|
||||
(navigation/navigate-to :keycard-authentication-method nil))))))
|
||||
|
||||
(rf/defn load-preparing-screen
|
||||
|
||||
@@ -11,13 +11,11 @@
|
||||
[status-im.multiaccounts.model :as multiaccounts.model]
|
||||
[status-im.popover.core :as popover]
|
||||
[status-im.utils.deprecated-types :as types]
|
||||
[status-im.utils.keychain.core :as keychain]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.address :as address]
|
||||
[utils.datetime :as datetime]
|
||||
[utils.ethereum.eip.eip55 :as eip55]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
@@ -183,26 +181,28 @@
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] nil)
|
||||
(dissoc :intro-wizard))}
|
||||
(multiaccounts.create/on-multiaccount-created
|
||||
{:recovered (or recovered (get-in db [:intro-wizard :recovering?]))
|
||||
:derived {constants/path-wallet-root-keyword
|
||||
{:public-key wallet-root-public-key
|
||||
:address (eip55/address->checksum wallet-root-address)}
|
||||
constants/path-whisper-keyword
|
||||
{:public-key whisper-public-key
|
||||
:address (eip55/address->checksum whisper-address)}
|
||||
constants/path-default-wallet-keyword
|
||||
{:public-key wallet-public-key
|
||||
:address (eip55/address->checksum wallet-address)}}
|
||||
:address address
|
||||
:public-key public-key
|
||||
:keycard-instance-uid instance-uid
|
||||
:key-uid (address/normalized-hex key-uid)
|
||||
:keycard-pairing pairing
|
||||
:keycard-paired-on paired-on
|
||||
:chat-key whisper-private-key}
|
||||
encryption-public-key
|
||||
{}))))
|
||||
;; NOTE: Disabling as keycard not functional and this needs to be moved to
|
||||
;; status-go
|
||||
#_(multiaccounts.create/on-multiaccount-created
|
||||
{:recovered (or recovered (get-in db [:intro-wizard :recovering?]))
|
||||
:derived {constants/path-wallet-root-keyword
|
||||
{:public-key wallet-root-public-key
|
||||
:address (eip55/address->checksum wallet-root-address)}
|
||||
constants/path-whisper-keyword
|
||||
{:public-key whisper-public-key
|
||||
:address (eip55/address->checksum whisper-address)}
|
||||
constants/path-default-wallet-keyword
|
||||
{:public-key wallet-public-key
|
||||
:address (eip55/address->checksum wallet-address)}}
|
||||
:address address
|
||||
:public-key public-key
|
||||
:keycard-instance-uid instance-uid
|
||||
:key-uid (address/normalized-hex key-uid)
|
||||
:keycard-pairing pairing
|
||||
:keycard-paired-on paired-on
|
||||
:chat-key whisper-private-key}
|
||||
encryption-public-key
|
||||
{}))))
|
||||
|
||||
(rf/defn return-to-keycard-login
|
||||
[{:keys [db] :as cofx}]
|
||||
@@ -221,12 +221,12 @@
|
||||
(rf/defn on-backup-success
|
||||
[{:keys [db] :as cofx} backup-type]
|
||||
(rf/merge cofx
|
||||
{:utils/show-popup {:title (i18n/label (if (= backup-type :recovery-card)
|
||||
:t/keycard-access-reset
|
||||
:t/keycard-backup-success-title))
|
||||
:content (i18n/label (if (= backup-type :recovery-card)
|
||||
:t/keycard-can-use-with-new-passcode
|
||||
:t/keycard-backup-success-body))}}
|
||||
{:effects.utils/show-popup {:title (i18n/label (if (= backup-type :recovery-card)
|
||||
:t/keycard-access-reset
|
||||
:t/keycard-backup-success-title))
|
||||
:content (i18n/label (if (= backup-type :recovery-card)
|
||||
:t/keycard-can-use-with-new-passcode
|
||||
:t/keycard-backup-success-body))}}
|
||||
(cond
|
||||
(multiaccounts.model/logged-in? db)
|
||||
(navigation/set-stack-root :profile-stack [:my-profile :keycard-settings])
|
||||
@@ -278,7 +278,7 @@
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/profiles-overview key-uid :keycard-pairing] pairing)
|
||||
(assoc :profile/login account)
|
||||
(assoc :auth-method keychain/auth-method-none)
|
||||
(assoc :auth-method "none")
|
||||
(update :keycard dissoc :flow :migration-password)
|
||||
(dissoc :recovered-account?))
|
||||
::finish-migration [account settings password encryption-pass login-params]}))
|
||||
@@ -373,4 +373,3 @@
|
||||
cofx
|
||||
{:on-card-connected :keycard/load-recovering-key-screen
|
||||
:handler (common/dispatch-event :keycard/import-multiaccount)}))
|
||||
|
||||
|
||||
@@ -489,14 +489,15 @@
|
||||
(log/warn "sign-typed-data not implemented" args))
|
||||
|
||||
(defn save-multiaccount-and-login
|
||||
[{:keys [key-uid multiaccount-data password settings node-config accounts-data]}]
|
||||
(native-module/save-account-and-login
|
||||
key-uid
|
||||
(types/clj->json multiaccount-data)
|
||||
password
|
||||
(types/clj->json settings)
|
||||
node-config
|
||||
(types/clj->json accounts-data)))
|
||||
[_]
|
||||
;; NOTE: disabling as we don't support keycard for now and it's using an outdated endpoint
|
||||
#_(native-module/save-account-and-login
|
||||
key-uid
|
||||
(types/clj->json multiaccount-data)
|
||||
password
|
||||
(types/clj->json settings)
|
||||
node-config
|
||||
(types/clj->json accounts-data)))
|
||||
|
||||
(defn login
|
||||
[{:keys [key-uid multiaccount-data password]}]
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
:error-label nil
|
||||
:on-verified nil}))
|
||||
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
|
||||
:utils/show-popup {:title ""
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/card-unpaired)}}
|
||||
(common/clear-on-card-connected)
|
||||
(remove-pairing-from-multiaccount nil)
|
||||
@@ -100,7 +100,7 @@
|
||||
:error-label nil
|
||||
:on-verified nil})
|
||||
:keycard/get-application-info nil
|
||||
:utils/show-popup {:title ""
|
||||
:effects.utils/show-popup {:title ""
|
||||
:content (i18n/label :t/something-went-wrong)}}
|
||||
(common/clear-on-card-connected)
|
||||
(navigation/navigate-to :keycard-settings nil)))
|
||||
@@ -139,15 +139,14 @@
|
||||
:error-label nil
|
||||
:on-verified nil}))
|
||||
:keycard/persist-pairings (dissoc pairings (keyword instance-uid))
|
||||
:utils/show-popup {:title (i18n/label (if keys-removed-from-card?
|
||||
:effects.utils/show-popup {:title (i18n/label (if keys-removed-from-card?
|
||||
:t/profile-deleted-title
|
||||
:t/database-reset-title))
|
||||
:content (i18n/label (if keys-removed-from-card?
|
||||
:t/profile-deleted-keycard
|
||||
:t/database-reset-content))
|
||||
:on-dismiss #(re-frame/dispatch [:logout])}}
|
||||
;;should be reimplemented
|
||||
;;:key-storage/delete-profile {:key-uid key-uid
|
||||
;;should be reimplemented :key-storage/delete-profile {:key-uid key-uid
|
||||
;;:on-success #(log/debug "[keycard] remove account ok")
|
||||
;; :on-error #(log/warn "[keycard] remove account: " %)}
|
||||
(common/clear-on-card-connected)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.node.core :as node]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -11,13 +10,11 @@
|
||||
[{:keys [db now] :as cofx} log-level]
|
||||
(let [old-log-level (get-in db [:profile/profile :log-level])]
|
||||
(when (not= old-log-level log-level)
|
||||
(rf/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:log-level
|
||||
log-level
|
||||
{})
|
||||
(node/prepare-new-config
|
||||
{:on-success #(re-frame/dispatch [:logout])})))))
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
:log-level
|
||||
log-level
|
||||
{:on-success #(re-frame/dispatch [:logout])}))))
|
||||
|
||||
(rf/defn show-change-log-level-confirmation
|
||||
{:events [:log-level.ui/log-level-selected]}
|
||||
|
||||
@@ -194,7 +194,7 @@
|
||||
{:events [:mailserver.ui/request-error-pressed]}
|
||||
[{:keys [db]}]
|
||||
(let [mailserver-error (:mailserver/request-error db)]
|
||||
{:utils/show-confirmation
|
||||
{:effects.utils/show-confirmation
|
||||
{:title (i18n/label :t/mailserver-request-error-title)
|
||||
:content (i18n/label :t/mailserver-request-error-content
|
||||
{:error mailserver-error})
|
||||
@@ -290,8 +290,7 @@
|
||||
[{:method "mailservers_addMailserver"
|
||||
:params [(mailserver->rpc mailserver current-fleet)]
|
||||
:on-success (fn []
|
||||
;; we naively logout if the user is connected to
|
||||
;; the edited mailserver
|
||||
;; we naively logout if the user is connected to the edited mailserver
|
||||
(when current
|
||||
(re-frame/dispatch
|
||||
[:multiaccounts.logout.ui/logout-confirmed]))
|
||||
@@ -413,3 +412,17 @@
|
||||
(rf/merge cofx
|
||||
{:db (dissoc db :mailserver.edit/mailserver)}
|
||||
(navigation/navigate-to :edit-mailserver nil)))
|
||||
|
||||
(defn add-mailservers
|
||||
[db mailservers]
|
||||
(reduce (fn [db {:keys [fleet id name] :as mailserver}]
|
||||
(let [updated-mailserver
|
||||
(-> mailserver
|
||||
(update :id keyword)
|
||||
(assoc :name (if (seq name) name id))
|
||||
(dissoc :fleet))]
|
||||
(assoc-in db
|
||||
[:mailserver/mailservers (keyword fleet) (keyword id)]
|
||||
updated-mailserver)))
|
||||
db
|
||||
mailservers))
|
||||
|
||||
@@ -2,17 +2,10 @@
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.data-store.settings :as data-store.settings]
|
||||
[status-im.node.core :as node]
|
||||
[status-im.ui.components.colors :as colors]
|
||||
[status-im.utils.deprecated-types :as types]
|
||||
[status-im.utils.signing-phrase.core :as signing-phrase]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.constants :as constants]
|
||||
[utils.ethereum.eip.eip55 :as eip55]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn normalize-derived-data-keys
|
||||
[derived-data]
|
||||
@@ -82,134 +75,3 @@
|
||||
(rf/defn save-multiaccount-and-login-with-keycard
|
||||
[_ args]
|
||||
{:keycard/save-multiaccount-and-login args})
|
||||
|
||||
(re-frame/reg-fx
|
||||
::save-account-and-login
|
||||
(fn [[key-uid multiaccount-data hashed-password settings config accounts-data]]
|
||||
(native-module/save-account-and-login
|
||||
key-uid
|
||||
multiaccount-data
|
||||
hashed-password
|
||||
settings
|
||||
config
|
||||
accounts-data)))
|
||||
|
||||
(rf/defn save-account-and-login
|
||||
[_ key-uid multiaccount-data password settings node-config accounts-data]
|
||||
{::save-account-and-login [key-uid
|
||||
(types/clj->json multiaccount-data)
|
||||
password
|
||||
(types/clj->json settings)
|
||||
node-config
|
||||
(types/clj->json accounts-data)]})
|
||||
|
||||
(defn prepare-accounts-data
|
||||
[multiaccount]
|
||||
[(let [{:keys [public-key address]}
|
||||
(get-in multiaccount [:derived constants/path-default-wallet-keyword])]
|
||||
{:public-key public-key
|
||||
:address (eip55/address->checksum address)
|
||||
:color colors/blue-persist
|
||||
:wallet true
|
||||
:path constants/path-default-wallet
|
||||
:name (i18n/label :t/main-account)})
|
||||
(let [{:keys [compressed-key public-key address name]}
|
||||
(get-in multiaccount [:derived constants/path-whisper-keyword])]
|
||||
{:public-key public-key
|
||||
:compressed-key compressed-key
|
||||
:address (eip55/address->checksum address)
|
||||
:name name
|
||||
:path constants/path-whisper
|
||||
:chat true})])
|
||||
|
||||
(rf/defn on-multiaccount-created
|
||||
[{:keys [signing-phrase random-guid-generator db] :as cofx}
|
||||
{:keys [address chat-key keycard-instance-uid key-uid
|
||||
keycard-pairing keycard-paired-on mnemonic recovered]
|
||||
:as multiaccount}
|
||||
password
|
||||
{:keys [save-mnemonic? login?] :or {login? true save-mnemonic? false}}]
|
||||
(let [[wallet-account
|
||||
{:keys [public-key
|
||||
compressed-key
|
||||
name]} :as accounts-data]
|
||||
(prepare-accounts-data
|
||||
multiaccount)
|
||||
multiaccount-data {:name name
|
||||
:address address
|
||||
:key-uid key-uid
|
||||
:keycard-pairing keycard-pairing}
|
||||
keycard-multiaccount? (boolean keycard-pairing)
|
||||
eip1581-address (get-in multiaccount
|
||||
[:derived
|
||||
constants/path-eip1581-keyword
|
||||
:address])
|
||||
new-multiaccount
|
||||
(cond->
|
||||
(merge
|
||||
{;; address of the master key
|
||||
:address address
|
||||
;; sha256 of master public key
|
||||
:key-uid key-uid
|
||||
;; The address from which we derive any wallet
|
||||
:wallet-root-address
|
||||
(get-in multiaccount
|
||||
[:derived
|
||||
constants/path-wallet-root-keyword
|
||||
:address])
|
||||
:name name
|
||||
;; public key of the chat account
|
||||
:public-key public-key
|
||||
;; compressed key of the chat account
|
||||
:compressed-key compressed-key
|
||||
;; default address for Dapps
|
||||
:dapps-address (:address wallet-account)
|
||||
:latest-derived-path 0
|
||||
:signing-phrase signing-phrase
|
||||
:backup-enabled? true
|
||||
:installation-id (random-guid-generator)
|
||||
;; default mailserver (history node) setting
|
||||
:use-mailservers? true
|
||||
:recovered recovered}
|
||||
config/default-multiaccount)
|
||||
;; The address from which we derive any chat
|
||||
;; account/encryption keys
|
||||
eip1581-address
|
||||
(assoc :eip1581-address eip1581-address)
|
||||
save-mnemonic?
|
||||
(assoc :mnemonic mnemonic)
|
||||
keycard-multiaccount?
|
||||
(assoc :keycard-instance-uid keycard-instance-uid
|
||||
:keycard-pairing keycard-pairing
|
||||
:keycard-paired-on keycard-paired-on))
|
||||
db (assoc db
|
||||
:profile/login {:key-uid key-uid
|
||||
:name name
|
||||
:password password
|
||||
:creating? true
|
||||
:processing true}
|
||||
:profile/profile new-multiaccount
|
||||
:profile/wallet-accounts [wallet-account]
|
||||
:networks/current-network config/default-network
|
||||
:networks/networks (data-store.settings/rpc->networks config/default-networks))
|
||||
settings (assoc new-multiaccount
|
||||
:networks/current-network config/default-network
|
||||
:networks/networks config/default-networks)]
|
||||
(rf/merge cofx
|
||||
{:db db}
|
||||
(if keycard-multiaccount?
|
||||
(save-multiaccount-and-login-with-keycard
|
||||
{:key-uid key-uid
|
||||
:multiaccount-data multiaccount-data
|
||||
:password password
|
||||
:settings settings
|
||||
:node-config (node/get-new-config db)
|
||||
:accounts-data accounts-data
|
||||
:chat-key chat-key})
|
||||
(save-account-and-login
|
||||
key-uid
|
||||
multiaccount-data
|
||||
(native-module/sha3 (security/safe-unmask-data password))
|
||||
settings
|
||||
(node/get-new-config db)
|
||||
accounts-data)))))
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
(rf/merge cofx
|
||||
{:set-root :progress
|
||||
:chat.ui/clear-inputs nil
|
||||
:shell/reset-state nil
|
||||
:effects.shell/reset-state nil
|
||||
:hide-popover nil
|
||||
::logout nil
|
||||
:profile.settings/webview-debug-changed false
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.node.core :as node]
|
||||
[status-im2.navigation.events :as navigation]
|
||||
[utils.ethereum.chain :as chain]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -89,7 +88,7 @@
|
||||
(rf/defn connect-failure
|
||||
{:events [::connect-failure]}
|
||||
[_ reason]
|
||||
{:utils/show-popup
|
||||
{:effects.utils/show-popup
|
||||
{:title (i18n/label :t/error)
|
||||
:content (str reason)}})
|
||||
|
||||
@@ -117,12 +116,10 @@
|
||||
(rf/defn save-network-settings
|
||||
{:events [::save-network-settings-pressed]}
|
||||
[{:keys [db] :as cofx} network]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db :networks/current-network network)
|
||||
:json-rpc/call [{:method "settings_saveSetting"
|
||||
:params [:networks/current-network network]
|
||||
:on-success #()}]}
|
||||
(node/prepare-new-config {:on-success #(re-frame/dispatch [:logout])})))
|
||||
{:db (assoc db :networks/current-network network)
|
||||
:json-rpc/call [{:method "settings_saveSetting"
|
||||
:params [:networks/current-network network]
|
||||
:on-success #(re-frame/dispatch [:logout])}]})
|
||||
|
||||
(rf/defn remove-network
|
||||
{:events [::remove-network-confirmed]}
|
||||
|
||||
@@ -1,12 +1,9 @@
|
||||
(ns status-im.node.core
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.utils.deprecated-types :as types]
|
||||
[status-im2.config :as config]
|
||||
[utils.re-frame :as rf]))
|
||||
[status-im2.config :as config]))
|
||||
|
||||
(defn- add-custom-bootnodes
|
||||
[config network all-bootnodes]
|
||||
@@ -196,32 +193,4 @@
|
||||
:always
|
||||
(add-log-level log-level))))
|
||||
|
||||
(defn get-new-config
|
||||
[db]
|
||||
(types/clj->json (get-multiaccount-node-config db)))
|
||||
|
||||
(rf/defn save-new-config
|
||||
"Saves a new status-go config for the current account
|
||||
This RPC method is the only way to change the node config of an account.
|
||||
NOTE: it is better used indirectly through `prepare-new-config`,
|
||||
which will take care of building up the proper config based on settings in
|
||||
app-db"
|
||||
{:events [::save-new-config]}
|
||||
[_ config {:keys [on-success]}]
|
||||
{:json-rpc/call [{:method "settings_saveSetting"
|
||||
:params [:node-config config]
|
||||
:on-success on-success}]})
|
||||
|
||||
(rf/defn prepare-new-config
|
||||
"Use this function to apply settings to the current account node config"
|
||||
[{:keys [db]} {:keys [on-success]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{::prepare-new-config [key-uid
|
||||
(get-new-config db)
|
||||
#(re-frame/dispatch
|
||||
[::save-new-config % {:on-success on-success}])]}))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::prepare-new-config
|
||||
(fn [[key-uid config callback]]
|
||||
(native-module/prepare-dir-and-update-config key-uid config callback)))
|
||||
|
||||
@@ -165,9 +165,9 @@
|
||||
(if (< (count (filter :enabled? (vals (get-in cofx [:db :pairing/installations]))))
|
||||
(inc config/max-installations))
|
||||
{:pairing/enable-installation [installation-id]}
|
||||
{:utils/show-popup {:title (i18n/label :t/pairing-maximum-number-reached-title)
|
||||
{:effects.utils/show-popup {:title (i18n/label :t/pairing-maximum-number-reached-title)
|
||||
|
||||
:content (i18n/label :t/pairing-maximum-number-reached-content)}}))
|
||||
:content (i18n/label :t/pairing-maximum-number-reached-content)}}))
|
||||
|
||||
(rf/defn disable-fx
|
||||
{:events [:pairing.ui/disable-installation-pressed]}
|
||||
|
||||
@@ -49,8 +49,8 @@
|
||||
[{:keys [db] :as cofx} {:keys [chat-id]}]
|
||||
(if-not (own-public-key? db chat-id)
|
||||
{:dispatch [:chat.ui/start-chat chat-id]}
|
||||
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
||||
:content (i18n/label :t/can-not-add-yourself)}}))
|
||||
{:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
||||
:content (i18n/label :t/can-not-add-yourself)}}))
|
||||
|
||||
(rf/defn handle-group-chat
|
||||
[cofx params]
|
||||
@@ -71,9 +71,9 @@
|
||||
(navigation/navigate-back))
|
||||
|
||||
:else
|
||||
{:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
||||
:content (i18n/label :t/ens-name-not-found)
|
||||
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
|
||||
{:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
||||
:content (i18n/label :t/ens-name-not-found)
|
||||
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
|
||||
|
||||
(rf/defn handle-eip681
|
||||
[cofx data]
|
||||
@@ -103,9 +103,9 @@
|
||||
(log/info "Unable to find matcher for scanned value"
|
||||
{:type type
|
||||
:event ::match-scanned-value})
|
||||
{:dispatch [:navigate-back]
|
||||
:utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
||||
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
|
||||
{:dispatch [:navigate-back]
|
||||
:effects.utils/show-popup {:title (i18n/label :t/unable-to-read-this-code)
|
||||
:on-dismiss #(re-frame/dispatch [:pop-to-root :shell-stack])}})))
|
||||
|
||||
(rf/defn on-scan
|
||||
{:events [::on-scan-success]}
|
||||
|
||||
@@ -78,9 +78,9 @@
|
||||
[{:keys [db]} data typed? result]
|
||||
(let [{:keys [result error]} (types/json->clj result)]
|
||||
(if error
|
||||
{:dispatch [:signing.ui/cancel-is-pressed]
|
||||
:utils/show-popup {:title (i18n/label :t/sign-request-failed)
|
||||
:content (:message error)}}
|
||||
{:dispatch [:signing.ui/cancel-is-pressed]
|
||||
:effects.utils/show-popup {:title (i18n/label :t/sign-request-failed)
|
||||
:content (:message error)}}
|
||||
{:db (update db
|
||||
:keycard assoc
|
||||
:hash result
|
||||
|
||||
@@ -60,10 +60,17 @@
|
||||
{:state state
|
||||
:username username}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:ens/current-names
|
||||
:<- [:ens/names]
|
||||
:<- [:chain-id]
|
||||
(fn [[all-names chain-id]]
|
||||
(get all-names chain-id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:ens.name/screen
|
||||
:<- [:get-screen-params :ens-name-details]
|
||||
:<- [:ens/names]
|
||||
:<- [:ens/current-names]
|
||||
(fn [[name ens]]
|
||||
(let [{:keys [address public-key expiration-date releasable?]} (get ens name)
|
||||
pending? (nil? address)]
|
||||
@@ -79,7 +86,7 @@
|
||||
|
||||
(re-frame/reg-sub
|
||||
:ens.main/screen
|
||||
:<- [:ens/names]
|
||||
:<- [:ens/current-names]
|
||||
:<- [:profile/profile]
|
||||
:<- [:ens/preferred-name]
|
||||
:<- [:ens/registrations]
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
(ns ^{:doc "API to init and stop whisper messaging"} status-im.transport.core
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.pairing.core :as pairing]
|
||||
[status-im.stickers.core :as stickers]
|
||||
status-im.transport.shh
|
||||
[status-im2.common.universal-links :as universal-links]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn set-node-info
|
||||
{:events [:transport.callback/node-info-fetched]}
|
||||
[{:keys [db]} node-info]
|
||||
{:db (assoc db :node-info node-info)})
|
||||
|
||||
(rf/defn fetch-node-info-fx
|
||||
[_]
|
||||
{:json-rpc/call [{:method "admin_nodeInfo"
|
||||
:on-success #(re-frame/dispatch [:transport.callback/node-info-fetched %])
|
||||
:on-error #(log/error "node-info: failed error" %)}]})
|
||||
|
||||
(defn add-mailservers
|
||||
[db mailservers]
|
||||
(reduce (fn [db {:keys [fleet id name] :as mailserver}]
|
||||
(let [updated-mailserver
|
||||
(-> mailserver
|
||||
(update :id keyword)
|
||||
(assoc :name (if (seq name) name id))
|
||||
(dissoc :fleet))]
|
||||
(assoc-in db
|
||||
[:mailserver/mailservers (keyword fleet) (keyword id)]
|
||||
updated-mailserver)))
|
||||
db
|
||||
mailservers))
|
||||
|
||||
(rf/defn start-messenger
|
||||
"We should only start receiving messages/processing topics once all the
|
||||
initializiation is completed, otherwise we might receive messages/topics
|
||||
when the state has not been properly initialized."
|
||||
[_]
|
||||
{:json-rpc/call [{:method "wakuext_startMessenger"
|
||||
:on-success #(re-frame/dispatch [::messenger-started %])
|
||||
:on-error #(log/error "failed to start messenger")}]})
|
||||
|
||||
(rf/defn messenger-started
|
||||
{:events [::messenger-started]}
|
||||
[{:keys [db] :as cofx} {:keys [mailservers] :as response}]
|
||||
(log/info "Messenger started")
|
||||
(let [new-account? (get db :onboarding-2/new-account?)]
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc :messenger/started? true)
|
||||
(add-mailservers mailservers))}
|
||||
(fetch-node-info-fx)
|
||||
(pairing/init)
|
||||
(stickers/load-packs)
|
||||
(when-not new-account?
|
||||
(universal-links/process-stored-event)))))
|
||||
@@ -1,59 +0,0 @@
|
||||
(ns ^{:doc "Protocol API and protocol utils"} status-im.transport.message.protocol
|
||||
(:require
|
||||
[clojure.set :as set]
|
||||
[re-frame.core :as re-frame]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- link-preview->rpc
|
||||
[preview]
|
||||
(update preview
|
||||
:thumbnail
|
||||
(fn [thumbnail]
|
||||
(set/rename-keys thumbnail {:data-uri :dataUri}))))
|
||||
|
||||
(defn build-message
|
||||
[msg]
|
||||
(-> msg
|
||||
(update :link-previews #(map link-preview->rpc %))
|
||||
(set/rename-keys
|
||||
{:album-id :albumId
|
||||
:audio-duration-ms :audioDurationMs
|
||||
:audio-path :audioPath
|
||||
:chat-id :chatId
|
||||
:community-id :communityId
|
||||
:content-type :contentType
|
||||
:ens-name :ensName
|
||||
:image-height :imageHeight
|
||||
:image-path :imagePath
|
||||
:image-width :imageWidth
|
||||
:link-previews :linkPreviews
|
||||
:response-to :responseTo
|
||||
:sticker :sticker
|
||||
:text :text})))
|
||||
|
||||
(rf/defn send-chat-messages
|
||||
[_ messages]
|
||||
{:json-rpc/call [{:method "wakuext_sendChatMessages"
|
||||
:params [(mapv build-message messages)]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:transport/message-sent %])
|
||||
:on-error #(do
|
||||
(log/warn "failed to send a message" %)
|
||||
(js/alert (str "failed to send a message: " %)))}]})
|
||||
|
||||
(rf/defn send-reaction
|
||||
[_ {:keys [message-id chat-id emoji-id]}]
|
||||
{:json-rpc/call [{:method "wakuext_sendEmojiReaction"
|
||||
:params [chat-id message-id emoji-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to send a reaction" %)}]})
|
||||
|
||||
(rf/defn send-retract-reaction
|
||||
[_ {:keys [emoji-reaction-id]}]
|
||||
{:json-rpc/call [{:method "wakuext_sendEmojiReactionRetraction"
|
||||
:params [emoji-reaction-id]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])
|
||||
:on-error #(log/error "failed to send a reaction retraction" %)}]})
|
||||
@@ -1,35 +0,0 @@
|
||||
(ns ^{:doc "Whisper API and events for managing keys and posting messages"} status-im.transport.shh
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im2.common.json-rpc.events :as json-rpc]
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(defn generate-sym-key-from-password
|
||||
[{:keys [password on-success on-error]}]
|
||||
(json-rpc/call {:method "waku_generateSymKeyFromPassword"
|
||||
:params [password]
|
||||
:on-success on-success
|
||||
:on-error on-error}))
|
||||
|
||||
(defn get-sym-key
|
||||
[{:keys [sym-key-id on-success on-error]}]
|
||||
(json-rpc/call {:method "waku_getSymKey"
|
||||
:params [sym-key-id]
|
||||
:on-success on-success
|
||||
:on-error on-error}))
|
||||
|
||||
(defn log-error
|
||||
[error]
|
||||
(log/error :shh/get-new-sym-key-error error))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:shh/generate-sym-key-from-password
|
||||
(fn [{:keys [password on-success]}]
|
||||
(generate-sym-key-from-password
|
||||
{:password password
|
||||
:on-success (fn [sym-key-id]
|
||||
(get-sym-key {:sym-key-id sym-key-id
|
||||
:on-success (fn [sym-key]
|
||||
(on-success sym-key sym-key-id))
|
||||
:on-error log-error}))
|
||||
:on-error log-error})))
|
||||
@@ -1,18 +0,0 @@
|
||||
(ns ^{:doc "Utils for transport layer"} status-im.transport.utils
|
||||
(:require
|
||||
[clojure.string :as string]))
|
||||
|
||||
(defn extract-enode-id
|
||||
[enode]
|
||||
(-> enode
|
||||
(string/split #"/")
|
||||
(get 2 "")
|
||||
(string/split #":")
|
||||
(get 0 "")
|
||||
(string/split "@")
|
||||
(get 0)))
|
||||
|
||||
(defn extract-url-components
|
||||
[address]
|
||||
(when address
|
||||
(rest (re-matches #"enode://(.*?)@(.*):(.*)" address))))
|
||||
@@ -7,12 +7,16 @@
|
||||
[utils.i18n :as i18n])
|
||||
(:require-macros [status-im.utils.views :as views]))
|
||||
|
||||
(defn hide-sheet-and-dispatch
|
||||
[event]
|
||||
(re-frame/dispatch [:bottom-sheet/hide-old])
|
||||
(re-frame/dispatch event))
|
||||
|
||||
(defn- normal-mode-settings-data
|
||||
[{:keys [network-name
|
||||
current-log-level
|
||||
waku-bloom-filter-mode
|
||||
light-client-enabled?
|
||||
transactions-management-enabled?
|
||||
wakuv2-flag
|
||||
current-fleet
|
||||
webview-debug]}]
|
||||
(keep
|
||||
@@ -49,19 +53,12 @@
|
||||
:accessory :text
|
||||
:accessory-text current-fleet
|
||||
:chevron true}
|
||||
(if wakuv2-flag
|
||||
{:size :small
|
||||
:title (i18n/label :t/wakuv2-settings)
|
||||
:accessibility-label :wakuv2-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:wakuv2.ui/enter-settings-pressed])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/bootnodes)
|
||||
:accessibility-label :bootnodes-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :bootnodes-settings])
|
||||
:chevron true})
|
||||
{:size :small
|
||||
:title (i18n/label :t/wakuv2-settings)
|
||||
:accessibility-label :wakuv2-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:wakuv2.ui/enter-settings-pressed])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/rpc-usage-info)
|
||||
:accessibility-label :rpc-usage-info
|
||||
@@ -76,6 +73,15 @@
|
||||
:on-press
|
||||
#(re-frame/dispatch [:navigate-to :peers-stats])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/light-client-enabled)
|
||||
:accessibility-label :light-client-enabled
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:wakuv2.ui/toggle-light-client (not light-client-enabled?)])
|
||||
:accessory :switch
|
||||
:active light-client-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/transactions-management-enabled)
|
||||
:accessibility-label :transactions-management-enabled
|
||||
@@ -94,16 +100,7 @@
|
||||
#(re-frame/dispatch
|
||||
[:profile.settings/change-webview-debug (not webview-debug)])
|
||||
:accessory :switch
|
||||
:active webview-debug}
|
||||
{:size :small
|
||||
:title (i18n/label :t/waku-bloom-filter-mode)
|
||||
:accessibility-label :waku-bloom-filter-mode-settings-switch
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/waku-bloom-filter-mode-switched (not waku-bloom-filter-mode)])
|
||||
:accessory :switch
|
||||
:active waku-bloom-filter-mode}]))
|
||||
:active webview-debug}]))
|
||||
|
||||
(defn- flat-list-data
|
||||
[options]
|
||||
@@ -117,10 +114,9 @@
|
||||
|
||||
(views/defview advanced-settings
|
||||
[]
|
||||
(views/letsubs [{:keys [webview-debug]} [:profile/profile]
|
||||
(views/letsubs [webview-debug [:profile/webview-debug]
|
||||
light-client-enabled? [:profile/light-client-enabled?]
|
||||
network-name [:network-name]
|
||||
waku-bloom-filter-mode [:waku/bloom-filter-mode]
|
||||
wakuv2-flag [:waku/v2-flag]
|
||||
transactions-management-enabled? [:wallet-legacy/transactions-management-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
current-fleet [:fleets/current-fleet]]
|
||||
@@ -129,10 +125,9 @@
|
||||
{:network-name network-name
|
||||
:current-log-level current-log-level
|
||||
:transactions-management-enabled? transactions-management-enabled?
|
||||
:light-client-enabled? light-client-enabled?
|
||||
:current-fleet current-fleet
|
||||
:dev-mode? false
|
||||
:wakuv2-flag wakuv2-flag
|
||||
:waku-bloom-filter-mode waku-bloom-filter-mode
|
||||
:webview-debug webview-debug})
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn render-item}]))
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im.ui.screens.fleet-settings.views
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.node.core :as node]
|
||||
[status-im.ui.components.icons.icons :as icons]
|
||||
[status-im.ui.components.list.views :as list]
|
||||
[status-im.ui.components.react :as react]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user