Compare commits

..
Author SHA1 Message Date
Andrea Maria Piana 88c56a4f2f status-go-issue 2023-11-16 12:58:22 +00:00
Icaro Motta 91300b9ff8 Fix: unable to join token-gated communities (#17894)
Fixes the bug by explicitly passing all available addresses to be revealed
to wakuext_requestToJoinCommunity and picking up the first available address
as the airdrop address. This is a temporary solution while we work on the
feature to allow users to choose which addresses to expose.

Fixes https://github.com/status-im/status-mobile/issues/17861

*Areas that may be impacted*: join community flows.

    ----------------------------------------------------------------------
    Community "Request to join" option is enabled.
    User holds more than X ETH.
    Anyone who holds <X> ETH is allowed to Become member in <COMMUNITY>.
    
    Expected: request to join is received by desktop client and accepted,
    mobile user joins the community.
    ----------------------------------------------------------------------
    
    ----------------------------------------------------------------------
    Community "Request to join" option is enabled.
    User holds less than X ETH.
    Anyone who holds <X> ETH is allowed to View and post in <CHANNEL>.
    
    Expected: request to join is received by desktop client and accepted, mobile
    user joins the community, but can't post in <CHANNEL>.
    ----------------------------------------------------------------------
    
    ----------------------------------------------------------------------
    Community "Request to join" option is enabled.
    No token permissions.
    
    Expected: request to join is received by desktop client and accepted,
    mobile user joins the community.
    ----------------------------------------------------------------------
2023-11-15 06:46:55 -03:00
Andrea Maria Piana d93b20242a Point to shared release branch 2023-11-14 10:54:02 +00:00
Andrea Maria Piana 0a43e5c97a Bump release to 1.26.0 2023-11-14 10:52:00 +00:00
401 changed files with 4147 additions and 8760 deletions
+1
View File
@@ -95,6 +95,7 @@ react-native.fs/unlink
react-native.fs/file-exists?
status-im.ui.components.colors/white
status-im.ui.components.colors/black
status-im.transport.core-test/messages
status-im.ui.components.core/animated-header
status-im.ui.components.core/safe-area-provider
status-im.ui.components.core/safe-area-consumer
+4 -12
View File
@@ -16,18 +16,10 @@
:clj-kondo-config {:level :error}
:cond-else {:level :error}
:consistent-alias {:level :error
: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}}
:aliases {clojure.string string
clojure.set set
clojure.walk walk
taoensso.timbre log}}
:deprecated-namespace {:level :warning}
:docstring-blank {:level :error}
:equals-true {:level :error}
-2
View File
@@ -1,2 +0,0 @@
{:lint-as {malli.experimental/defn schema.core/defn}
:linters {:unresolved-symbol {:exclude [(malli.core/=>)]}}}
@@ -1,4 +0,0 @@
{:linters
{:unresolved-symbol
{:exclude [(cljs.test/is [match? thrown-match?])
(clojure.test/is [match? thrown-match?])]}}}
-2
View File
@@ -32,12 +32,10 @@
"letsubs" :binding
"with-let" "let"
"reg-event-fx" :arg1-pair
"reg-fx" :arg1-pair
"testing" :arg1-body
"deftest-sub" :arg1-body
"wait-for" :arg1-body
"with-deps-check" :arg1-body
"schema/=>" :arg1-body
"->" [:noarg1-body
{:list {:constant-pair? false :force-nl? false}
:next-inner-restore [[:list :constant-pair?]]}]
+5 -6
View File
@@ -311,14 +311,13 @@ 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/require-i18n-resource-first.sh && \
@sh scripts/lint-re-frame-in-quo-components.sh && \
sh scripts/lint-direct-require-component-outside-quo.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
@@ -328,7 +327,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
+1 -1
View File
@@ -1 +1 @@
1.25.0
1.26.0
@@ -27,23 +27,18 @@ class StatusOkHttpClientFactory implements OkHttpClientFactory {
X509Certificate cert = null;
HandshakeCertificates clientCertificates;
String certPem = "";
// Get TLS PEM certificate from status-go
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
certPem = getCertificatePem();
} catch(Exception e) {
Log.e(TAG, "Could not getImageTLSCert",e);
}
if (certPem.isEmpty()) {
Log.e(TAG, "Certificate is empty, cannot create OkHttpClient without a valid certificate");
return null;
}
// Convert PEM certificate string to X509Certificate object
// Get TLS PEM certificate from status-go
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices with
// java.lang.RuntimeException: Could not invoke WebSocketModule.connect
Thread.sleep(500);
certPem = StatusPackage.getImageTLSCert();
} catch(Exception e) {
Log.e(TAG, "Could not getImageTLSCert",e);
}
// Convert PEM certificate string to X509Certificate object
try {
// induce half second sleep because sometimes a cert is not immediately available
// TODO : remove sleep if App no longer crashes on Android 10 devices
@@ -79,17 +74,4 @@ class StatusOkHttpClientFactory implements OkHttpClientFactory {
return null;
}
}
private String getCertificatePem() {
try {
String certPem = StatusPackage.getImageTLSCert();
if (certPem == null || certPem.trim().isEmpty()) {
Log.e(TAG, "Certificate PEM string is null or empty");
return "";
}
return certPem;
} catch (Exception e) {
Log.e(TAG, "Could not getImageTLSCert", e);
return "";
}
}
}
+1
View File
@@ -77,6 +77,7 @@ pipeline {
}
}
stage('Upload') {
when { expression { !utils.isReleaseBuild() } }
steps { script {
env.DIAWI_URL = ios.uploadToDiawi()
env.PKG_URL = env.DIAWI_URL
+1 -21
View File
@@ -641,26 +641,6 @@ keywords and concatenating them into a single string.
```
### Tests
#### Prefer `match?` over `=` when comparing data structures
Prefer the `match?` directive over `=` when comparing data structures, otherwise
when the check fails the output can be too difficult to read. `match?` is
defined by library https://github.com/nubank/matcher-combinators.
```clojure
;; bad
(deftest some-test
(let [expected {...}
actual {...}]
(is (= expected actual))))
;; good
(deftest some-test
(let [expected {...}
actual {...}]
(is (match? expected actual))))
```
#### Subscription tests
Test [layer-3 subscriptions](https://day8.github.io/re-frame/subscriptions/) by
@@ -736,7 +716,7 @@ src
- `src/js`: Raw Javascript files, e.g. React Native Reanimated worklets.
- `src/mocks`: Plumbing configuration to be able to run tests.
- `src/quo/`: The component library for Status Mobile. [Read more...](../src/quo/README.md)
- `src/quo/`: The component library for Status Mobile.
- `src/react_native/`: Contains only low-level constructs to help React Native
work in tandem with Clojure(Script).
- `src/status_im2/`: Directory where we try to be as strict as possible about
+12 -66
View File
@@ -45,20 +45,11 @@
},
{
"path": "borkdude/dynaload/0.3.5/dynaload-0.3.5",
"path": "borkdude/edamame/1.1.17/edamame-1.1.17",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "accd696ba364b850b4d92e38f5a34d0e828a0ad1",
"sha256": "0k62m1f29xfh3cp67w7kcvkp5aj35simi8kf95ycvkmgp76w11q8"
}
},
{
"path": "borkdude/edamame/1.3.23/edamame-1.3.23",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "254d023e97ed438f0f44532b5a06d928d031ede4",
"sha256": "0l7mxza2nimslhg0qh6jp7gmb8sd6l89fk5d1zvzq2xskscq2vly"
"sha1": "9087f7abf0104e0354d7db7fc4576608eac558f4",
"sha256": "1n1872i240lakn4pzsag4grf7bv7lcsipmqllxd9m4k1zp3dgla1"
}
},
@@ -90,20 +81,20 @@
},
{
"path": "cider/cider-nrepl/0.25.3/cider-nrepl-0.25.3",
"path": "cider/cider-nrepl/0.29.0/cider-nrepl-0.29.0",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "5ae0efd9377a5e60c084bdaf4a2ce094f759ce23",
"sha256": "0drxf9nm23i1pcgrkwbcr09msq37csilzww38709add0hz8spjhq"
"sha1": "45f6034b26a14138e74145b7a4059628c0fedcd1",
"sha256": "1dy1l6y8cb8xiqq97a4lf8giyiicq4wfl4s2lxn5fb6614cjxqx2"
}
},
{
"path": "cider/piggieback/0.4.1/piggieback-0.4.1",
"path": "cider/piggieback/0.5.2/piggieback-0.5.2",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "0a02a3e2ecd7a126ab60d8a44793342f20ced79b",
"sha256": "142vl5np33akcrnn6pksi0rjfsmmi528villxsj6cwcndvybiw4m"
"sha1": "ecfd5c286a85db3f059e75c37fca5722d9e26f79",
"sha256": "1ps9yf3cxmlm447hqkidjb5xry90n0wl3jk0jn28fagq31lzylkl"
}
},
@@ -548,24 +539,6 @@
}
},
{
"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",
@@ -602,15 +575,6 @@
}
},
{
"path": "nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "4c94bd510f0c18a20191e46dd6becedebc640bbd",
"sha256": "0wpla2hx0s4mda58ndyd8938zmnz1gyhgfr6pzfphy27xfbvsssl"
}
},
{
"path": "org/apache/ant/ant/1.10.11/ant-1.10.11",
"host": "https://repo1.maven.org/maven2",
@@ -755,15 +719,6 @@
}
},
{
"path": "org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "aa95d25ea98bfe1152ea540f6e58a303c8cacc86",
"sha256": "0qvdsr5ryjmrpz622ivpyq5aayn42y4bk531vbasyj2yj7gcg35h"
}
},
{
"path": "org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218",
"host": "https://repo1.maven.org/maven2",
@@ -773,15 +728,6 @@
}
},
{
"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",
@@ -963,11 +909,11 @@
},
{
"path": "refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0",
"path": "refactor-nrepl/refactor-nrepl/3.6.0/refactor-nrepl-3.6.0",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "6bc3441afc94f7ca024e41a864ca75e05df7e207",
"sha256": "0w8hax99y98l53mixxzx2ja0vcnhjv8dnsaz1zj3vqk775ns5w6i"
"sha1": "2b3bb82da53b5db9c2b2aa298417816b81d0ed97",
"sha256": "1ysqabmlnghki6x0636zngxza2d83c85276wp9ma9wk183mkv52a"
}
},
+4 -10
View File
@@ -3,13 +3,12 @@ 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/dynaload/0.3.5/dynaload-0.3.5.jar
borkdude/edamame/1.3.23/edamame-1.3.23.jar
borkdude/edamame/1.1.17/edamame-1.1.17.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.25.3/cider-nrepl-0.25.3.jar
cider/piggieback/0.4.1/piggieback-0.4.1.jar
cider/cider-nrepl/0.29.0/cider-nrepl-0.29.0.jar
cider/piggieback/0.5.2/piggieback-0.5.2.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
@@ -59,13 +58,10 @@ 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
nrepl/nrepl/1.0.0/nrepl-1.0.0.jar
nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8.jar
org/apache/ant/ant/1.10.11/ant-1.10.11.jar
org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11.jar
org/babashka/sci/0.7.38/sci-0.7.38.jar
@@ -82,9 +78,7 @@ org/clojure/data.json/2.4.0/data.json-2.4.0.jar
org/clojure/data.priority-map/1.1.0/data.priority-map-1.1.0.jar
org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar
org/clojure/google-closure-library-third-party/0.0-20230227-c7c0a541/google-closure-library-third-party-0.0-20230227-c7c0a541.jar
org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0.jar
org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar
org/clojure/test.check/1.1.1/test.check-1.1.1.jar
org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0.jar
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
@@ -105,7 +99,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/2.5.0/refactor-nrepl-2.5.0.jar
refactor-nrepl/refactor-nrepl/3.6.0/refactor-nrepl-3.6.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
-9
View File
@@ -14,7 +14,6 @@ stdenv.mkDerivation {
"patchJavaPhase"
"patchReactNativePhase"
"patchPodPhase"
"patchGlogPhase"
"installPhase"
];
@@ -99,14 +98,6 @@ stdenv.mkDerivation {
'[RCTConvert UIColor:options.tintColor() ? @(*options.tintColor()) : nil];'
'';
# Fix pod issue after upgrading to MacOS Sonoma and Xcode 15
# https://github.com/status-im/status-mobile/issues/17682
patchGlogPhase = ''
substituteInPlace ./node_modules/react-native/scripts/ios-configure-glog.sh \
--replace 'export CC="' '#export CC="' \
--replace 'export CXX="' '#export CXX="'
'';
# The ELF types are incompatible with the host platform, so let's not even try
# TODO: Use Android NDK to strip binaries manually
dontPatchELF = true;
+3 -6
View File
@@ -67,12 +67,9 @@ stdenv.mkDerivation {
'';
buildPhase = ''
# Assemble CLASSPATH from available clojure dependencies.
# 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' ':')"
# We append 'src' so it can find the local sources.
export CLASS_PATH="$(find ${deps.clojure} \
-iname '*.jar' | tr '\n' ':')src"
# target must be one of the builds defined in shadow-cljs.edn
java -cp "$CLASS_PATH" clojure.main \
-1
View File
@@ -73,7 +73,6 @@ in {
allowHigher = true;
};
go = super.go_1_19;
clang = super.clang_15;
buildGoPackage = super.buildGo119Package;
buildGoModule = super.buildGo119Module;
gomobile = (super.gomobile.overrideAttrs (old: {
+1 -1
View File
@@ -94,7 +94,7 @@
"process": "0.11.10",
"react-test-renderer": "18.0.0",
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#refs/tags/v2.0.2-status",
"shadow-cljs": "2.26.2"
"shadow-cljs": "2.25.0"
},
"binary": {
"module_name": "status_nodejs_addon",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 114 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 75 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

@@ -1,10 +0,0 @@
#!/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
+4 -22
View File
@@ -9,15 +9,12 @@
[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 "3.9.1"]
[cider/cider-nrepl "0.31.0"]
[refactor-nrepl "2.5.0"]
[cider/cider-nrepl "0.25.3"]
[cider/piggieback "0.4.1"]
[org.slf4j/slf4j-nop "2.0.9"]
[re-frisk-remote "1.6.0"]
[nubank/matcher-combinators "3.8.8"]
;; Use the same version specified in the Nix dependency.
[clj-kondo/clj-kondo "2023.09.07"]
@@ -53,7 +50,6 @@
: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
@@ -75,10 +71,6 @@
: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
@@ -112,15 +104,13 @@
: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
{schema.core/throw-on-error? true
status-im2.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
{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"
@@ -149,17 +139,9 @@
:compiler-options {:optimizations :simple
:source-map false}}
:component-test {:target :npm-module
: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]
:entries [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}}}}
-1
View File
@@ -49,7 +49,6 @@
:Text {}
:StatusBar {}
:ScrollView {}
:SafeAreaView {}
:KeyboardAvoidingView {}
:TextInput {}
:Image {}
+17
View File
@@ -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]
-11
View File
@@ -116,17 +116,6 @@ rendered. We use [React Native Testing Library](https://callstack.github.io/reac
There are dozens of examples in the repository, so use them as a reference. A
good and complete example is [quo.components.avatars.user-avatar.component-spec](/src/quo/components/avatars/user_avatar/component_spec.cljs)
### No-props test
When writing tests for the component that has props, please add one test that covers situation when props aren't passed. Because even if component not showing anything meaningful without props, it shouldn't crash.
```clojure
(h/describe "Transaction Progress"
(h/test "component renders without props"
(h/render [quo/transaction-progress {}])
(h/is-truthy (h/get-by-label-text :transaction-progress)))
```
## Do not couple the library with re-frame
Don't use re-frame inside this library (e.g. dispatch & subscribe). If a
@@ -30,6 +30,6 @@
{:accessibility-label :account-emoji
:adjusts-font-size-to-fit true
:style {:font-size emoji-size}}
(when emoji (string/trim emoji))]]))
(string/trim emoji)]]))
(def view (quo.theme/with-theme view-internal))
@@ -67,7 +67,7 @@
[rn/text
{:style (style/emoji-size size)
:accessibility-label :emoji}
(when emoji (string/trim emoji))])
(string/trim emoji)])
[lock locked? size theme]])
(def view (quo.theme/with-theme view-internal))
@@ -2,30 +2,26 @@
(:require [quo.foundations.colors :as colors]))
(defn- circle-color
[customization-color neutral? theme]
(if neutral?
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme)
(colors/custom-color customization-color 50 20)))
[customization-color]
(colors/custom-color customization-color 50 20))
(defn- text-color
[customization-color neutral? theme]
(if neutral?
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
(colors/theme-colors
(colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme)))
[customization-color theme]
(colors/theme-colors
(colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme))
(defn container
[circle-size customization-color neutral? theme]
[circle-size customization-color]
{:width circle-size
:height circle-size
:border-radius circle-size
:text-align :center
:justify-content :center
:align-items :center
:background-color (circle-color customization-color neutral? theme)})
:background-color (circle-color customization-color)})
(defn text
[customization-color neutral? theme]
{:color (text-color customization-color neutral? theme)})
[customization-color theme]
{:color (text-color customization-color theme)})
@@ -1,6 +1,5 @@
(ns quo.components.avatars.wallet-user-avatar.view
(:require [clojure.string :as string]
[quo.components.avatars.wallet-user-avatar.style :as style]
(:require [quo.components.avatars.wallet-user-avatar.style :as style]
[quo.components.markdown.text :as text]
[quo.theme :as quo.theme]
[react-native.core :as rn]
@@ -41,21 +40,18 @@
:customization-color - keyword (default: nil) - color of the avatar
:size - keyword (default: last element of properties object) - size of the
avatar
:monospace? - boolean (default: false) - use monospace font
:lowercase? - boolean (default: false) - lowercase text
:neutral? - boolean (default: false) - use neutral colors variant"
[{:keys [full-name customization-color size theme monospace? lowercase? neutral?]
:monospace? - boolean (default: false) - use monospace font"
[{:keys [full-name customization-color size theme monospace?]
:or {size biggest-possible}}]
(let [circle-size (:size (size properties))
small? (check-if-size-small size)
initials (utils.string/get-initials full-name (if small? 1 2))]
small? (check-if-size-small size)]
[rn/view
{:style (style/container circle-size customization-color neutral? theme)}
{:style (style/container circle-size customization-color)}
[text/text
{:accessibility-label :wallet-user-avatar
:size (:font-size (size properties))
:weight (if monospace? :monospace (:font-weight (size properties)))
:style (style/text customization-color neutral? theme)}
(if (and initials lowercase?) (string/lower-case initials) initials)]]))
:style (style/text customization-color theme)}
(utils.string/get-initials full-name (if small? 1 2))]]))
(def wallet-user-avatar (quo.theme/with-theme view-internal))
@@ -3,22 +3,18 @@
[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"
(render [step/view {} nil])
(h/render [step/view {} nil])
(-> (h/expect (h/query-by-label-text :step-counter))
(h/is-truthy)))
(h/test "renders step with a string value"
(render [step/view {} "1"])
(h/render [step/view {} "1"])
(-> (h/expect (h/get-by-text "1"))
(h/is-truthy)))
(h/test "renders step with an integer value"
(render [step/view {} 1])
(h/render [step/view {} 1])
(-> (h/expect (h/get-by-text "1"))
(h/is-truthy))))
+3 -20
View File
@@ -2,24 +2,10 @@
(:require
[quo.components.counter.step.style :as style]
[quo.components.markdown.text :as text]
quo.theme
[quo.theme :as 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)
@@ -37,9 +23,6 @@
[text/text
{:weight :medium
:size :label
:style {:color (style/text-color type theme)}}
label]]))
:style {:color (style/text-color type theme)}} label]]))
(def view
(quo.theme/with-theme
(schema/instrument #'view-internal ?schema)))
(def view (theme/with-theme view-internal))
@@ -1,56 +0,0 @@
(ns quo.components.dropdowns.dropdown-input.component-spec
(:require
[quo.components.dropdowns.dropdown-input.view :as dropdown-input]
[test-helpers.component :as h]))
(h/describe "Dropdown Input"
(h/test "default render"
(let [header-label "Label"
label "Dropdown"]
(h/render [dropdown-input/view
{:label? true
:header-label
header-label} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-truthy (h/get-by-text header-label))
(h/is-truthy (h/get-by-text label))))
(h/test "render with icon"
(let [label "Dropdown"]
(h/render [dropdown-input/view
{:icon? true
:icon-name
:i/wallet
:label? true}
label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-truthy (h/get-by-label-text :left-icon))
(h/is-truthy (h/get-by-text label))))
(h/test "render in active state"
(let [label "Dropdown"]
(h/render [dropdown-input/view
{:state :active
:label?
true} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-truthy (h/get-by-label-text :right-icon "Expecting active state icon"))))
(h/test "render in disabled state"
(let [label "Dropdown"]
(h/render [dropdown-input/view
{:state :disabled
:label? true} label])
(h/is-truthy (h/get-by-label-text :dropdown))
(h/is-disabled (h/get-by-text label "Dropdown should be disabled in disabled state"))))
(h/test "on-press"
(let [event (h/mock-fn)
label "Dropdown"]
(h/render [dropdown-input/view
{:on-press event
:label?
true} label])
(h/fire-event :press (h/get-by-text label))
(h/was-called event))))
@@ -1,49 +0,0 @@
(ns quo.components.dropdowns.dropdown-input.properties
(:require
[quo.foundations.colors :as colors]))
(def icon-size 20)
(defn- grey-blur
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
:right-icon-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if active?
(colors/theme-colors colors/neutral-80-opa-20
colors/white-opa-40
theme)
(colors/theme-colors colors/neutral-80-opa-10
colors/white-opa-10
theme))})
(defn- outline
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if active?
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))})
(defn- grey
[theme active?]
{:left-icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:right-icon-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
:right-icon-color-2 (colors/theme-colors colors/neutral-100 colors/white theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if active?
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-20
colors/neutral-60
theme))})
(defn get-colors
[{:keys [theme state blur?]}]
(let [active? (= state :active)]
(cond
blur? (grey-blur theme active?)
(= theme :dark) (outline theme active?)
(= theme :light) (grey theme active?))))
@@ -1,62 +0,0 @@
(ns quo.components.dropdowns.dropdown-input.style
(:require
[quo.foundations.colors :as colors]))
(def gap 8)
(def blur-view
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0})
(def left-icon
{:margin-right gap})
(defn right-icon
[theme]
{:color (colors/theme-colors colors/neutral-100 colors/white theme)
:margin-right gap})
(defn header-label
[theme blur?]
{:color (if blur?
(colors/theme-colors colors/neutral-80-opa-40
colors/white-opa-70
theme)
(colors/theme-colors colors/neutral-50
colors/neutral-40
theme))
:margin-bottom gap})
(def root-container
{:width "100%"
:height 40})
(defn container
[{:keys [background-color border-color]}
{:keys [icon? state]}]
(cond-> {:align-items :center
:justify-content :space-between
:flex-direction :row
:padding-vertical 9
:padding-left 16
:padding-right 12
:overflow :hidden
:background-color background-color
:border-radius 12}
icon?
(assoc :padding-left 12)
border-color
(assoc :border-color border-color
:border-width 1)
(= state :disabled)
(assoc :opacity 0.3)))
(def right-half-container
{:flex-direction :row
:align-items :center})
@@ -1,68 +0,0 @@
(ns quo.components.dropdowns.dropdown-input.view
(:require
[quo.components.dropdowns.dropdown-input.properties :as properties]
[quo.components.dropdowns.dropdown-input.style :as style]
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.theme :as theme]
[react-native.core :as rn]))
(defn- view-internal
[{:keys [state theme on-press icon?
label? blur?
accessibility-label header-label]
:or {state :default
icon? true
label? true
blur? false
header-label "Label"}
:as props}
label]
(let [{:keys [left-icon-color right-icon-color right-icon-color-2]
:as colors} (properties/get-colors props)
right-icon (if (= state :active) :i/pullup :i/dropdown)]
[rn/view
{:style style/root-container}
(when label?
[text/text
{:size :paragraph-2
:weight :medium
:align :left
:style (style/header-label theme blur?)} header-label])
[rn/pressable
{:accessibility-label (or accessibility-label :dropdown)
:disabled (= state :disabled)
:on-press on-press
:style (style/container colors props)}
[rn/view
{:style style/right-half-container}
(when icon?
[icon/icon
:i/placeholder
{:accessibility-label :left-icon
:color left-icon-color
:size properties/icon-size
:container-style style/left-icon}])
[text/text
{:size :paragraph-1
:weight :regular
:number-of-lines 1
:style (style/right-icon theme)}
label]]
[icon/icon
right-icon
{:size properties/icon-size
:accessibility-label :right-icon
:color right-icon-color
:color-2 right-icon-color-2}]]]))
(def view
"Props:
- state: :default (default) | :active | :disabled
- label: string
- header-label: string
- icon?: boolean
- label?: boolean
- blur?: boolean
- on-press: function"
(theme/with-theme view-internal))
@@ -19,7 +19,3 @@
:background-color colors/danger-50
:align-items :center
:justify-content :center})
(def empty-state
{:width 375
:height 116})
@@ -2,12 +2,11 @@
(: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
@@ -43,10 +42,11 @@
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)
[fast-image/fast-image
{:style style/empty-state
:source (resources/get-themed-image :no-funds theme)
:accessibility-label :illustration}]
[rn/view
{:accessibility-label :illustration
:style style/illustration}
[text/text {:style {:color colors/white}}
"Illustration here"]]
[rn/view
[linear-gradient/linear-gradient
{:colors gradient-colors
+19 -18
View File
@@ -3,18 +3,22 @@
[quo.components.icon :as quo.icons]
[quo.components.markdown.text :as text]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[quo.theme :as theme]
[react-native.core :as rn]))
(defn get-color
[k theme]
(case k
:success (colors/resolve-color :success theme)
:error (colors/resolve-color :danger theme)
:warning (colors/resolve-color :warning theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(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 view-internal
(defn get-color
[k]
(get-in themes [(theme/get-theme) k]))
(defn info-message
"[info-message opts \"message\"]
opts
{:type :default/:success/:error
@@ -23,11 +27,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 theme icon text-color icon-color no-icon-color? style accessibility-label]} message]
[{:keys [type size icon text-color icon-color no-icon-color? style]} 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 theme))
text-color (or text-color (get-color type))
icon-color (or icon-color text-color)]
[rn/view
{:style (merge {:flex-direction :row
@@ -38,10 +42,7 @@
:no-color no-icon-color?
:size icon-size}]
[text/text
{:accessibility-label accessibility-label
:size size
:weight weight
:style {:color text-color
:margin-horizontal 4}} message]]))
(def info-message (quo.theme/with-theme view-internal))
{:size size
:weight weight
:style {:color text-color
:margin-horizontal 4}} message]]))
@@ -61,10 +61,14 @@
value (reagent/atom "")
focused? (atom false)]
(fn [{:keys [scanned-value theme blur? on-change-text on-blur on-focus on-clear on-scan on-detect-ens
on-detect-address address-regex valid-ens-or-address?]}]
on-detect-address
ens-regex address-regex
valid-ens-or-address?]}]
(let [on-change (fn [text]
(when (not= @value text)
(let [address? (when address-regex
(let [ens? (when ens-regex
(boolean (re-matches ens-regex text)))
address? (when address-regex
(boolean (re-matches address-regex text)))]
(if (> (count text) 0)
(reset! status :typing)
@@ -72,9 +76,9 @@
(reset! value text)
(when on-change-text
(on-change-text text))
(when (and on-detect-ens (> (count text) 0))
(when (and ens? on-detect-ens)
(reset! status :loading)
(on-detect-ens text #(reset! status :typing)))
(on-detect-ens text))
(when (and address? on-detect-address)
(reset! status :loading)
(on-detect-address text)))))
@@ -1,17 +0,0 @@
(ns quo.components.ios.drawer-bar.style
(:require
[quo.foundations.colors :as colors]
[quo.theme :as theme]))
(def handle-container
{:padding-vertical 8
:height 20
:align-items :center})
(defn handle
[{:keys [theme]}]
{:width 32
:height 4
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
:opacity (theme/theme-value 0.05 0.1 theme)
:border-radius 100})
@@ -1,12 +0,0 @@
(ns quo.components.ios.drawer-bar.view
(:require
[quo.components.ios.drawer-bar.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]))
(defn- view-internal
[props]
[rn/view {:style style/handle-container}
[rn/view {:style (style/handle props)}]])
(def view (quo.theme/with-theme view-internal))
@@ -13,7 +13,7 @@
(h/render [account/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})))
{:backgroundColor (colors/custom-color :blue 50 5)})))
(h/test "on-press-in changes state to :pressed with blur? enabled"
(h/render [account/view {:blur? true}])
@@ -21,26 +21,31 @@
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-5})))
(h/test "render with state :active"
(h/render [account/view {:state :active}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 10)}))
(h/test "on-press-out changes state to :active"
(h/render [account/view])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/custom-color :blue 50 10)})))
(h/test "render with state :active and blur? enabled"
(h/render [account/view
{:blur? true
:state :active}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-10}))
(h/test "on-press-out changes state to :active with blur? enabled"
(h/render [account/view {:blur? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor colors/white-opa-10})))
(h/test "render with state :selected"
(h/render [account/view {:state :selected}])
(h/is-truthy (h/query-by-label-text :check-icon)))
(h/test "on-press-out changes state to :selected"
(h/render [account/view {:selectable? true}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/wait-for #(h/is-truthy (h/query-by-label-text :check-icon))))
(h/test "calls on-press"
(h/test "on-press-out calls on-press"
(let [on-press (h/mock-fn)]
(h/render [account/view {:on-press on-press}])
(h/fire-event :on-press (h/get-by-label-text :container))
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/fire-event :on-press-out (h/get-by-label-text :container))
(h/was-called on-press)))
(h/test "renders token props if type :tag"
@@ -3,12 +3,12 @@
[quo.foundations.colors :as colors]))
(defn- background-color
[{:keys [state pressed? blur? customization-color]}]
(cond (or pressed? (= state :selected))
(if blur? colors/white-opa-5 (colors/resolve-color customization-color :light 5))
[{:keys [state blur? customization-color]}]
(cond (or (= state :pressed) (= state :selected))
(if blur? colors/white-opa-5 (colors/custom-color customization-color 50 5))
(= state :active)
(if blur? colors/white-opa-10 (colors/resolve-color customization-color :light 10))
(and pressed? blur?) colors/white-opa-10
(if blur? colors/white-opa-10 (colors/custom-color customization-color 50 10))
(and (= state :pressed) blur?) colors/white-opa-10
:else :transparent))
(defn container
+51 -31
View File
@@ -94,42 +94,62 @@
[icon/icon :i/check
{:color (if blur?
colors/white
(colors/resolve-color customization-color theme))}]])
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme))}]])
(defn- internal-view
[_]
(let [pressed? (reagent/atom false)
on-press-in #(reset! pressed? true)
on-press-out #(reset! pressed? false)]
(fn [{:keys [type state blur? customization-color on-press]
(defn- f-internal-view
[]
(let [state (reagent/atom :default)
active-or-selected? (atom false)
timer (atom nil)
on-press-in (fn []
(when-not (= @state :selected)
(reset! timer (js/setTimeout #(reset! state :pressed) 100))))]
(fn [{:keys [type selectable? blur? customization-color on-press]
:or {customization-color :blue
type :default
state :default
blur? false}
:as props}]
[rn/pressable
{:style (style/container
{:state state
:blur? blur?
:customization-color customization-color
:pressed? @pressed?})
:on-press-in on-press-in
:on-press on-press
:on-press-out on-press-out
:accessibility-label :container}
[account-view props]
[rn/view {:style (when (= type :tag) style/token-tag-container)}
(cond
(#{:balance-neutral :balance-negative :balance-positive} type)
[balance-view props]
(let [on-press-out (fn []
(let [new-state (if @active-or-selected?
:default
(if (and (= type :default) selectable?)
:selected
:active))]
(when @timer (js/clearTimeout @timer))
(reset! timer nil)
(reset! active-or-selected? (or (= new-state :active)
(= new-state :selected)))
(reset! state new-state)
(when on-press
(on-press))))]
(rn/use-effect
#(cond (and selectable? (= type :default) (= @state :active)) (reset! state :selected)
(and (not selectable?) (= type :default) (= @state :selected)) (reset! state :active))
[selectable?])
[rn/pressable
{:style (style/container
{:state @state :blur? blur? :customization-color customization-color})
:on-press-in on-press-in
:on-press-out on-press-out
:accessibility-label :container}
[account-view props]
[rn/view {:style (when (= type :tag) style/token-tag-container)}
(when (or (= type :balance-neutral)
(= type :balance-negative)
(= type :balance-positive))
[balance-view props])
(when (= type :tag)
[token-tag props])
(when (= type :action)
[options-button props])
(when (and (= type :default)
(= @state :selected))
[check-icon props])]]))))
(= type :tag)
[token-tag props]
(= type :action)
[options-button props]
(and (= type :default) (= state :selected))
[check-icon props])]])))
(defn- internal-view
[props]
[:f> f-internal-view props])
(def view (quo.theme/with-theme internal-view))
@@ -13,11 +13,11 @@
[{:keys [theme address networks blur?]}]
[rn/view {:style style/left-container}
[wallet-user-avatar/wallet-user-avatar
{:size :size-32
:full-name "0 x"
{:size :medium
:f-name "0"
:l-name "x"
:monospace? true
:lowercase? true
:neutral? true}]
:uppercase? false}]
[rn/view {:style style/account-container}
[text/text {:size :paragraph-1}
(map (fn [network]
@@ -25,8 +25,8 @@
[text/text
{:size :paragraph-1
:weight :semi-bold
:style {:color (colors/resolve-color (:network-name network) theme)}}
(str (:short-name network) ":")])
:style {:color (colors/resolve-color network theme)}}
(str (subs (name network) 0 3) ":")])
networks)
[text/text
{:size :paragraph-1
@@ -1,5 +1,6 @@
(ns quo.components.list-items.saved-address.view
(:require
[clojure.string :as string]
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
[quo.components.icon :as icon]
[quo.components.list-items.saved-address.style :as style]
@@ -12,23 +13,27 @@
(defn- left-container
[{:keys [blur? theme name ens address customization-color]}]
[rn/view {:style style/left-container}
[wallet-user-avatar/wallet-user-avatar
{:size :size-32
:full-name name
:customization-color customization-color}]
[rn/view {:style style/account-container}
[text/text
{:weight :semi-bold
:size :paragraph-1
:style style/name-text}
name]
[text/text {:size :paragraph-2}
[text/text
{:size :paragraph-2
:weight :monospace
:style (style/account-address blur? theme)}
(or ens (address/get-shortened-key address))]]]])
(let [names (remove string/blank? (string/split name " "))
first-name (if (> (count names) 0) (first names) "")
last-name (if (> (count names) 1) (last names) "")]
[rn/view {:style style/left-container}
[wallet-user-avatar/wallet-user-avatar
{:size :medium
:f-name first-name
:l-name last-name
:customization-color customization-color}]
[rn/view {:style style/account-container}
[text/text
{:weight :semi-bold
:size :paragraph-1
:style style/name-text}
name]
[text/text {:size :paragraph-2}
[text/text
{:size :paragraph-2
:weight :monospace
:style (style/account-address blur? theme)}
(or ens (address/get-shortened-key address))]]]]))
(defn- internal-view
[]
@@ -26,25 +26,21 @@
(def info
{:flex-direction :row
:align-items :center
:width "70%"})
:align-items :center})
(def token-info
{:height 40
:flex 1})
{:height 40})
(def token-image
{:width 32
:height 32
:border-width 1
:border-radius 16
:border-color colors/neutral-80-opa-5
:margin-right 8
:background-color colors/neutral-80-opa-5})
{:width 32
:height 32
:border-width 1
:border-radius 16
:border-color colors/neutral-80-opa-5
:margin-right 8})
(def values-container
{:align-items :flex-end
:max-width "30%"})
{:align-items :flex-end})
(defn fiat-value
[theme]
@@ -15,14 +15,11 @@
{:source (or (:source token) token)
:style style/token-image}]
[rn/view {:style style/token-info}
[text/text
{:weight :semi-bold
:number-of-lines 1}
(if-not (empty? label) label "-")]
[text/text {:weight :semi-bold} label]
[preview-list/view
{:type :network
:size :size-14
:number (count networks)}
:number 3}
networks]]])
(defn- values
@@ -33,14 +30,12 @@
:accessibility-label :check-icon}]
[rn/view {:style style/values-container}
[text/text
{:weight :medium
:size :paragraph-2
:number-of-lines 1}
{:weight :medium
:size :paragraph-2}
token-value]
[text/text
{:style (style/fiat-value theme)
:size :paragraph-2
:number-of-lines 1}
{:style (style/fiat-value theme)
:size :paragraph-2}
fiat-value]]))
(defn- view-internal
@@ -22,10 +22,9 @@
(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-with-theme-provider [list/view
{:type :step
:step-number 1}]
:dark)
(h/render [list/view
{:type :step
:step-number 1}])
(h/is-truthy (h/get-by-label-text :step-counter)))
(h/test "renders decription with a context tag component and description after the tag"
@@ -36,7 +36,7 @@
:blur? false
:type :digit} 1])
(h/is-truthy (h/query-by-label-text :text-label))
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key))
(h/was-called on-press)))
(h/test "Is not pressable when disabled is true"
@@ -47,5 +47,5 @@
:blur? false
:type :digit} 1])
(h/is-truthy (h/query-by-label-text :text-label))
(h/fire-event :press (h/query-by-label-text :keyboard-key-1))
(h/fire-event :press (h/query-by-label-text :keyboard-key))
(h/was-not-called on-press))))
@@ -7,11 +7,6 @@
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn- label->accessibility-label
[label]
(let [label-name (if (keyword? label) (name label) label)]
(keyword (str "keyboard-key-" label-name))))
(defn- view-internal
[]
(let [pressed? (reagent/atom false)]
@@ -19,11 +14,9 @@
(let [label-color (style/get-label-color disabled? theme blur?)
background-color (style/toggle-background-color @pressed? blur? theme)]
[rn/pressable
{:accessibility-label (label->accessibility-label label)
{:accessibility-label :keyboard-key
:disabled (or disabled? (not label))
:on-press (fn []
(when on-press
(on-press label)))
:on-press (fn [] (on-press label))
:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)
:style (style/container background-color)}
@@ -1,7 +1,7 @@
(ns quo.components.numbered-keyboard.numbered-keyboard.style)
(def container
{:display :flex
{:flex 1
:padding-top 8
:padding-horizontal 48})
@@ -17,17 +17,13 @@
(defn- view-internal
[]
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press on-delete
container-style]
:or {left-action :none}}]
(fn [{:keys [disabled? theme blur? left-action delete-key? on-press]}]
[rn/view
{:style (merge style/container
container-style)}
{:style style/container}
(for [row-index (range 1 4)]
^{:key row-index}
[rn/view {:style style/row-container}
(for [column-index (range 1 4)]
^{:key (str row-index column-index)}
[keyboard-item
{:item (+ (* (dec row-index) 3) column-index)
:type :digit
@@ -62,10 +58,10 @@
:theme theme}]
(if delete-key?
[keyboard-item
{:item :i/backspace
{:item :i/delete
:type :key
:disabled? disabled?
:on-press on-delete
:on-press on-press
:blur? blur?
:theme theme}]
[keyboard-item])]]))
-22
View File
@@ -1,22 +0,0 @@
(ns quo.components.overlay.style
(:require [quo.foundations.colors :as colors]))
(defn overlay-background
[type]
(let [background-color (case type
:shell colors/neutral-80-opa-80-blur
:drawer colors/neutral-100-opa-70-blur
nil)]
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0
:background-color background-color}))
(def container
{:flex 1})
(def blur-container
{:flex 1
:background-color :transparent})
-20
View File
@@ -1,20 +0,0 @@
(ns quo.components.overlay.view
(:require
[quo.components.overlay.style :as style]
[react-native.blur :as blur]
[react-native.core :as rn]))
(defn view
[{:keys [type]} & children]
[rn/view {:style (style/overlay-background type)}
(if (= type :shell)
[blur/view
{:blur-amount 20
:blur-radius 25
:blur-type :transparent
:overlay-color :transparent
:style style/container}
[rn/view {:style style/blur-container}
children]]
[rn/view {:style style/container}
children])])
@@ -1,7 +1,6 @@
(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
@@ -10,14 +9,14 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -27,14 +26,14 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? false
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -45,14 +44,14 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :small
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -63,14 +62,14 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -81,31 +80,31 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
(h/is-truthy (h/get-by-text "Subtitle")))
(h/is-truthy (h/get-by-text "Description")))
(h/test "right icon is not visible when icon-right? is false"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? false
:card? true
:label :none
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -115,6 +114,7 @@
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? true
:right-icon :i/chevron-right
:card? true
@@ -122,17 +122,17 @@
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
(h/is-truthy (h/query-by-label-text :icon-right)))
(h/test "icon is visible when subtitle type is icon"
(h/test "description icon is visible when description is icon"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :icon
:icon-right? true
:right-icon :i/chevron-right
:card? true
@@ -140,17 +140,17 @@
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :icon
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
(h/is-truthy (h/query-by-label-text :subtitle-type-icon)))
(h/is-truthy (h/query-by-label-text :description-icon)))
(h/test "image is visible when subtitle type is network"
(h/test "description image is visible when description is network"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :network
:icon-right? true
:right-icon :i/chevron-right
:card? true
@@ -158,18 +158,17 @@
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :network
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow
:network-image (quo.resources/get-network :ethereum)}])
(h/is-truthy (h/query-by-label-text :subtitle-type-image)))
:customization-color :yellow}])
(h/is-truthy (h/query-by-label-text :description-image)))
(h/test "emoji is visible when subtitle type is account"
(h/test "description emoji is visible when description is account"
(h/render [quo/data-item
{:on-press (h/mock-fn)
:blur? false
:description :account
:icon-right? true
:right-icon :i/chevron-right
:card? true
@@ -177,8 +176,7 @@
:status :default
:size :default
:title "Label"
:subtitle "Subtitle"
:subtitle-type :account
:subtitle "Description"
:icon :i/placeholder
:emoji "🎮"
:customization-color :yellow}])
@@ -37,8 +37,8 @@
:align-items :center})
(defn subtitle-icon-container
[subtitle-type]
{:margin-right (when (not= :default subtitle-type) 4)
[description]
{:margin-right (when (not= :default description) 4)
:justify-content :center})
(defn title
+13 -14
View File
@@ -7,6 +7,7 @@
[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]))
@@ -16,15 +17,13 @@
[rn/view {:style (style/loading-container size blur? theme)}])
(defn- left-subtitle
[{:keys [theme size subtitle-type icon icon-color blur? subtitle customization-color emoji
network-image]
:or {subtitle-type :default}}]
[{:keys [theme size description icon icon-color blur? subtitle customization-color emoji]}]
[rn/view {:style style/subtitle-container}
(when (not= :small size)
[rn/view {:style (style/subtitle-icon-container subtitle-type)}
(case subtitle-type
[rn/view {:style (style/subtitle-icon-container description)}
(case description
:icon [icons/icon icon
{:accessibility-label :subtitle-type-icon
{:accessibility-label :description-icon
:size 16
:color icon-color}]
:account [account-avatar/view
@@ -33,8 +32,8 @@
:emoji emoji
:type :default}]
:network [rn/image
{:accessibility-label :subtitle-type-image
:source network-image
{:accessibility-label :description-image
:source (quo.resources/tokens :eth)
:style style/image}]
nil)])
[text/text
@@ -59,9 +58,10 @@
(i18n/label :t/days)])])
(defn- left-side
"The description can either be given as a string `subtitle-type` or a component `custom-subtitle`"
[{:keys [theme title status size blur? custom-subtitle icon subtitle subtitle-type label icon-color
customization-color network-image emoji]
"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
emoji]
:as props}]
[rn/view {:style style/left-side}
[left-title
@@ -79,14 +79,13 @@
[left-subtitle
{:theme theme
:size size
:subtitle-type subtitle-type
:description description
:icon icon
:icon-color icon-color
:blur? blur?
:subtitle subtitle
:customization-color customization-color
:emoji emoji
:network-image network-image}]))])
:emoji emoji}]))])
(defn- right-side
[{:keys [label icon-right? right-icon icon-color communities-list]}]
+27 -18
View File
@@ -17,21 +17,30 @@
{:width size})))
(defn base-tag
[{:keys [id size disabled? border-color border-width background-color on-press
accessibility-label type labelled?]
:or {size 32}}
children]
[rn/touchable-without-feedback
(merge {:disabled disabled?
:accessibility-label accessibility-label}
(when on-press
{:on-press #(on-press id)}))
[rn/view
{:style (merge (style-container size
disabled?
border-color
border-width
background-color
labelled?
type))}
children]])
[_]
(fn
[{:keys [id
size
disabled?
border-color
border-width
background-color
on-press
accessibility-label
type
labelled?]
:or {size 32}} children]
[rn/touchable-without-feedback
(merge {:disabled disabled?
:accessibility-label accessibility-label}
(when on-press
{:on-press #(on-press id)}))
[rn/view
{:style (merge (style-container size
disabled?
border-color
border-width
background-color
labelled?
type))}
children]]))
@@ -1,53 +0,0 @@
(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"))))
@@ -1,29 +0,0 @@
(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})
@@ -1,67 +0,0 @@
(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))
+39 -30
View File
@@ -4,7 +4,7 @@
[quo.components.markdown.text :as text]
[quo.components.tags.base-tag :as base-tag]
[quo.foundations.colors :as colors]
[quo.theme]
[quo.theme :as theme]
[react-native.core :as rn]))
(def themes
@@ -66,45 +66,54 @@
text-color)
label])])
(defn tag-internal
(defn tag
"opts
{:type :icon/:emoji/:label
:label string
:size 32/24
:on-press fn
:blurred? true/false
:blurred? true/false
:resource icon/image
:labelled? true/false
:disabled? true/false}
opts
- `blurred` boolean: use to determine border color if the background is blurred
- `type` can be icon or emoji with or without a tag label
- `labelled` boolean: is true if tag has label else false"
[{:keys [id on-press disabled? size active accessibility-label label resource type
labelled? blurred? icon-color theme]
:or {size 32}}]
(let [state (cond
disabled? :disabled
active :active
:else :default)
{:keys [border-color
blurred-border-color
text-color]} (get-in themes [theme state])]
[rn/view {:style {:align-items :center}}
[base-tag/base-tag
{:id id
:size size
:border-width 1
:border-color (if blurred?
blurred-border-color
border-color)
:on-press on-press
:accessibility-label accessibility-label
:disabled? disabled?
:type type
:labelled? (if (= type :label) true labelled?)}
[tag-resources size type resource icon-color label text-color labelled?]]]))
(def tag (quo.theme/with-theme tag-internal))
[_ _]
(fn
[{:keys [id
on-press
disabled?
size
active
accessibility-label
label
resource
type
labelled?
blurred?
icon-color
override-theme]
:or {size 32}}]
(let [state (cond disabled? :disabled
active :active
:else :default)
{:keys [border-color blurred-border-color text-color]}
(get-in themes [(or override-theme (theme/get-theme)) state])]
[rn/view {:style {:align-items :center}}
[base-tag/base-tag
{:id id
:size size
:border-width 1
:border-color (if blurred?
blurred-border-color
border-color)
:on-press on-press
:accessibility-label accessibility-label
:disabled? disabled?
:type type
:labelled? (if (= type :label) true labelled?)}
[tag-resources size type resource icon-color label text-color labelled?]]])))
@@ -1,28 +0,0 @@
(ns quo.components.text-combinations.channel-name.component-spec
(:require [quo.components.text-combinations.channel-name.view :as channel-name]
[test-helpers.component :as h]))
(h/describe "Channel name"
(h/test "Renders Default"
(h/render [channel-name/view {:channel-name "Test channel"}])
(h/is-truthy (h/get-by-text "# Test channel")))
(h/test "Renders unlocked icon"
(h/render [channel-name/view
{:channel-name "Test channel"
:unlocked? true}])
(h/is-truthy (h/get-by-label-text :channel-name-unlocked-icon)))
(h/test "Renders muted icon"
(h/render [channel-name/view
{:channel-name "Test channel"
:muted? true}])
(h/is-truthy (h/get-by-label-text :channel-name-muted-icon)))
(h/test "Renders muted and unlocked icon"
(h/render [channel-name/view
{:channel-name "Test channel"
:muted? true
:unlocked? true}])
(h/is-truthy (h/get-by-label-text :channel-name-unlocked-icon))
(h/is-truthy (h/get-by-label-text :channel-name-muted-icon))))
@@ -1,30 +0,0 @@
(ns quo.components.text-combinations.channel-name.style
(:require [quo.foundations.colors :as colors]))
(def container {:flex-direction :row})
(def icons-container
{:flex-direction :row
:padding-top 8
:padding-bottom 4
:margin-left 6})
(def icon {:width 20 :height 20})
(def icons-gap {:width 4})
(defn- blur-icon-color
[theme]
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme))
(defn unlocked-icon-color
[theme blur?]
(if blur?
(blur-icon-color theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn muted-icon-color
[theme blur?]
(if blur?
(blur-icon-color theme)
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)))
@@ -1,40 +0,0 @@
(ns quo.components.text-combinations.channel-name.view
(:require [quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.text-combinations.channel-name.style :as style]
[quo.theme]
[react-native.core :as rn]))
(defn icons
[{:keys [theme unlocked? muted? blur?]}]
[rn/view {:style style/icons-container}
(when unlocked?
[rn/view
{:style style/icon
:accessibility-label :channel-name-unlocked-icon}
[icon/icon :i/unlocked
{:color (style/unlocked-icon-color theme blur?)
:size 20}]])
(when (and unlocked? muted?)
[rn/view {:style style/icons-gap}])
(when muted?
[rn/view
{:style style/icon
:accessibility-label :channel-name-muted-icon}
[icon/icon :i/muted
{:color (style/muted-icon-color theme blur?)
:size 20}]])])
(defn- view-internal
[{:keys [unlocked? muted? channel-name] :as props}]
[rn/view {:style style/container}
[text/text
{:size :heading-1
:weight :semi-bold}
(str "# " channel-name)]
(when (or unlocked? muted?)
[icons props])])
(def view (quo.theme/with-theme view-internal))
@@ -1,51 +0,0 @@
(ns quo.components.text-combinations.standard-title.component-spec
(:require [quo.components.text-combinations.standard-title.view :as standard-title]
[test-helpers.component :as h]))
(h/describe "Text combinations - Standard title"
(h/test "Default render"
(h/render [standard-title/view {:title "This is a title"}])
(h/is-truthy (h/get-by-text "This is a title")))
(h/test "Counter variant"
(h/render [standard-title/view
{:title "This is a title"
:right :counter
:counter-left 50
:counter-right 100}])
(h/is-truthy (h/get-by-text "50/100")))
(h/describe "Action variant"
(h/test "Default render"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :action
:on-press on-press-fn}])
(h/is-truthy (h/get-by-text "This is a title"))))
(h/test "Action fired"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :action
:on-press on-press-fn}])
(h/fire-event :on-press (h/get-by-label-text :standard-title-action))
(h/was-called-times on-press-fn 1))))
(h/describe "Tag variant"
(h/test "Default render"
(h/render [standard-title/view
{:title "This is a title"
:right :tag}])
(h/is-truthy (h/get-by-text "This is a title")))
(h/test "Tag callback fired"
(let [on-press-fn (h/mock-fn)]
(h/render [standard-title/view
{:title "This is a title"
:right :tag
:on-press on-press-fn}])
(h/fire-event :on-press (h/get-by-label-text :standard-title-tag))
(h/was-called-times on-press-fn 1)))))
@@ -1,24 +0,0 @@
(ns quo.components.text-combinations.standard-title.style
(:require [quo.foundations.colors :as colors]))
(def container
{:flex-direction :row
:justify-content :space-between})
(def right-container {:margin-left 20})
(def right-counter
{:padding-top 12
:padding-bottom 2})
(defn right-counter-text
[blur? theme]
{:color (if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme))})
(defn right-tag-icon-color
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
@@ -1,68 +0,0 @@
(ns quo.components.text-combinations.standard-title.view
(:require [clojure.string :as string]
[quo.components.buttons.button.view :as button]
[quo.components.markdown.text :as text]
[quo.components.tags.tag :as tag]
[quo.components.text-combinations.standard-title.style :as style]
[quo.theme]
[react-native.core :as rn]
[utils.number]))
(defn- get-counter-number
[n]
(let [parsed-number (utils.number/parse-int n)]
(if (< n 10)
(str "0" parsed-number)
parsed-number)))
(defn- right-counter
[{:keys [blur? theme counter-left counter-right]}]
[rn/view {:style style/right-counter}
[text/text
{:size :paragraph-2
:weight :regular
:style (style/right-counter-text blur? theme)}
(str (get-counter-number counter-left)
"/"
(get-counter-number counter-right))]])
(defn- right-action
[{:keys [customization-color on-press icon]
:or {icon :i/placeholder}}]
[button/button
{:accessibility-label :standard-title-action
:size 32
:icon-only? true
:customization-color customization-color
:on-press on-press}
icon])
(defn- right-tag
[{:keys [theme blur? on-press icon label]
:or {icon :i/placeholder}}]
(let [labelled? (not (string/blank? label))]
[tag/tag
{:accessibility-label :standard-title-tag
:size 32
:type :icon
:resource icon
:on-press on-press
:labelled? labelled?
:label (when labelled? label)
:blurred? blur?
:icon-color (style/right-tag-icon-color blur? theme)}]))
(defn- view-internal
[{:keys [title right] :as props}]
[rn/view {:style style/container}
[text/text {:size :heading-1 :weight :semi-bold}
title]
(when right
[rn/view {:style style/right-container}
(case right
:counter [right-counter props]
:action [right-action props]
:tag [right-tag props]
nil)])])
(def view (quo.theme/with-theme view-internal))
@@ -9,8 +9,3 @@
(def description-description-text
{:margin-top 8})
(def emoji-hash
{:margin-top 8
:letter-spacing 0.5
:line-height 20.5})

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