Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6558dfc25a | ||
|
|
73e9f67dbd | ||
|
|
86c5505c94 | ||
|
|
c1dcd7a764 | ||
|
|
17ebedd6b8 | ||
|
|
2e2d15adfb | ||
|
|
1d1d586223 | ||
|
|
88dd5e04bb | ||
|
|
8f8c8dede2 | ||
|
|
2e0643fabe | ||
|
|
ec4046e543 | ||
|
|
4a44161163 | ||
|
|
b9353b1ccd | ||
|
|
5ceb7c2215 | ||
|
|
2043e9353b | ||
|
|
7153e4da48 | ||
|
|
c7cba5b4d3 | ||
|
|
45df308dd0 | ||
|
|
a74c934936 |
@@ -16,10 +16,18 @@
|
||||
:clj-kondo-config {:level :error}
|
||||
:cond-else {:level :error}
|
||||
:consistent-alias {:level :error
|
||||
:aliases {clojure.string string
|
||||
clojure.set set
|
||||
clojure.walk walk
|
||||
taoensso.timbre log}}
|
||||
:aliases {clojure.set set
|
||||
clojure.string string
|
||||
clojure.walk walk
|
||||
malli.core malli
|
||||
malli.dev.pretty malli.pretty
|
||||
malli.dev.virhe malli.virhe
|
||||
malli.error malli.error
|
||||
malli.generator malli.generator
|
||||
malli.transform malli.transform
|
||||
malli.util malli.util
|
||||
schema.core schema
|
||||
taoensso.timbre log}}
|
||||
:deprecated-namespace {:level :warning}
|
||||
:docstring-blank {:level :error}
|
||||
:equals-true {:level :error}
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{:linters
|
||||
{:unresolved-symbol
|
||||
{:exclude [(cljs.test/is [match? thrown-match?])
|
||||
(clojure.test/is [match? thrown-match?])]}}}
|
||||
@@ -36,6 +36,7 @@
|
||||
"deftest-sub" :arg1-body
|
||||
"wait-for" :arg1-body
|
||||
"with-deps-check" :arg1-body
|
||||
"schema/=>" :arg1-body
|
||||
"->" [:noarg1-body
|
||||
{:list {:constant-pair? false :force-nl? false}
|
||||
:next-inner-restore [[:list :constant-pair?]]}]
|
||||
|
||||
@@ -311,13 +311,14 @@ endef
|
||||
lint: export TARGET := clojure
|
||||
lint: export CLJ_LINTER_PRINT_WARNINGS ?= false
|
||||
lint: ##@test Run code style checks
|
||||
@sh scripts/lint-re-frame-in-quo-components.sh && \
|
||||
sh scripts/lint-direct-require-component-outside-quo.sh && \
|
||||
@sh scripts/lint/re-frame-in-quo-components.sh && \
|
||||
sh scripts/lint/direct-require-component-outside-quo.sh && \
|
||||
sh scripts/lint/require-i18n-resource-first.sh && \
|
||||
clj-kondo --config .clj-kondo/config.edn --cache false --fail-level error --lint src $(if $(filter $(CLJ_LINTER_PRINT_WARNINGS),true),,| grep -v ': warning: ') && \
|
||||
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
|
||||
scripts/lint_translations.clj && \
|
||||
scripts/lint/translations.clj && \
|
||||
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
|
||||
sh scripts/lint-trailing-newline.sh && \
|
||||
sh scripts/lint/trailing-newline.sh && \
|
||||
node_modules/.bin/prettier --write .
|
||||
|
||||
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
|
||||
@@ -327,7 +328,7 @@ lint-fix: ##@test Run code style checks and fix issues
|
||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
|
||||
clojure-lsp --ns-exclude-regex ".*/src/status_im2/core\.cljs$$" clean-ns && \
|
||||
sh scripts/lint-trailing-newline.sh --fix && \
|
||||
sh scripts/lint/trailing-newline.sh --fix && \
|
||||
node_modules/.bin/prettier --write .
|
||||
|
||||
shadow-server: export TARGET := clojure
|
||||
|
||||
@@ -77,6 +77,7 @@ pipeline {
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
when { expression { !utils.isReleaseBuild() } }
|
||||
steps { script {
|
||||
env.DIAWI_URL = ios.uploadToDiawi()
|
||||
env.PKG_URL = env.DIAWI_URL
|
||||
|
||||
@@ -1183,11 +1183,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
return pathCombine(absRootDirPath, "keystore");
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String fleets() {
|
||||
return Statusgo.fleets();
|
||||
}
|
||||
|
||||
@ReactMethod(isBlockingSynchronousMethod = true)
|
||||
public String backupDisabledDataDir() {
|
||||
return this.getNoBackupDirectory();
|
||||
|
||||
@@ -981,10 +981,6 @@ RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isAddress:(NSString *)address) {
|
||||
return StatusgoIsAddress(address);
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(fleets) {
|
||||
return StatusgoFleets();
|
||||
}
|
||||
|
||||
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(toChecksumAddress:(NSString *)address) {
|
||||
return StatusgoToChecksumAddress(address);
|
||||
}
|
||||
|
||||
@@ -298,7 +298,6 @@ void _MultiAccountStoreAccount(const FunctionCallbackInfo<Value>& args) {
|
||||
delete c;
|
||||
}
|
||||
|
||||
|
||||
void _InitKeystore(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
@@ -563,17 +562,6 @@ void _CheckAddressChecksum(const FunctionCallbackInfo<Value>& args) {
|
||||
|
||||
}
|
||||
|
||||
void _Fleets(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
// Call exported Go function, which returns a C string
|
||||
char *c = Fleets();
|
||||
|
||||
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
|
||||
args.GetReturnValue().Set(ret);
|
||||
delete c;
|
||||
}
|
||||
|
||||
|
||||
void _IsAddress(const FunctionCallbackInfo<Value>& args) {
|
||||
Isolate* isolate = args.GetIsolate();
|
||||
Local<Context> context = isolate->GetCurrentContext();
|
||||
@@ -1900,7 +1888,6 @@ void init(Local<Object> exports) {
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreDerivedAccounts", _MultiAccountStoreDerivedAccounts);
|
||||
NODE_SET_METHOD(exports, "multiAccountStoreAccount", _MultiAccountStoreAccount);
|
||||
NODE_SET_METHOD(exports, "initKeystore", _InitKeystore);
|
||||
NODE_SET_METHOD(exports, "fleets", _Fleets);
|
||||
NODE_SET_METHOD(exports, "stopCPUProfiling", _StopCPUProfiling);
|
||||
NODE_SET_METHOD(exports, "encodeTransfer", _EncodeTransfer);
|
||||
NODE_SET_METHOD(exports, "encodeFunctionCall", _EncodeFunctionCall);
|
||||
|
||||
@@ -45,11 +45,20 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "borkdude/edamame/1.1.17/edamame-1.1.17",
|
||||
"path": "borkdude/dynaload/0.3.5/dynaload-0.3.5",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "9087f7abf0104e0354d7db7fc4576608eac558f4",
|
||||
"sha256": "1n1872i240lakn4pzsag4grf7bv7lcsipmqllxd9m4k1zp3dgla1"
|
||||
"sha1": "accd696ba364b850b4d92e38f5a34d0e828a0ad1",
|
||||
"sha256": "0k62m1f29xfh3cp67w7kcvkp5aj35simi8kf95ycvkmgp76w11q8"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "borkdude/edamame/1.3.23/edamame-1.3.23",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "254d023e97ed438f0f44532b5a06d928d031ede4",
|
||||
"sha256": "0l7mxza2nimslhg0qh6jp7gmb8sd6l89fk5d1zvzq2xskscq2vly"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -81,20 +90,20 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "cider/cider-nrepl/0.29.0/cider-nrepl-0.29.0",
|
||||
"path": "cider/cider-nrepl/0.25.3/cider-nrepl-0.25.3",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "45f6034b26a14138e74145b7a4059628c0fedcd1",
|
||||
"sha256": "1dy1l6y8cb8xiqq97a4lf8giyiicq4wfl4s2lxn5fb6614cjxqx2"
|
||||
"sha1": "5ae0efd9377a5e60c084bdaf4a2ce094f759ce23",
|
||||
"sha256": "0drxf9nm23i1pcgrkwbcr09msq37csilzww38709add0hz8spjhq"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "cider/piggieback/0.5.2/piggieback-0.5.2",
|
||||
"path": "cider/piggieback/0.4.1/piggieback-0.4.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "ecfd5c286a85db3f059e75c37fca5722d9e26f79",
|
||||
"sha256": "1ps9yf3cxmlm447hqkidjb5xry90n0wl3jk0jn28fagq31lzylkl"
|
||||
"sha1": "0a02a3e2ecd7a126ab60d8a44793342f20ced79b",
|
||||
"sha256": "142vl5np33akcrnn6pksi0rjfsmmi528villxsj6cwcndvybiw4m"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -539,6 +548,24 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "metosin/malli/0.13.0/malli-0.13.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "286c52d26a3a9d613b5f692971bd19c581cdc4b0",
|
||||
"sha256": "0vaq9d6cln5j4ww302fwlgg7m647cf2j16gs2i1p1d4klbn4jddz"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "mvxcvi/arrangement/2.1.0/arrangement-2.1.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "1bc8f3bba7a28de85f319b7d464aa8d955f44918",
|
||||
"sha256": "1j1rkwrs4wm8zk9v7ilgpnyav5sipdd2bmb83sazh392blw52wpk"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "net/cgrand/macrovich/0.2.1/macrovich-0.2.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
@@ -728,6 +755,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/test.check/1.1.1/test.check-1.1.1",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "f33d988fd57bc9c11af1952db81c10f319c91416",
|
||||
"sha256": "0y2hpkj7zl4yrpsl35ifpdaja5c72b8fpjcnmdgmld9c7cb1hlcl"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -909,11 +945,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "refactor-nrepl/refactor-nrepl/3.6.0/refactor-nrepl-3.6.0",
|
||||
"path": "refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "2b3bb82da53b5db9c2b2aa298417816b81d0ed97",
|
||||
"sha256": "1ysqabmlnghki6x0636zngxza2d83c85276wp9ma9wk183mkv52a"
|
||||
"sha1": "6bc3441afc94f7ca024e41a864ca75e05df7e207",
|
||||
"sha256": "0w8hax99y98l53mixxzx2ja0vcnhjv8dnsaz1zj3vqk775ns5w6i"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -3,12 +3,13 @@ babashka/fs/0.2.16/fs-0.2.16.jar
|
||||
bidi/bidi/2.1.6/bidi-2.1.6.jar
|
||||
binaryage/env-config/0.2.2/env-config-0.2.2.jar
|
||||
binaryage/oops/0.7.2/oops-0.7.2.jar
|
||||
borkdude/edamame/1.1.17/edamame-1.1.17.jar
|
||||
borkdude/dynaload/0.3.5/dynaload-0.3.5.jar
|
||||
borkdude/edamame/1.3.23/edamame-1.3.23.jar
|
||||
borkdude/sci.impl.reflector/0.0.1/sci.impl.reflector-0.0.1.jar
|
||||
camel-snake-kebab/camel-snake-kebab/0.4.3/camel-snake-kebab-0.4.3.jar
|
||||
cheshire/cheshire/5.11.0/cheshire-5.11.0.jar
|
||||
cider/cider-nrepl/0.29.0/cider-nrepl-0.29.0.jar
|
||||
cider/piggieback/0.5.2/piggieback-0.5.2.jar
|
||||
cider/cider-nrepl/0.25.3/cider-nrepl-0.25.3.jar
|
||||
cider/piggieback/0.4.1/piggieback-0.4.1.jar
|
||||
clj-kondo/clj-kondo/2023.09.07/clj-kondo-2023.09.07.jar
|
||||
cljs-bean/cljs-bean/1.9.0/cljs-bean-1.9.0.jar
|
||||
clout/clout/2.1.2/clout-2.1.2.jar
|
||||
@@ -58,6 +59,8 @@ javax/annotation/jsr250-api/1.0/jsr250-api-1.0.jar
|
||||
javax/servlet/servlet-api/2.5/servlet-api-2.5.jar
|
||||
javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar
|
||||
medley/medley/0.8.2/medley-0.8.2.jar
|
||||
metosin/malli/0.13.0/malli-0.13.0.jar
|
||||
mvxcvi/arrangement/2.1.0/arrangement-2.1.0.jar
|
||||
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
|
||||
@@ -79,6 +82,7 @@ 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/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
|
||||
org/clojure/tools.analyzer.jvm/1.2.2/tools.analyzer.jvm-1.2.2.jar
|
||||
org/clojure/tools.cli/1.0.206/tools.cli-1.0.206.jar
|
||||
@@ -99,7 +103,7 @@ org/wildfly/common/wildfly-common/1.5.2.Final/wildfly-common-1.5.2.Final.jar
|
||||
prismatic/schema/1.1.7/schema-1.1.7.jar
|
||||
reagent/reagent/1.2.0/reagent-1.2.0.jar
|
||||
re-com/re-com/2.8.0/re-com-2.8.0.jar
|
||||
refactor-nrepl/refactor-nrepl/3.6.0/refactor-nrepl-3.6.0.jar
|
||||
refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0.jar
|
||||
re-frame/re-frame/1.3.0/re-frame-1.3.0.jar
|
||||
re-frisk-remote/re-frisk-remote/1.6.0/re-frisk-remote-1.6.0.jar
|
||||
re-frisk/sente/1.15.0/sente-1.15.0.jar
|
||||
|
||||
@@ -67,9 +67,12 @@ stdenv.mkDerivation {
|
||||
'';
|
||||
buildPhase = ''
|
||||
# Assemble CLASSPATH from available clojure dependencies.
|
||||
# We append 'src' so it can find the local sources.
|
||||
export CLASS_PATH="$(find ${deps.clojure} \
|
||||
-iname '*.jar' | tr '\n' ':')src"
|
||||
# We prepend 'src' so it can find the local sources and prioritize
|
||||
# our own namespaces over dependencies, given that indirect dependencies
|
||||
# can also cause naming conflicts (e.g. prismatic/schema already uses
|
||||
# namespace schema.core).
|
||||
export CLASS_PATH="src:$(find ${deps.clojure} \
|
||||
-iname '*.jar' | tr '\n' ':')"
|
||||
|
||||
# target must be one of the builds defined in shadow-cljs.edn
|
||||
java -cp "$CLASS_PATH" clojure.main \
|
||||
|
||||
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
After Width: | Height: | Size: 61 KiB |
|
After Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 16 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 30 KiB |
@@ -0,0 +1,10 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
if rg --quiet --multiline '^\(ns.*\n^\s*\(:require\n(^\s*(;|#_).*\n)*(^\s*\[status-im2\.setup\.i18n-resources\W)' src/status_im2/core.cljs; then
|
||||
exit 0
|
||||
elif [ $? -eq 1 ]; then
|
||||
echo "status-im2.setup.i18n-resources must be loaded first (be the first one in ns :require form) in status-im2.core"
|
||||
echo "For more info, check the comment here https://github.com/status-im/status-mobile/pull/17618#discussion_r1361275489"
|
||||
else
|
||||
exit $?
|
||||
fi
|
||||
@@ -9,6 +9,7 @@
|
||||
[cljs-bean "1.9.0"]
|
||||
[com.cognitect/transit-cljs "0.8.280"]
|
||||
[camel-snake-kebab "0.4.3"]
|
||||
[metosin/malli "0.13.0"]
|
||||
|
||||
;; Dev dependencies
|
||||
[refactor-nrepl "2.5.0"]
|
||||
@@ -50,6 +51,7 @@
|
||||
:after-load-async status-im2.setup.hot-reload/reload
|
||||
:build-notify status-im2.setup.hot-reload/build-notify
|
||||
:preloads [re-frisk-remote.preload
|
||||
status-im2.setup.schema-preload
|
||||
;; In order to use component test helpers in the REPL we
|
||||
;; need to preload namespaces that are not normally required
|
||||
;; by production code, such as
|
||||
@@ -71,6 +73,10 @@
|
||||
:warnings {:fn-deprecated false}
|
||||
:closure-defines {re-frame.trace/trace-enabled? true}
|
||||
:source-map false
|
||||
;; This seems to be necessary while using the REPL,
|
||||
;; otherwise sometimes you'll get weird errors when
|
||||
;; instrumenting functions.
|
||||
:static-fns false
|
||||
:infer-externs true}
|
||||
;; if you want to use a real device, set your local ip
|
||||
;; in the SHADOW_HOST env variable to make sure that
|
||||
@@ -104,13 +110,15 @@
|
||||
:output-dir "target/test"
|
||||
:optimizations :simple
|
||||
:target :node-test
|
||||
:dev {:devtools {:preloads [status-im2.setup.schema-preload]}}
|
||||
;; Uncomment line below to `make test-watch` a specific file
|
||||
;; :ns-regexp "status-im2.subs.messages-test$"
|
||||
:main status-im.test-runner/main
|
||||
;; set :ui-driven to true to let shadow-cljs inject node-repl
|
||||
:ui-driven true
|
||||
:closure-defines
|
||||
{status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
{schema.core/throw-on-error? true
|
||||
status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
|
||||
status-im2.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"
|
||||
status-im2.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"
|
||||
status-im2.config/ALCHEMY_ARBITRUM_GOERLI_TOKEN #shadow/env "ALCHEMY_ARBITRUM_GOERLI_TOKEN"
|
||||
@@ -139,9 +147,17 @@
|
||||
:compiler-options {:optimizations :simple
|
||||
:source-map false}}
|
||||
:component-test {:target :npm-module
|
||||
:entries [quo.core-spec status-im2.core-spec]
|
||||
:entries [;; We need to tell shadow-cljs to compile
|
||||
;; the preloads namespace because it will
|
||||
;; be used directly by Jest in the option
|
||||
;; setupFilesAfterEnv.
|
||||
status-im2.setup.schema-preload
|
||||
|
||||
quo.core-spec
|
||||
status-im2.core-spec]
|
||||
:ns-regexp "component-spec$"
|
||||
:output-dir "component-spec"
|
||||
:closure-defines {schema.core/throw-on-error? true}
|
||||
:compiler-options {:warnings-as-errors false
|
||||
:static-fns false
|
||||
:infer-externs true}}}}
|
||||
|
||||
@@ -40,6 +40,23 @@
|
||||
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]
|
||||
@@ -519,10 +536,6 @@
|
||||
[]
|
||||
(.backupDisabledDataDir ^js (status)))
|
||||
|
||||
(defn fleets
|
||||
[]
|
||||
(.fleets ^js (status)))
|
||||
|
||||
(defn keystore-dir
|
||||
[]
|
||||
(.keystoreDir ^js (status)))
|
||||
|
||||
@@ -3,18 +3,22 @@
|
||||
[quo.components.counter.step.view :as step]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn render
|
||||
[component]
|
||||
(h/render-with-theme-provider component :dark))
|
||||
|
||||
(h/describe "step component"
|
||||
(h/test "default render of step component"
|
||||
(h/render [step/view {} nil])
|
||||
(render [step/view {} nil])
|
||||
(-> (h/expect (h/query-by-label-text :step-counter))
|
||||
(h/is-truthy)))
|
||||
|
||||
(h/test "renders step with a string value"
|
||||
(h/render [step/view {} "1"])
|
||||
(render [step/view {} "1"])
|
||||
(-> (h/expect (h/get-by-text "1"))
|
||||
(h/is-truthy)))
|
||||
|
||||
(h/test "renders step with an integer value"
|
||||
(h/render [step/view {} 1])
|
||||
(render [step/view {} 1])
|
||||
(-> (h/expect (h/get-by-text "1"))
|
||||
(h/is-truthy))))
|
||||
|
||||
@@ -2,10 +2,24 @@
|
||||
(:require
|
||||
[quo.components.counter.step.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.theme :as theme]
|
||||
quo.theme
|
||||
[react-native.core :as rn]
|
||||
[schema.core :as schema]
|
||||
[utils.number]))
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:catn
|
||||
[:props
|
||||
[:map {:closed true}
|
||||
[:accessibility-label {:optional true} [:maybe :keyword]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:in-blur-view? {:optional true} [:maybe :boolean]]
|
||||
[:theme :schema.common/theme]
|
||||
[:type {:optional true} [:enum :active :complete :neutral]]]]
|
||||
[:value [:maybe [:or :string :int]]]]
|
||||
:any])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [type accessibility-label theme in-blur-view? customization-color]} value]
|
||||
(let [type (or type :neutral)
|
||||
@@ -23,6 +37,9 @@
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :label
|
||||
:style {:color (style/text-color type theme)}} label]]))
|
||||
:style {:color (style/text-color type theme)}}
|
||||
label]]))
|
||||
|
||||
(def view (theme/with-theme view-internal))
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'view-internal ?schema)))
|
||||
|
||||
@@ -19,3 +19,7 @@
|
||||
:background-color colors/danger-50
|
||||
:align-items :center
|
||||
:justify-content :center})
|
||||
|
||||
(def empty-state
|
||||
{:width 375
|
||||
:height 116})
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
(:require
|
||||
[quo.components.graph.utils :as utils]
|
||||
[quo.components.graph.wallet-graph.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.resources :as resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.charts :as charts]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.linear-gradient :as linear-gradient]))
|
||||
|
||||
(defn- time-frame->max-data-points
|
||||
@@ -42,11 +43,10 @@
|
||||
gradient-colors [(colors/alpha line-color 0.1) (colors/alpha line-color 0)]
|
||||
fill-color (colors/theme-colors colors/white colors/neutral-95)]
|
||||
(if (= time-frame :empty)
|
||||
[rn/view
|
||||
{:accessibility-label :illustration
|
||||
:style style/illustration}
|
||||
[text/text {:style {:color colors/white}}
|
||||
"Illustration here"]]
|
||||
[fast-image/fast-image
|
||||
{:style style/empty-state
|
||||
:source (resources/get-themed-image :no-funds theme)
|
||||
:accessibility-label :illustration}]
|
||||
[rn/view
|
||||
[linear-gradient/linear-gradient
|
||||
{:colors gradient-colors
|
||||
|
||||
@@ -3,22 +3,17 @@
|
||||
[quo.components.icon :as quo.icons]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as theme]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(def themes
|
||||
{:light {:default colors/neutral-50
|
||||
:success colors/success-50
|
||||
:error colors/danger-50}
|
||||
:dark {:default colors/neutral-40
|
||||
:success colors/success-60
|
||||
:error colors/danger-60}})
|
||||
|
||||
(defn get-color
|
||||
[k]
|
||||
(get-in themes [(theme/get-theme) k]))
|
||||
[k theme]
|
||||
(case k
|
||||
:success (colors/resolve-color :success theme)
|
||||
:error (colors/resolve-color :danger theme)
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
|
||||
|
||||
(defn info-message
|
||||
(defn view-internal
|
||||
"[info-message opts \"message\"]
|
||||
opts
|
||||
{:type :default/:success/:error
|
||||
@@ -27,11 +22,11 @@
|
||||
:text-color colors/white ;; text color override
|
||||
:icon-color colors/white ;; icon color override
|
||||
:no-icon-color? false ;; disable tint color for icon"
|
||||
[{:keys [type size icon text-color icon-color no-icon-color? style]} message]
|
||||
[{:keys [type size theme icon text-color icon-color no-icon-color? style accessibility-label]} message]
|
||||
(let [weight (if (= size :default) :regular :medium)
|
||||
icon-size (if (= size :default) 16 12)
|
||||
size (if (= size :default) :paragraph-2 :label)
|
||||
text-color (or text-color (get-color type))
|
||||
text-color (or text-color (get-color type theme))
|
||||
icon-color (or icon-color text-color)]
|
||||
[rn/view
|
||||
{:style (merge {:flex-direction :row
|
||||
@@ -42,7 +37,10 @@
|
||||
:no-color no-icon-color?
|
||||
:size icon-size}]
|
||||
[text/text
|
||||
{:size size
|
||||
:weight weight
|
||||
:style {:color text-color
|
||||
:margin-horizontal 4}} message]]))
|
||||
{:accessibility-label accessibility-label
|
||||
:size size
|
||||
:weight weight
|
||||
:style {:color text-color
|
||||
:margin-horizontal 4}} message]]))
|
||||
|
||||
(def info-message (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -22,9 +22,10 @@
|
||||
(h/is-truthy (h/get-by-text "test description")))
|
||||
|
||||
(h/test "renders step component when step-number is valid and type is step"
|
||||
(h/render [list/view
|
||||
{:type :step
|
||||
:step-number 1}])
|
||||
(h/render-with-theme-provider [list/view
|
||||
{:type :step
|
||||
:step-number 1}]
|
||||
:dark)
|
||||
(h/is-truthy (h/get-by-label-text :step-counter)))
|
||||
|
||||
(h/test "renders decription with a context tag component and description after the tag"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns quo.components.settings.data-item.component-spec
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.resources :as quo.resources]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe
|
||||
@@ -161,7 +162,8 @@
|
||||
:subtitle "Description"
|
||||
:icon :i/placeholder
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow}])
|
||||
:customization-color :yellow
|
||||
:network-image (quo.resources/get-network :ethereum)}])
|
||||
(h/is-truthy (h/query-by-label-text :description-image)))
|
||||
|
||||
(h/test "description emoji is visible when description is account"
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.settings.data-item.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.foundations.resources :as quo.resources]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[utils.i18n :as i18n]))
|
||||
@@ -17,7 +16,8 @@
|
||||
[rn/view {:style (style/loading-container size blur? theme)}])
|
||||
|
||||
(defn- left-subtitle
|
||||
[{:keys [theme size description icon icon-color blur? subtitle customization-color emoji]}]
|
||||
[{:keys [theme size description icon icon-color blur? subtitle customization-color emoji
|
||||
network-image]}]
|
||||
[rn/view {:style style/subtitle-container}
|
||||
(when (not= :small size)
|
||||
[rn/view {:style (style/subtitle-icon-container description)}
|
||||
@@ -33,7 +33,7 @@
|
||||
:type :default}]
|
||||
:network [rn/image
|
||||
{:accessibility-label :description-image
|
||||
:source (quo.resources/tokens :eth)
|
||||
:source network-image
|
||||
:style style/image}]
|
||||
nil)])
|
||||
[text/text
|
||||
@@ -60,7 +60,7 @@
|
||||
(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
|
||||
customization-color network-image
|
||||
emoji]
|
||||
:as props}]
|
||||
[rn/view {:style style/left-side}
|
||||
@@ -85,7 +85,8 @@
|
||||
:blur? blur?
|
||||
:subtitle subtitle
|
||||
:customization-color customization-color
|
||||
:emoji emoji}]))])
|
||||
:emoji emoji
|
||||
:network-image network-image}]))])
|
||||
|
||||
(defn- right-side
|
||||
[{:keys [label icon-right? right-icon icon-color communities-list]}]
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
(ns quo.components.tags.summary-tag.component-spec
|
||||
(:require
|
||||
[quo.components.tags.summary-tag.view :as summary-tag]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "Summary tag component tests"
|
||||
(h/test "Basic render"
|
||||
(h/render [summary-tag/view])
|
||||
(h/is-truthy (h/query-by-label-text :container)))
|
||||
|
||||
(h/test "Account view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :account
|
||||
:label "Alice's Account"
|
||||
:customization-color "#ff0000"
|
||||
:emoji "🎉"}])
|
||||
(h/is-truthy (h/get-by-text "Alice's Account")))
|
||||
|
||||
(h/test "Network view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :network
|
||||
:label "Ethereum Network"
|
||||
:image-source "path/to/ethereum-logo.png"}])
|
||||
(h/is-truthy (h/get-by-text "Ethereum Network")))
|
||||
|
||||
(h/test "Saved address view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :saved-address
|
||||
:label "Charlie's Wallet"
|
||||
:customization-color "#00ff00"}])
|
||||
(h/is-truthy (h/get-by-text "Charlie's Wallet")))
|
||||
|
||||
(h/test "Collectible view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :collectible
|
||||
:label "Rare Artifact"
|
||||
:image-source "path/to/artifact-image.png"}])
|
||||
(h/is-truthy (h/get-by-text "Rare Artifact")))
|
||||
|
||||
(h/test "User view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :user
|
||||
:label "Bob Smith"
|
||||
:image-source "path/to/profile-pic.png"
|
||||
:customization-color "#0000ff"}])
|
||||
(h/is-truthy (h/get-by-text "Bob Smith")))
|
||||
|
||||
(h/test "Token view render"
|
||||
(h/render [summary-tag/view
|
||||
{:type :token
|
||||
:label "1,000 SNT"
|
||||
:image-source "path/to/token-image.png"}])
|
||||
(h/is-truthy (h/get-by-text "1,000 SNT"))))
|
||||
@@ -0,0 +1,29 @@
|
||||
(ns quo.components.tags.summary-tag.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn main
|
||||
[{:keys [type theme customization-color]}]
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
:height 32
|
||||
:padding-left 4
|
||||
:padding-right 10
|
||||
:flex-direction :row
|
||||
:border-radius (if (#{:account :collectible} type) 10 16)
|
||||
:background-color (colors/resolve-color customization-color theme 10)})
|
||||
|
||||
(defn label
|
||||
[type theme]
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)
|
||||
:margin-left (if (= type :address) 6 4)})
|
||||
|
||||
(def collectible-image
|
||||
{:width 24
|
||||
:height 24
|
||||
:border-radius 10})
|
||||
|
||||
(def token-image
|
||||
{:width 24
|
||||
:height 24
|
||||
:border-radius 12})
|
||||
@@ -0,0 +1,67 @@
|
||||
(ns quo.components.tags.summary-tag.view
|
||||
(:require
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.tags.summary-tag.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- left-view
|
||||
[{:keys [label type customization-color emoji image-source]}]
|
||||
(case type
|
||||
:account
|
||||
[account-avatar/view
|
||||
{:customization-color customization-color
|
||||
:size 24
|
||||
:emoji emoji
|
||||
:type :default}]
|
||||
:network
|
||||
[rn/image
|
||||
{:source image-source
|
||||
:style style/token-image}]
|
||||
:saved-address
|
||||
[wallet-user-avatar/wallet-user-avatar
|
||||
{:full-name label
|
||||
:size :size-24
|
||||
:customization-color customization-color}]
|
||||
:collectible
|
||||
[rn/image
|
||||
{:source image-source
|
||||
:style style/collectible-image}]
|
||||
:user
|
||||
[user-avatar/user-avatar
|
||||
{:full-name label
|
||||
:size :xs
|
||||
:profile-picture image-source
|
||||
:customization-color customization-color}]
|
||||
:token
|
||||
[rn/image
|
||||
{:source image-source
|
||||
:style style/token-image}]
|
||||
nil))
|
||||
|
||||
(defn- view-internal
|
||||
"Options:
|
||||
- :label - string - tag label
|
||||
- :customization-color - color - It will be passed down to components that
|
||||
should vary based on a custom color.
|
||||
- :type - :token / :user / :collectible / :saved-address / :network / :account
|
||||
- :emoji - string - emoji used for displaying account avatar
|
||||
- :image-source - resource - image to display on :network, :collectible :user and :token
|
||||
- :theme - :light / :dark"
|
||||
[{:keys [label customization-color type theme]
|
||||
:as props
|
||||
:or {customization-color colors/neutral-80-opa-5}}]
|
||||
[rn/view
|
||||
{:accessibility-label :container
|
||||
:style (style/main (assoc props :customization-color customization-color))}
|
||||
[left-view props]
|
||||
[text/text
|
||||
{:style (style/label type theme)
|
||||
:weight :semi-bold
|
||||
:size :heading-1} label]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -131,6 +131,7 @@
|
||||
quo.components.tags.number-tag.view
|
||||
quo.components.tags.permission-tag
|
||||
quo.components.tags.status-tags
|
||||
quo.components.tags.summary-tag.view
|
||||
quo.components.tags.tag
|
||||
quo.components.tags.tags
|
||||
quo.components.tags.tiny-tag.view
|
||||
@@ -211,7 +212,7 @@
|
||||
|
||||
;;;; Counter
|
||||
(def counter quo.components.counter.counter.view/view)
|
||||
(def step quo.components.counter.step.view/view)
|
||||
(def step #'quo.components.counter.step.view/view)
|
||||
|
||||
;;;; Dividers
|
||||
(def divider-label quo.components.dividers.divider-label.view/view)
|
||||
@@ -360,6 +361,7 @@
|
||||
(def number-tag quo.components.tags.number-tag.view/view)
|
||||
(def permission-tag quo.components.tags.permission-tag/tag)
|
||||
(def status-tag quo.components.tags.status-tags/status-tag)
|
||||
(def summary-tag quo.components.tags.summary-tag.view/view)
|
||||
(def tag quo.components.tags.tag/tag)
|
||||
(def tags quo.components.tags.tags/tags)
|
||||
(def tiny-tag quo.components.tags.tiny-tag.view/view)
|
||||
|
||||
@@ -73,6 +73,7 @@
|
||||
[quo.components.switchers.group-messaging-card.component-spec]
|
||||
[quo.components.tags.network-tags.component-spec]
|
||||
[quo.components.tags.status-tags-component-spec]
|
||||
[quo.components.tags.summary-tag.component-spec]
|
||||
[quo.components.tags.tiny-tag.component-spec]
|
||||
[quo.components.wallet.account-card.component-spec]
|
||||
[quo.components.wallet.account-origin.component-spec]
|
||||
|
||||
@@ -7,6 +7,15 @@
|
||||
:keycard-watermark (js/require "../resources/images/ui2/keycard-watermark.png")
|
||||
:bored-ape (js/require "../resources/images/mock2/bored-ape.png")})
|
||||
|
||||
(def ui-themed
|
||||
{:no-funds
|
||||
{:light (js/require "../resources/images/ui2/no-funds-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-funds-dark.png")}})
|
||||
|
||||
(defn get-themed-image
|
||||
[k theme]
|
||||
(get-in ui-themed [k theme]))
|
||||
|
||||
(defn get-image
|
||||
[k]
|
||||
(get ui k))
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
# Schemas
|
||||
|
||||
This document will grow to describe how we use Malli in the project and our
|
||||
conventions. It's still early days 🐪
|
||||
|
||||
## Guidelines
|
||||
### Use var quote `#'` when aliasing instrumented vars
|
||||
|
||||
It is common in this repository to have aliases to vars. For example, `view`
|
||||
referring to `var-internal`, or `quo.core/button` referring to
|
||||
`quo.components.buttons.button.view`.
|
||||
|
||||
If the original var being aliased is instrumented, the alias var MUST [var
|
||||
quote](https://clojure.org/guides/weird_characters#_var_quote) the original var.
|
||||
If you don't do this, the aliased var will not be instrumented.
|
||||
|
||||
```clojure
|
||||
;; bad, view-internal is instrumented, but both aliases don't use a var quote.
|
||||
(schema.core/=> view-internal ?schema)
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
(def button quo.components.buttons.button.view/button)
|
||||
|
||||
;; good
|
||||
(schema.core/=> view-internal ?schema)
|
||||
(def view (quo.theme/with-theme #'view-internal))
|
||||
(def button #'quo.components.buttons.button.view/button)
|
||||
```
|
||||
|
||||
### Prefix schema references with `?`
|
||||
|
||||
Prefix schema bindings and vars with a question mark `?`. This is the naming
|
||||
convention used by malli itself when functions receive instances of schemas and
|
||||
it's an unambiguous way to avoid naming clashes.
|
||||
|
||||
```clojure
|
||||
;; bad
|
||||
(def message-type [:enum ...])
|
||||
|
||||
(defn view
|
||||
[message-type] ; Shadows `message-type` schema
|
||||
(do-something message-type))
|
||||
|
||||
;; good
|
||||
(def ?message-type [:enum ...])
|
||||
|
||||
(defn view
|
||||
[message-type] ; Unambiguous naming strategy
|
||||
(do-something message-type))
|
||||
```
|
||||
|
||||
### Define schemas as functions when needed
|
||||
|
||||
Malli has many utility functions to manipulate schemas as data, and they will
|
||||
automatically check if the schemas were already defined in the registry.
|
||||
|
||||
For schemas we want to conveniently access from the global registry, like
|
||||
`:schema.common/theme`, they must be registered before Malli tries to use them.
|
||||
|
||||
```clojure
|
||||
;; bad, will fail if :schema.common/bar is not registered.
|
||||
(def ^:private ?foo
|
||||
(malli.util/select-keys :schema.common/bar [:id :name]))
|
||||
|
||||
;; good, execution will be delayed until the schema ?foo is correctly registered.
|
||||
(defn- ?foo
|
||||
[]
|
||||
(malli.util/select-keys :schema.common/bar [:id :name]))
|
||||
```
|
||||
@@ -0,0 +1,14 @@
|
||||
(ns schema.common
|
||||
(:require
|
||||
[schema.registry :as registry]))
|
||||
|
||||
(def ^:private ?theme
|
||||
[:enum :light :dark])
|
||||
|
||||
(def ^:private ?customization-color
|
||||
[:or :string :keyword])
|
||||
|
||||
(defn register-schemas
|
||||
[]
|
||||
(registry/register ::theme ?theme)
|
||||
(registry/register ::customization-color ?customization-color))
|
||||
@@ -0,0 +1,17 @@
|
||||
(ns schema.core)
|
||||
|
||||
(defmacro =>
|
||||
"Similar to `malli.core/=>`, but instrumentation code will be completely removed
|
||||
in non-debug environments.
|
||||
|
||||
`value` is first transformed via `malli.core/schema` to make sure we fail fast
|
||||
and only register valid schemas."
|
||||
[sym value]
|
||||
`(if ^boolean js/goog.DEBUG
|
||||
(try
|
||||
(malli.core/=> ~sym (malli.core/schema ~value))
|
||||
(catch js/Error e#
|
||||
(taoensso.timbre/error "Failed to instrument function"
|
||||
{:symbol ~sym :error e#})
|
||||
~sym))
|
||||
~sym))
|
||||
@@ -0,0 +1,95 @@
|
||||
(ns schema.core
|
||||
(:require-macros schema.core)
|
||||
(:require
|
||||
[malli.core :as malli]
|
||||
[malli.dev.pretty :as malli.pretty]
|
||||
schema.state
|
||||
[taoensso.timbre :as log]))
|
||||
|
||||
(goog-define throw-on-error? false)
|
||||
|
||||
(defn- ui-reporter
|
||||
"Prints to STDOUT and signals a schema error should be displayed on screen."
|
||||
[schema-id printer]
|
||||
(let [report (malli.pretty/reporter printer)]
|
||||
(fn [type data]
|
||||
(report type data)
|
||||
(swap! schema.state/errors conj schema-id))))
|
||||
|
||||
(defn- thrower
|
||||
"Similar to `malli.dev.pretty/thrower`, but this reporter uses js/Error instead
|
||||
of ex-info, otherwise invalid schema errors will be printed in one long and
|
||||
incomprehensible line in unit test failures."
|
||||
([] (thrower (malli.pretty/-printer)))
|
||||
([printer]
|
||||
(let [report (malli.pretty/reporter printer)]
|
||||
(fn [type data]
|
||||
(let [message (with-out-str (report type data))]
|
||||
(throw (js/Error. (str "\n" message))))))))
|
||||
|
||||
(defn reporter
|
||||
([]
|
||||
(reporter nil nil))
|
||||
([schema-id]
|
||||
(reporter schema-id nil))
|
||||
([schema-id opts]
|
||||
(let [printer (malli.pretty/-printer
|
||||
(merge {:width 60
|
||||
:print-length 6
|
||||
:print-level 3
|
||||
:print-meta false}
|
||||
opts))]
|
||||
(if throw-on-error?
|
||||
;; The thrower reporter should be used to short-circuit tests on schema errors.
|
||||
(thrower printer)
|
||||
(ui-reporter schema-id printer)))))
|
||||
|
||||
(defn- with-clear-schema-error
|
||||
"Clears current schema error on app if args passed to `f` are valid."
|
||||
[schema-id validate-input f]
|
||||
(fn [& args]
|
||||
(when (validate-input args)
|
||||
(swap! schema.state/errors disj schema-id))
|
||||
(apply f args)))
|
||||
|
||||
(defn instrument
|
||||
"Similar to `malli/-instrument`, but will automatically clear up visible schema
|
||||
errors if `f` is called with valid arguments.
|
||||
|
||||
We use a validator cached by `malli.core/validator`, so that validation is
|
||||
performed once.
|
||||
|
||||
If `?schema` is invalid, then behave like a nop, log the error and return `f`.
|
||||
|
||||
`schema-id` is optional, but should be passed when instrumenting anonymous
|
||||
functions. Consider using a namespaced keyword. For example:
|
||||
|
||||
(schema/instrument ::foo
|
||||
(fn [x] (inc x))
|
||||
[:=> [:cat :int] :int])
|
||||
"
|
||||
([f ?schema]
|
||||
(if ^boolean js/goog.DEBUG
|
||||
(let [schema-id (when (var? f) (symbol f))]
|
||||
(when-not schema-id
|
||||
(log/warn "Anonymous function instrumented without an explicit identifier."
|
||||
{:schema ?schema}))
|
||||
(instrument schema-id f ?schema))
|
||||
f))
|
||||
([schema-id f ?schema]
|
||||
(if ^boolean js/goog.DEBUG
|
||||
(try
|
||||
(let [?schema (malli/schema ?schema)
|
||||
{schema-input :input} (malli/-function-info ?schema)
|
||||
[validate-input _] (malli/-vmap malli/validator [schema-input])]
|
||||
(malli/-instrument {:schema ?schema
|
||||
:report (reporter schema-id
|
||||
{:title (str "Schema error at " schema-id)})}
|
||||
(with-clear-schema-error schema-id validate-input f)))
|
||||
(catch js/Error e
|
||||
(log/error "Failed to instrument function"
|
||||
{:schema-id schema-id
|
||||
:error e
|
||||
:function f})
|
||||
f))
|
||||
f)))
|
||||
@@ -0,0 +1,26 @@
|
||||
(ns schema.registry
|
||||
(:refer-clojure :exclude [merge])
|
||||
(:require
|
||||
[malli.core :as malli]
|
||||
malli.registry))
|
||||
|
||||
(defonce ^:private registry
|
||||
(atom (malli/default-schemas)))
|
||||
|
||||
(defn init-global-registry
|
||||
[]
|
||||
(malli.registry/set-default-registry! (malli.registry/mutable-registry registry)))
|
||||
|
||||
(defn register
|
||||
"Defines a new schema in mutable `registry`.
|
||||
|
||||
We normalize `?schema` by always registering it as a proper instance of
|
||||
`malli.core/Schema` to avoid inconsistencies down the road."
|
||||
[type ?schema]
|
||||
(swap! registry assoc type (malli/schema ?schema))
|
||||
?schema)
|
||||
|
||||
(defn merge
|
||||
[& schemas]
|
||||
(apply swap! registry cljs.core/merge schemas)
|
||||
schemas)
|
||||
@@ -0,0 +1,11 @@
|
||||
(ns schema.state
|
||||
(:require [reagent.core :as reagent]))
|
||||
|
||||
(def errors
|
||||
"Set of schema identifiers, usually namespaced keywords. When the set is empty,
|
||||
no schema errors will be displayed on the app. See `schema.view/view`."
|
||||
(reagent/atom #{}))
|
||||
|
||||
(defn clear-errors
|
||||
[]
|
||||
(reset! errors #{}))
|
||||
@@ -0,0 +1,28 @@
|
||||
(ns schema.style)
|
||||
|
||||
(defn container
|
||||
[{:keys [bottom-inset]}]
|
||||
{:align-items :center
|
||||
:flex-direction :row
|
||||
:background-color "#cc0000"
|
||||
:border-bottom-left-radius 8
|
||||
:border-top-left-radius 8
|
||||
:justify-content :center
|
||||
:padding-vertical 6
|
||||
:padding-right 16
|
||||
:position :absolute
|
||||
:bottom (+ 12 bottom-inset)
|
||||
:right 0
|
||||
:z-index 10000000})
|
||||
|
||||
(def icon
|
||||
{:margin-horizontal 8})
|
||||
|
||||
(def text
|
||||
{:font-family "Inter-SemiBold"
|
||||
:font-size 13
|
||||
:color "#ddd"})
|
||||
|
||||
(def text-suffix
|
||||
{:font-style :italic
|
||||
:font-size 9})
|
||||
@@ -0,0 +1,18 @@
|
||||
(ns schema.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
schema.state
|
||||
[schema.style :as style]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(when (seq @schema.state/errors)
|
||||
[rn/pressable
|
||||
{:on-press schema.state/clear-errors
|
||||
:style (style/container {:bottom-inset (safe-area/get-bottom)})}
|
||||
[quo/icon :i/close {:size 12 :color "#ddd" :container-style style/icon}]
|
||||
[rn/text {:style style/text}
|
||||
"Schema error(s)"
|
||||
[rn/text {:style (merge style/text style/text-suffix)} " check logs"]]]))
|
||||
@@ -1,20 +0,0 @@
|
||||
(ns status-im.contexts.profile.rpc
|
||||
(:require
|
||||
clojure.set
|
||||
[clojure.string :as string]
|
||||
[utils.ens.core :as utils.ens]))
|
||||
|
||||
(defn rpc->wakuv2-config
|
||||
[wakuv2-config]
|
||||
(clojure.set/rename-keys wakuv2-config {:LightClient :light-client}))
|
||||
|
||||
(defn rpc->profiles-overview
|
||||
[{:keys [customizationColor keycard-pairing] :as profile}]
|
||||
(if (map? profile)
|
||||
(-> profile
|
||||
(update :wakuv2-config rpc->wakuv2-config)
|
||||
(dissoc :customizationColor)
|
||||
(assoc :customization-color (keyword customizationColor))
|
||||
(assoc :ens-name? (utils.ens/is-valid-eth-name? (:name profile)))
|
||||
(assoc :keycard-pairing (when-not (string/blank? keycard-pairing) keycard-pairing)))
|
||||
profile))
|
||||
@@ -1,26 +1,17 @@
|
||||
(ns status-im.fleet.core
|
||||
(:require
|
||||
[native-module.core :as native-module]
|
||||
[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]
|
||||
[utils.transforms :as transforms]))
|
||||
|
||||
(def ^:private default-fleets (transforms/json->clj (native-module/fleets)))
|
||||
(def ^:private default-fleet (:defaultFleet default-fleets))
|
||||
(def fleets
|
||||
(->> default-fleets
|
||||
:fleets
|
||||
keys
|
||||
(map name)))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn current-fleet-sub
|
||||
[multiaccount]
|
||||
(keyword (or (get multiaccount :fleet)
|
||||
default-fleet)))
|
||||
config/fleet)))
|
||||
|
||||
(defn format-mailserver
|
||||
[mailserver address]
|
||||
@@ -87,9 +78,10 @@
|
||||
[{:keys [db now] :as cofx} fleet]
|
||||
(let [old-fleet (get-in db [:profile/profile :fleet])]
|
||||
(when (not= fleet old-fleet)
|
||||
(multiaccounts.update/multiaccount-update
|
||||
(rf/merge
|
||||
cofx
|
||||
:fleet
|
||||
fleet
|
||||
{:on-success
|
||||
#(re-frame/dispatch [:logout])}))))
|
||||
(multiaccounts.update/multiaccount-update :fleet fleet {})
|
||||
(node/prepare-new-config
|
||||
{:on-success
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.update.callback/save-settings-success])})))))
|
||||
|
||||
@@ -523,7 +523,8 @@
|
||||
(error-object->map response)]))}))
|
||||
|
||||
(defn save-multiaccount-and-login
|
||||
[_])
|
||||
[args]
|
||||
(keycard/save-multiaccount-and-login card args))
|
||||
|
||||
(defn login
|
||||
[args]
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
[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]))
|
||||
@@ -151,7 +152,6 @@
|
||||
:keycard/check-nfc-enabled nil}
|
||||
(intro-wizard)))
|
||||
|
||||
;; NOTE: currently non functional, keycard needs to be reimplemented
|
||||
(rf/defn create-keycard-multiaccount
|
||||
{:events [::create-keycard-multiaccount]
|
||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
||||
@@ -182,7 +182,27 @@
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] nil)
|
||||
(dissoc :intro-wizard))})))
|
||||
(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
|
||||
{}))))
|
||||
|
||||
(rf/defn return-to-keycard-login
|
||||
[{:keys [db] :as cofx}]
|
||||
|
||||
@@ -489,7 +489,14 @@
|
||||
(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)))
|
||||
|
||||
(defn login
|
||||
[{:keys [key-uid multiaccount-data password]}]
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(: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]))
|
||||
|
||||
@@ -10,11 +11,13 @@
|
||||
[{: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)
|
||||
(multiaccounts.update/multiaccount-update
|
||||
cofx
|
||||
:log-level
|
||||
log-level
|
||||
{:on-success #(re-frame/dispatch [:logout])}))))
|
||||
(rf/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:log-level
|
||||
log-level
|
||||
{})
|
||||
(node/prepare-new-config
|
||||
{:on-success #(re-frame/dispatch [:logout])})))))
|
||||
|
||||
(rf/defn show-change-log-level-confirmation
|
||||
{:events [:log-level.ui/log-level-selected]}
|
||||
|
||||
@@ -2,10 +2,17 @@
|
||||
(: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.re-frame :as rf]))
|
||||
[utils.ethereum.eip.eip55 :as eip55]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(defn normalize-derived-data-keys
|
||||
[derived-data]
|
||||
@@ -75,3 +82,134 @@
|
||||
(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)))))
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(: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]
|
||||
@@ -116,10 +117,12 @@
|
||||
(rf/defn save-network-settings
|
||||
{:events [::save-network-settings-pressed]}
|
||||
[{:keys [db] :as cofx} network]
|
||||
{: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/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])})))
|
||||
|
||||
(rf/defn remove-network
|
||||
{:events [::remove-network-confirmed]}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
(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]))
|
||||
[status-im2.config :as config]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- add-custom-bootnodes
|
||||
[config network all-bootnodes]
|
||||
@@ -192,4 +195,32 @@
|
||||
: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)))
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
status-im.subs.root
|
||||
status-im2.setup.i18n-resources
|
||||
[status-im2.setup.interceptors :as interceptors]
|
||||
[status-im2.setup.schema :as schema]
|
||||
status-im2.subs.root
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -118,6 +119,7 @@
|
||||
[& args]
|
||||
(reset-test-data!)
|
||||
(interceptors/register-global-interceptors)
|
||||
(schema/setup!)
|
||||
(rf/set-mergeable-keys #{:filters/load-filters
|
||||
:pairing/set-installation-metadata
|
||||
:dispatch-n
|
||||
|
||||
@@ -7,17 +7,12 @@
|
||||
[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
|
||||
test-networks-enabled?
|
||||
light-client-enabled?
|
||||
waku-bloom-filter-mode
|
||||
transactions-management-enabled?
|
||||
wakuv2-flag
|
||||
current-fleet
|
||||
webview-debug]}]
|
||||
(keep
|
||||
@@ -54,12 +49,19 @@
|
||||
:accessory :text
|
||||
:accessory-text current-fleet
|
||||
: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}
|
||||
(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/rpc-usage-info)
|
||||
:accessibility-label :rpc-usage-info
|
||||
@@ -74,15 +76,6 @@
|
||||
: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
|
||||
@@ -103,19 +96,14 @@
|
||||
:accessory :switch
|
||||
:active webview-debug}
|
||||
{:size :small
|
||||
:title "Testnet mode"
|
||||
:accessibility-label :test-networks-enabled
|
||||
: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 [:profile.settings/toggle-test-networks])
|
||||
#(re-frame/dispatch
|
||||
[:multiaccounts.ui/waku-bloom-filter-mode-switched (not waku-bloom-filter-mode)])
|
||||
:accessory :switch
|
||||
:active test-networks-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/set-currency)
|
||||
:accessibility-label :wallet-change-currency
|
||||
:on-press #(hide-sheet-and-dispatch
|
||||
[:navigate-to :currency-settings])
|
||||
:chevron true}]))
|
||||
:active waku-bloom-filter-mode}]))
|
||||
|
||||
(defn- flat-list-data
|
||||
[options]
|
||||
@@ -129,10 +117,10 @@
|
||||
|
||||
(views/defview advanced-settings
|
||||
[]
|
||||
(views/letsubs [test-networks-enabled? [:profile/test-networks-enabled?]
|
||||
light-client-enabled? [:profile/light-client-enabled?]
|
||||
webview-debug [:profile/webview-debug]
|
||||
(views/letsubs [{:keys [webview-debug]} [:profile/profile]
|
||||
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]]
|
||||
@@ -141,10 +129,10 @@
|
||||
{: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
|
||||
:webview-debug webview-debug
|
||||
:test-networks-enabled? test-networks-enabled?})
|
||||
: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,7 @@
|
||||
(ns status-im.ui.screens.fleet-settings.views
|
||||
(:require
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.fleet.core :as fleets]
|
||||
[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]
|
||||
@@ -30,11 +30,16 @@
|
||||
[react/text {:style styles/fleet-item-name-text}
|
||||
fleet]]]]))
|
||||
|
||||
(defn fleets
|
||||
[custom-fleets]
|
||||
(map name (keys (node/fleets {:custom-fleets custom-fleets}))))
|
||||
|
||||
(views/defview fleet-settings
|
||||
[]
|
||||
(views/letsubs [current-fleet [:fleets/current-fleet]]
|
||||
(views/letsubs [custom-fleets [:fleets/custom-fleets]
|
||||
current-fleet [:fleets/current-fleet]]
|
||||
[list/flat-list
|
||||
{:data fleets/fleets
|
||||
{:data (fleets custom-fleets)
|
||||
:default-separator? false
|
||||
:key-fn identity
|
||||
:render-data (name current-fleet)
|
||||
|
||||
@@ -131,6 +131,13 @@
|
||||
:accessibility-label :appearance-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :quo-preview])}])
|
||||
(when config/quo-preview-enabled?
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/appearance
|
||||
:title "Status IM Components"
|
||||
:accessibility-label :status-im-common-components
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:navigate-to :status-im-preview])}])
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/appearance
|
||||
:title (i18n/label :t/appearance)
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
|
||||
(def test-dir (.mkdtempSync fs test-dir-prefix))
|
||||
|
||||
(def initialized? (atom false))
|
||||
|
||||
(defn signal-received-callback
|
||||
[a]
|
||||
(re-frame/dispatch [:signals/signal-received a]))
|
||||
@@ -22,10 +24,12 @@
|
||||
;; We poll for signals, could not get callback working
|
||||
(defn init!
|
||||
[]
|
||||
(.setSignalEventCallback native-status)
|
||||
(js/setInterval (fn []
|
||||
(.pollSignal native-status signal-received-callback)
|
||||
100)))
|
||||
(when-not @initialized?
|
||||
(.setSignalEventCallback native-status)
|
||||
(reset! initialized? true)
|
||||
(js/setInterval (fn []
|
||||
(.pollSignal native-status signal-received-callback)
|
||||
100))))
|
||||
|
||||
(def status
|
||||
(clj->js
|
||||
@@ -117,9 +121,6 @@
|
||||
:isAddress
|
||||
(fn [address] (.isAddress native-status address))
|
||||
|
||||
:fleets
|
||||
(fn [] (.fleets native-status))
|
||||
|
||||
:validateMnemonic
|
||||
(fn [json callback] (callback (.validateMnemonic native-status json)))
|
||||
|
||||
|
||||
@@ -2,11 +2,22 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.multiaccounts.update.core :as multiaccounts.update]
|
||||
[status-im.node.core :as node]
|
||||
[status-im2.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(rf/defn switch-waku-bloom-filter-mode
|
||||
{:events [:multiaccounts.ui/waku-bloom-filter-mode-switched]}
|
||||
[cofx enabled?]
|
||||
(rf/merge cofx
|
||||
(multiaccounts.update/multiaccount-update
|
||||
:waku-bloom-filter-mode
|
||||
enabled?
|
||||
{})
|
||||
(node/prepare-new-config
|
||||
{:on-success #(re-frame/dispatch [:logout])})))
|
||||
|
||||
(def address-regex #"/ip4/\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/tcp/\d{1,5}/p2p/[a-zA-Z0-9]+")
|
||||
|
||||
@@ -97,16 +108,13 @@
|
||||
vals
|
||||
(map #(vector (:name %1) (:address %1)))
|
||||
(into {}))]
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/profile :wakuv2-config :CustomNodes] new-nodes)
|
||||
(dissoc :wakuv2-nodes/manage :wakuv2-nodes/list))
|
||||
:json-rpc/call [{:method "wakuext_setCustomNodes"
|
||||
:params [{:customNodes new-nodes}]
|
||||
:on-success #(log/info "updated custom nodes")
|
||||
:on-error #(log/error "failed to set custom nodes"
|
||||
{:error %
|
||||
:custom-nodes new-nodes})}]
|
||||
:dispatch [:navigate-back]}))
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:profile/profile :wakuv2-config :CustomNodes] new-nodes)
|
||||
(dissoc :wakuv2-nodes/manage :wakuv2-nodes/list))
|
||||
:dispatch [:navigate-back]}
|
||||
(node/prepare-new-config
|
||||
{:on-success #(re-frame/dispatch [:logout])}))))
|
||||
|
||||
(rf/defn show-delete-node-confirmation
|
||||
{:events [:wakuv2.ui/delete-pressed]}
|
||||
@@ -123,17 +131,3 @@
|
||||
(rf/merge cofx
|
||||
(delete id)
|
||||
(navigation/navigate-back)))
|
||||
|
||||
(rf/defn toggle-light-client
|
||||
{:events [:wakuv2.ui/toggle-light-client]}
|
||||
[{:keys [db]} enabled?]
|
||||
{:db (assoc-in db [:profile/profile :wakuv2-config :LightClient] enabled?)
|
||||
|
||||
:json-rpc/call [{:method "wakuext_setLightClient"
|
||||
:params [{:enabled enabled?}]
|
||||
:on-success (fn []
|
||||
(log/info "light client set successfully" enabled?)
|
||||
(re-frame/dispatch [:logout]))
|
||||
:on-error #(log/error "failed to set light client"
|
||||
{:error %
|
||||
:enabled? enabled?})}]})
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
(ns status-im2.common.floating-button-page.component-spec
|
||||
(:require [quo.core :as quo]
|
||||
[status-im2.common.floating-button-page.view :as floating-button-page]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(h/describe "floating button page"
|
||||
(h/test "renders with a header and standard button"
|
||||
(h/render [floating-button-page/view
|
||||
{:header [quo/page-nav
|
||||
{:type :title-description
|
||||
:title "floating button page"
|
||||
:description "press right icon to swap button type"
|
||||
:text-align :left
|
||||
:background :blur
|
||||
:icon-name :i/close}]
|
||||
:footer [quo/button {} "continue"]}])
|
||||
(h/is-truthy (h/get-by-text "continue"))
|
||||
(h/is-truthy (h/get-by-text "floating button page")))
|
||||
|
||||
(h/test "renders with a header and a slide button"
|
||||
(h/render [floating-button-page/view
|
||||
{:header [quo/page-nav
|
||||
{:type :title-description
|
||||
:title "floating button page"
|
||||
:description "press right icon to swap button type"
|
||||
:text-align :left
|
||||
:background :blur
|
||||
:icon-name :i/close}]
|
||||
:footer [quo/slide-button
|
||||
{:track-text "We gotta slide"
|
||||
:track-icon :face-id}]}])
|
||||
(h/is-truthy (h/get-by-text "We gotta slide"))))
|
||||
@@ -0,0 +1,17 @@
|
||||
(ns status-im2.common.floating-button-page.floating-container.style
|
||||
(:require [react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn content-container
|
||||
[blur? keyboard-shown?]
|
||||
(let [margin-bottom (if keyboard-shown? 0 (safe-area/get-bottom))]
|
||||
(cond-> {:margin-top :auto
|
||||
:overflow :hidden
|
||||
:margin-bottom margin-bottom
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20}
|
||||
blur? (dissoc :padding-vertical :padding-horizontal))))
|
||||
|
||||
(def blur-inner-container
|
||||
{:background-color :transparent ; required, otherwise blur-view will shrink
|
||||
:padding-vertical 12
|
||||
:padding-horizontal 20})
|
||||
@@ -0,0 +1,25 @@
|
||||
(ns status-im2.common.floating-button-page.floating-container.view
|
||||
(:require [quo.theme :as quo.theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[status-im2.common.floating-button-page.floating-container.style :as style]))
|
||||
|
||||
(defn- blur-container
|
||||
[child theme]
|
||||
[blur/view
|
||||
{:blur-amount 12
|
||||
:blur-radius 12
|
||||
:blur-type (quo.theme/theme-value :light :dark theme)}
|
||||
[rn/view {:style style/blur-inner-container}
|
||||
child]])
|
||||
|
||||
(defn view-internal
|
||||
[{:keys [theme on-layout keyboard-shown? blur?]} child]
|
||||
[rn/view
|
||||
{:style (style/content-container blur? keyboard-shown?)
|
||||
:on-layout on-layout}
|
||||
(if blur?
|
||||
[blur-container child theme]
|
||||
child)])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
@@ -0,0 +1,15 @@
|
||||
(ns status-im2.common.floating-button-page.style)
|
||||
|
||||
(def page-container
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
|
||||
(def keyboard-avoiding-view
|
||||
{:position :absolute
|
||||
:top 0
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0})
|
||||
@@ -0,0 +1,102 @@
|
||||
(ns status-im2.common.floating-button-page.view
|
||||
(:require
|
||||
[oops.core :as oops]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.floating-button-page.floating-container.view :as floating-container]
|
||||
[status-im2.common.floating-button-page.style :as style]))
|
||||
|
||||
(defn- show-background
|
||||
[{:keys [window-height keyboard-height footer-container-height content-scroll-y
|
||||
content-container-height header-height keyboard-shown?]}]
|
||||
(let [available-space (- window-height
|
||||
(safe-area/get-top)
|
||||
header-height
|
||||
keyboard-height ; Already contains the bottom safe area value
|
||||
footer-container-height)
|
||||
scroll-view-height (- content-container-height content-scroll-y)
|
||||
overlap? (< available-space scroll-view-height)]
|
||||
(and keyboard-shown? overlap?)))
|
||||
|
||||
(defn- set-height-on-layout
|
||||
[ratom]
|
||||
(fn [event]
|
||||
(let [height (oops/oget event "nativeEvent.layout.height")]
|
||||
(reset! ratom height))))
|
||||
|
||||
(defn- init-keyboard-listeners
|
||||
[{:keys [on-did-show]}]
|
||||
(let [keyboard-will-show? (reagent/atom false)
|
||||
keyboard-did-show? (reagent/atom false)
|
||||
add-listener (fn [listener callback]
|
||||
(oops/ocall rn/keyboard "addListener" listener callback))
|
||||
will-show-listener (add-listener "keyboardWillShow"
|
||||
#(reset! keyboard-will-show? true))
|
||||
did-show-listener (add-listener "keyboardDidShow"
|
||||
(fn [e]
|
||||
(reset! keyboard-did-show? true)
|
||||
(when on-did-show (on-did-show e))))
|
||||
will-hide-listener (add-listener "keyboardWillHide"
|
||||
#(reset! keyboard-will-show? false))
|
||||
did-hide-listener (add-listener "keyboardDidHide"
|
||||
#(reset! keyboard-did-show? false))
|
||||
remove-listeners (fn []
|
||||
(doseq [listener [will-show-listener will-hide-listener
|
||||
did-show-listener did-hide-listener]]
|
||||
(oops/ocall listener "remove")))]
|
||||
{:keyboard-will-show? keyboard-will-show?
|
||||
:keyboard-did-show? keyboard-did-show?
|
||||
:remove-listeners remove-listeners}))
|
||||
|
||||
(defn view
|
||||
[{:keys [header footer]} & children]
|
||||
(reagent/with-let [window-height (:height (rn/get-window))
|
||||
footer-container-height (reagent/atom 0)
|
||||
header-height (reagent/atom 0)
|
||||
content-container-height (reagent/atom 0)
|
||||
content-scroll-y (reagent/atom 0)
|
||||
keyboard-height (reagent/atom 0)
|
||||
{:keys [keyboard-will-show?
|
||||
keyboard-did-show?
|
||||
remove-listeners]} (init-keyboard-listeners
|
||||
{:on-did-show
|
||||
(fn [e]
|
||||
(reset! keyboard-height
|
||||
(oops/oget e "endCoordinates.height")))})
|
||||
set-header-height (set-height-on-layout header-height)
|
||||
set-content-container-height (set-height-on-layout content-container-height)
|
||||
set-footer-container-height (set-height-on-layout footer-container-height)
|
||||
set-content-y-scroll (fn [event]
|
||||
(reset! content-scroll-y
|
||||
(oops/oget event "nativeEvent.contentOffset.y")))]
|
||||
(let [keyboard-shown? (if platform/ios? @keyboard-will-show? @keyboard-did-show?)
|
||||
show-background? (show-background {:window-height window-height
|
||||
:footer-container-height @footer-container-height
|
||||
:keyboard-height @keyboard-height
|
||||
:content-scroll-y @content-scroll-y
|
||||
:content-container-height @content-container-height
|
||||
:header-height @header-height
|
||||
:keyboard-shown? keyboard-shown?})]
|
||||
|
||||
[rn/view {:style style/page-container}
|
||||
[rn/view {:on-layout set-header-height}
|
||||
header]
|
||||
[rn/scroll-view
|
||||
{:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1}}
|
||||
(into [rn/view {:on-layout set-content-container-height}]
|
||||
children)]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/keyboard-avoiding-view
|
||||
:keyboard-vertical-offset (if platform/ios? (safe-area/get-top) 0)
|
||||
:pointer-events :box-none}
|
||||
[floating-container/view
|
||||
{:on-layout set-footer-container-height
|
||||
:keyboard-shown? keyboard-shown?
|
||||
:blur? show-background?}
|
||||
footer]]])
|
||||
(finally
|
||||
(remove-listeners))))
|
||||
@@ -6,10 +6,8 @@
|
||||
[status-im2.common.confirmation-drawer.view :as confirmation-drawer]
|
||||
[status-im2.common.mute-drawer.view :as mute-drawer]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.constants :as constants]
|
||||
[status-im2.contexts.chat.actions.view :as chat-actions]
|
||||
[status-im2.contexts.communities.actions.chat.view :as communities-chat-actions]
|
||||
[status-im2.contexts.communities.actions.chat.view :as chat-actions]
|
||||
[status-im2.contexts.contacts.drawers.nickname-drawer.view :as nickname-drawer]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -255,6 +253,16 @@
|
||||
:chevron? true
|
||||
:add-divider? add-divider?}))
|
||||
|
||||
;; TODO(OmarBasem): Requires design input.
|
||||
(defn fetch-messages-entry
|
||||
[]
|
||||
(entry {:icon :i/save
|
||||
:label (i18n/label :t/fetch-messages)
|
||||
:on-press #(js/alert "TODO: to be implemented, requires design input")
|
||||
:danger? false
|
||||
:accessibility-label :fetch-messages
|
||||
:sub-label nil
|
||||
:chevron? true}))
|
||||
|
||||
(defn remove-from-contacts-entry
|
||||
[contact]
|
||||
@@ -411,9 +419,9 @@
|
||||
[(mark-as-read-entry chat-id needs-divider?)
|
||||
(mute-chat-entry chat-id chat-type muted-till)
|
||||
(notifications-entry false)
|
||||
(when (and config/fetch-messages-enabled? inside-chat?)
|
||||
(chat-actions/fetch-messages chat-id))
|
||||
(when public?
|
||||
(when inside-chat?
|
||||
(fetch-messages-entry))
|
||||
(when (or (not group-chat) public?)
|
||||
(show-qr-entry))
|
||||
(when-not group-chat
|
||||
(share-profile-entry))
|
||||
@@ -473,7 +481,7 @@
|
||||
constants/private-group-chat-type
|
||||
[private-group-chat-actions chat inside-chat?]
|
||||
constants/community-chat-type
|
||||
[communities-chat-actions/actions chat inside-chat?]
|
||||
[chat-actions/actions chat inside-chat?]
|
||||
nil))
|
||||
|
||||
(defn group-details-actions
|
||||
|
||||
@@ -31,10 +31,10 @@
|
||||
:on-change-text #(reset! entered-password %)}]
|
||||
(when (not-empty error)
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:style {:margin-top 8}}
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info
|
||||
:containstyle {:margin-top 8}}
|
||||
(i18n/label :t/oops-wrong-password)])
|
||||
[quo/button
|
||||
{:container-style {:margin-bottom 12 :margin-top 40}
|
||||
|
||||
@@ -79,7 +79,19 @@
|
||||
:dark (js/require "../resources/images/ui2/no-contacts-to-invite-dark.png")}
|
||||
:no-notifications
|
||||
{:light (js/require "../resources/images/ui2/no-notifications-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-notifications-dark.png")}})
|
||||
:dark (js/require "../resources/images/ui2/no-notifications-dark.png")}
|
||||
:no-activity
|
||||
{:light (js/require "../resources/images/ui2/no-activity-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-activity-dark.png")}
|
||||
:no-collectibles
|
||||
{:light (js/require "../resources/images/ui2/no-collectibles-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-collectibles-dark.png")}
|
||||
:no-dapps
|
||||
{:light (js/require "../resources/images/ui2/no-dapps-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-dapps-dark.png")}
|
||||
:no-permissions
|
||||
{:light (js/require "../resources/images/ui2/no-permissions-light.png")
|
||||
:dark (js/require "../resources/images/ui2/no-permissions-dark.png")}})
|
||||
|
||||
(def mock-images
|
||||
{:bored-ape (js/require "../resources/images/mock2/bored-ape.png")
|
||||
|
||||
@@ -170,5 +170,3 @@
|
||||
(def default-kdf-iterations 3200)
|
||||
|
||||
(def shell-navigation-disabled? false)
|
||||
(def community-accounts-selection-enabled? false)
|
||||
(def fetch-messages-enabled? (enabled? (get-config :FETCH_MESSAGES_ENABLED "1")))
|
||||
|
||||
@@ -4,16 +4,6 @@
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn fetch-messages
|
||||
[chat-id]
|
||||
{:icon :i/download
|
||||
:right-icon :i/chevron-right
|
||||
:accessibility-label :chat-fetch-messages
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(rf/dispatch [:chat/fetch-messages chat-id]))
|
||||
:label (i18n/label :t/fetch-messages)})
|
||||
|
||||
(defn new-chat
|
||||
[]
|
||||
[quo/action-drawer
|
||||
|
||||
@@ -449,20 +449,3 @@
|
||||
{:events [:chat/check-last-chat]}
|
||||
[{:keys [db]}]
|
||||
{:chat/open-last-chat (get-in db [:profile/profile :key-uid])})
|
||||
|
||||
(rf/defn status-tag-pressed
|
||||
{:events [:communities/status-tag-pressed]}
|
||||
[{:keys [db] :as cofx} community-id literal]
|
||||
(let [{:keys [id]} (some #(when (= (:name %) literal) %)
|
||||
(vals (get-in db [:communities community-id :chats])))]
|
||||
(when (and id
|
||||
(not= (:current-chat-id db) (str community-id id)))
|
||||
(navigate-to-chat cofx (str community-id id) nil))))
|
||||
|
||||
(rf/defn fetch-messages
|
||||
{:events [:chat/fetch-messages]}
|
||||
[_ chat-id]
|
||||
{:json-rpc/call [{:method "wakuext_fetchMessages"
|
||||
:params [{:id chat-id}]
|
||||
:on-success #()
|
||||
:on-error #(log/error "failed to fetch messages for chat" chat-id %)}]})
|
||||
|
||||
@@ -8,10 +8,6 @@
|
||||
[utils.re-frame :as rf]
|
||||
[utils.url :as url]))
|
||||
|
||||
;; these constants are used when there is no width or height defined for a specific image
|
||||
(def ^:const fallback-image-width 1000)
|
||||
(def ^:const fallback-image-height 1000)
|
||||
|
||||
(defn calculate-dimensions
|
||||
[width height max-container-width max-container-height]
|
||||
(let [max-width (if (> width height) max-container-width (* 1.5 constants/image-size))
|
||||
@@ -19,12 +15,7 @@
|
||||
{:width (min width max-width) :height (min height max-height)}))
|
||||
|
||||
(defn image-message
|
||||
[index
|
||||
{:keys [content image-width image-height message-id]
|
||||
:as message
|
||||
:or {image-width fallback-image-width
|
||||
image-height fallback-image-height}}
|
||||
{:keys [on-long-press]}
|
||||
[index {:keys [content image-width image-height message-id] :as message} {:keys [on-long-press]}
|
||||
message-container-data]
|
||||
(let [insets (safe-area/get-insets)
|
||||
{:keys [window-width padding-left padding-right avatar-container-width
|
||||
|
||||
@@ -4,8 +4,6 @@
|
||||
[status-im2.common.mute-drawer.view :as mute-drawer]
|
||||
[status-im2.common.muting.helpers :refer [format-mute-till]]
|
||||
[status-im2.common.not-implemented :as not-implemented]
|
||||
[status-im2.config :as config]
|
||||
[status-im2.contexts.chat.actions.view :as chat-actions]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -85,6 +83,13 @@
|
||||
:on-press not-implemented/alert
|
||||
:label (i18n/label :t/pinned-messages)})
|
||||
|
||||
(defn- action-fetch-messages
|
||||
[]
|
||||
{:icon :i/download
|
||||
:right-icon :i/chevron-right
|
||||
:accessibility-label :chat-fetch-messages
|
||||
:on-press not-implemented/alert
|
||||
:label (i18n/label :t/fetch-messages)})
|
||||
|
||||
(defn- action-invite-people
|
||||
[]
|
||||
@@ -136,8 +141,7 @@
|
||||
(action-mark-as-read)
|
||||
(action-toggle-muted chat-id muted muted-till chat-type)
|
||||
(action-notification-settings)
|
||||
(when config/fetch-messages-enabled?
|
||||
(chat-actions/fetch-messages chat-id))
|
||||
(action-fetch-messages)
|
||||
(action-invite-people)
|
||||
(action-qr-code)
|
||||
(action-share)]]]
|
||||
|
||||
@@ -73,12 +73,12 @@
|
||||
(data-store.settings/rpc->settings settings)
|
||||
profile-overview (profile.rpc/rpc->profiles-overview account)]
|
||||
(rf/merge cofx
|
||||
{:db (assoc db
|
||||
:chats/loading? true
|
||||
:networks/current-network current-network
|
||||
:wallet/tokens-loading? true
|
||||
:networks/networks (merge networks config/default-networks-by-id)
|
||||
:profile/profile (merge profile-overview settings))}
|
||||
{:db (-> db
|
||||
(assoc :chats/loading? true
|
||||
:networks/current-network current-network
|
||||
:networks/networks (merge networks config/default-networks-by-id)
|
||||
:profile/profile (merge profile-overview settings))
|
||||
(assoc-in [:wallet :ui :tokens-loading?] true))}
|
||||
(notifications/load-preferences)
|
||||
(data-store.chats/fetch-chats-preview
|
||||
{:on-success
|
||||
|
||||
@@ -6,14 +6,14 @@
|
||||
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [theme]}]
|
||||
[{:keys [theme title]}]
|
||||
(let [logged-in? (rf/sub [:multiaccount/logged-in?])
|
||||
has-profiles? (boolean (rf/sub [:profile/profiles-overview]))
|
||||
root (if has-profiles? :profiles :intro)
|
||||
light? (= theme :light)]
|
||||
[quo/page-nav
|
||||
{:type :title
|
||||
:title "quo components preview"
|
||||
:title title
|
||||
:text-align :left
|
||||
:icon-name :i/close
|
||||
:right-side [{:icon-name (if light? :i/dark :i/light)
|
||||
|
||||
@@ -26,4 +26,4 @@
|
||||
:descriptor descriptor
|
||||
:blur? (:in-blur-view? @state)
|
||||
:show-blur-background? (:in-blur-view? @state)}
|
||||
[quo/step @state (:value @state)]])))
|
||||
[quo/step (dissoc @state :value) (:value @state)]])))
|
||||
|
||||
@@ -153,6 +153,7 @@
|
||||
[status-im2.contexts.quo-preview.tags.number-tag :as number-tag]
|
||||
[status-im2.contexts.quo-preview.tags.permission-tag :as permission-tag]
|
||||
[status-im2.contexts.quo-preview.tags.status-tags :as status-tags]
|
||||
[status-im2.contexts.quo-preview.tags.summary-tag :as summary-tag]
|
||||
[status-im2.contexts.quo-preview.tags.tag :as tag]
|
||||
[status-im2.contexts.quo-preview.tags.tags :as tags]
|
||||
[status-im2.contexts.quo-preview.tags.tiny-tag :as tiny-tag]
|
||||
@@ -433,6 +434,8 @@
|
||||
:component permission-tag/view}
|
||||
{:name :status-tags
|
||||
:component status-tags/view}
|
||||
{:name :summary-tag
|
||||
:component summary-tag/view}
|
||||
{:name :tag
|
||||
:component tag/view}
|
||||
{:name :tags
|
||||
@@ -484,7 +487,7 @@
|
||||
(defn- main-screen
|
||||
[]
|
||||
[:<>
|
||||
[common/navigation-bar]
|
||||
[common/navigation-bar {:title "Quo components preview"}]
|
||||
[rn/scroll-view {:style (style/main)}
|
||||
(for [category (sort screens-categories)]
|
||||
^{:key (first category)}
|
||||
|
||||
@@ -317,10 +317,10 @@
|
||||
children)])
|
||||
|
||||
(defn- f-preview-container
|
||||
[{:keys [state descriptor blur? blur-dark-only?
|
||||
[{:keys [title state descriptor blur? blur-dark-only?
|
||||
component-container-style
|
||||
blur-container-style blur-view-props blur-height show-blur-background?]
|
||||
:or {blur-height 200}}
|
||||
:or {blur-height 200 title "quo component"}}
|
||||
& children]
|
||||
(let [theme (quo.theme/use-theme-value)]
|
||||
(rn/use-effect (fn []
|
||||
@@ -332,7 +332,7 @@
|
||||
[rn/view
|
||||
{:style {:top (safe-area/get-top)
|
||||
:flex 1}}
|
||||
[common/navigation-bar]
|
||||
[common/navigation-bar {:title title}]
|
||||
[rn/scroll-view
|
||||
{:style (style/panel-basic)
|
||||
:shows-vertical-scroll-indicator false}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns status-im2.contexts.quo-preview.settings.data-item
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.resources :as quo.resources]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
@@ -50,6 +51,7 @@
|
||||
:right-icon :i/chevron-right
|
||||
:emoji "🎮"
|
||||
:customization-color :yellow
|
||||
:network-image (quo.resources/get-network :ethereum)
|
||||
:communities-list communities-list})]
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
(ns status-im2.contexts.quo-preview.tags.summary-tag
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.resources :as quo.resources]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.quo-preview.preview :as preview]))
|
||||
|
||||
(defn data
|
||||
[type]
|
||||
(case type
|
||||
:token
|
||||
{:customization-color "#9999991A"
|
||||
:label "150 ETH"
|
||||
:image-source (quo.resources/get-token :eth)}
|
||||
:address
|
||||
{:label "0x39c...Bd2"}
|
||||
:user
|
||||
{:image-source (resources/mock-images :user-picture-male4)
|
||||
:customization-color :blue
|
||||
:label "Mark Libot"}
|
||||
:collectible
|
||||
{:label "Isekai #1"
|
||||
:image-source (resources/mock-images :collectible2)
|
||||
:customization-color :yellow}
|
||||
:network
|
||||
{:image-source (quo.resources/get-network :ethereum)
|
||||
:label "Mainnet"}
|
||||
:saved-address
|
||||
{:customization-color :flamingo
|
||||
:label "Peter Lambo"}
|
||||
:account
|
||||
{:label "Account"
|
||||
:emoji "🍿"
|
||||
:customization-color :purple}))
|
||||
|
||||
(def descriptor
|
||||
[{:key :type
|
||||
:type :select
|
||||
:options [{:value "Token"
|
||||
:key :token}
|
||||
{:value "Address"
|
||||
:key :address}
|
||||
{:value "User"
|
||||
:key :user}
|
||||
{:value "Collectible"
|
||||
:key :collectible}
|
||||
{:value "Network"
|
||||
:key :network}
|
||||
{:value "Saved address"
|
||||
:key :saved-address}
|
||||
{:value "Account"
|
||||
:key :account}]}])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [state (reagent/atom
|
||||
(merge {:type :token}
|
||||
(data :token)))]
|
||||
(fn []
|
||||
[preview/preview-container
|
||||
{:state state
|
||||
:descriptor descriptor}
|
||||
[rn/view {:style {:align-items :center}}
|
||||
[quo/summary-tag (merge @state (data (:type @state)))]]])))
|
||||
@@ -0,0 +1,22 @@
|
||||
(ns status-im2.contexts.status-im-preview.common.floating-button-page.style
|
||||
(:require [quo.foundations.colors :as colors]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
|
||||
(defn container
|
||||
[]
|
||||
{:flex 1
|
||||
:margin-top (safe-area/get-top)})
|
||||
|
||||
(def background-image
|
||||
{:position :absolute
|
||||
:top (- (safe-area/get-top))
|
||||
:left 0
|
||||
:right 0
|
||||
:bottom 200})
|
||||
|
||||
(defn page-content
|
||||
[height]
|
||||
{:flex 1
|
||||
:height height
|
||||
:overflow :hidden
|
||||
:background-color (colors/resolve-color :army 30)})
|
||||
@@ -0,0 +1,55 @@
|
||||
(ns status-im2.contexts.status-im-preview.common.floating-button-page.view
|
||||
(:require [quo.core :as quo]
|
||||
[re-frame.core :as rf]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im2.common.resources :as resources]
|
||||
[status-im2.contexts.status-im-preview.common.floating-button-page.style :as style]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [content-height (reagent/atom 450)
|
||||
slide? (reagent/atom false)]
|
||||
(fn []
|
||||
[rn/view {:style (style/container)}
|
||||
(when-not @slide?
|
||||
[rn/image
|
||||
{:style style/background-image
|
||||
:source (resources/get-mock-image :dark-blur-bg)}])
|
||||
[floating-button-page/view
|
||||
{:header [quo/page-nav
|
||||
{:type :title-description
|
||||
:title "floating button page"
|
||||
:description "press right icon to swap button type"
|
||||
:text-align :left
|
||||
:right-side [{:icon-name :i/swap
|
||||
:on-press #(swap! slide? not)}]
|
||||
:background :blur
|
||||
:icon-name :i/close
|
||||
:on-press #(rf/dispatch [:navigate-back])}]
|
||||
:footer (if @slide?
|
||||
[quo/slide-button
|
||||
{:track-text "We gotta slide"
|
||||
:track-icon :face-id
|
||||
:container-style {:z-index 2}
|
||||
:customization-color :blue
|
||||
:on-complete #(js/alert "button slid")}
|
||||
"Save address"]
|
||||
[quo/button
|
||||
{:container-style {:z-index 2}
|
||||
:on-press #(js/alert "button pressed")}
|
||||
"Save address"])}
|
||||
[rn/view {:style (style/page-content @content-height)}
|
||||
[quo/text {:size :heading-1} "Page Content"]
|
||||
[quo/input
|
||||
{:auto-focus true
|
||||
:value ""}]
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:on-press #(swap! content-height (fn [v] (+ v 10)))}
|
||||
"increase height"]
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:on-press #(swap! content-height (fn [v] (- v 10)))}
|
||||
"decrease height"]]]])))
|
||||
@@ -0,0 +1,59 @@
|
||||
(ns status-im2.contexts.status-im-preview.main
|
||||
(:refer-clojure :exclude [filter])
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im2.contexts.quo-preview.common :as common]
|
||||
[status-im2.contexts.status-im-preview.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im2.contexts.status-im-preview.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def screens-categories
|
||||
{:common [{:name :floating-button-page
|
||||
:component floating-button-page/view}]})
|
||||
|
||||
(defn- category-view
|
||||
[]
|
||||
(let [open? (reagent/atom false)
|
||||
on-press #(swap! open? not)]
|
||||
(fn [category]
|
||||
[rn/view {:style {:margin-vertical 8}}
|
||||
[quo/dropdown
|
||||
{:type :grey
|
||||
:state (if @open? :active :default)
|
||||
:on-press on-press}
|
||||
(name (key category))]
|
||||
(when @open?
|
||||
(for [{category-name :name} (val category)]
|
||||
^{:key category-name}
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:container-style {:margin-vertical 8}
|
||||
:on-press #(rf/dispatch [:navigate-to category-name])}
|
||||
(name category-name)]))])))
|
||||
|
||||
(defn- main-screen
|
||||
[]
|
||||
[:<>
|
||||
[common/navigation-bar {:title "Status IM components"}]
|
||||
[rn/scroll-view {:style (style/main)}
|
||||
(for [category (sort screens-categories)]
|
||||
^{:key (first category)}
|
||||
[category-view category])]])
|
||||
|
||||
(def screens
|
||||
(->> screens-categories
|
||||
(map val)
|
||||
flatten
|
||||
(map (fn [subcategory]
|
||||
(update-in subcategory
|
||||
[:options :topBar]
|
||||
merge
|
||||
{:visible false})))))
|
||||
|
||||
(def main-screens
|
||||
[{:name :status-im-preview
|
||||
:options {:topBar {:visible false}
|
||||
:insets {:top? true}}
|
||||
:component main-screen}])
|
||||
@@ -0,0 +1,10 @@
|
||||
(ns status-im2.contexts.status-im-preview.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn main
|
||||
[]
|
||||
{:flex 1
|
||||
:padding-bottom 8
|
||||
:padding-horizontal 16
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-90)})
|
||||