Compare commits
2
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e7c701b90 | ||
|
|
f05261a1e9 |
@@ -26,7 +26,6 @@
|
||||
malli.generator malli.generator
|
||||
malli.transform malli.transform
|
||||
malli.util malli.util
|
||||
promesa.core p
|
||||
schema.core schema
|
||||
status-im.feature-flags ff
|
||||
taoensso.timbre log}}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
{:lint-as {promesa.core/-> clojure.core/->
|
||||
promesa.core/->> clojure.core/->>
|
||||
promesa.core/as-> clojure.core/as->
|
||||
promesa.core/let clojure.core/let
|
||||
promesa.core/plet clojure.core/let
|
||||
promesa.core/loop clojure.core/loop
|
||||
promesa.core/recur clojure.core/recur
|
||||
promesa.core/with-redefs clojure.core/with-redefs
|
||||
promesa.core/doseq clojure.core/doseq}}
|
||||
@@ -34,4 +34,3 @@ STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
TEST_STATEOFUS=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||
FLAG_NEW_CONTACT_UI_ENABLED=0
|
||||
|
||||
@@ -22,37 +22,34 @@
|
||||
:multi-lhs-hang]
|
||||
|
||||
:fn-map
|
||||
{"reg-sub" :arg1-pair
|
||||
"h/describe" :arg1-body
|
||||
"h/describe-skip" :arg1-body
|
||||
"h/describe-only" :arg1-body
|
||||
"h/test" :arg1-body
|
||||
"h/test-skip" :arg1-body
|
||||
"h/test-only" :arg1-body
|
||||
"test/async" :arg1-body
|
||||
"test/use-fixtures" :arg1-body
|
||||
"global.describe" :arg1-body
|
||||
"global.test" :arg1-body
|
||||
"list-comp" :binding
|
||||
"defview" :arg1-body
|
||||
"letsubs" :binding
|
||||
"with-let" "let"
|
||||
"reg-event-fx" :arg1-pair
|
||||
"reg-fx" :arg1-pair
|
||||
"testing" :arg1-body
|
||||
"deftest-sub" :arg1-body
|
||||
"h/integration-test" :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?]]}]
|
||||
"set!" "reset!"
|
||||
"assoc-when" "assoc"
|
||||
"assoc-some" "assoc"
|
||||
"conj-when" "conj"
|
||||
"conj-some" "conj"}
|
||||
{"reg-sub" :arg1-pair
|
||||
"h/describe" :arg1-body
|
||||
"h/describe-skip" :arg1-body
|
||||
"h/describe-only" :arg1-body
|
||||
"h/test" :arg1-body
|
||||
"h/test-skip" :arg1-body
|
||||
"h/test-only" :arg1-body
|
||||
"global.describe" :arg1-body
|
||||
"global.test" :arg1-body
|
||||
"list-comp" :binding
|
||||
"defview" :arg1-body
|
||||
"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?]]}]
|
||||
"set!" "reset!"
|
||||
"assoc-when" "assoc"
|
||||
"assoc-some" "assoc"
|
||||
"conj-when" "conj"
|
||||
"conj-some" "conj"}
|
||||
|
||||
:style-map
|
||||
{:no-comma {:map {:comma? false}}
|
||||
|
||||
@@ -359,7 +359,7 @@ test-watch-for-repl: ##@test Watch all Clojure tests and support REPL connection
|
||||
"until [ -f $$SHADOW_OUTPUT_TO ] ; do sleep 1 ; done ; node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO --repl"
|
||||
|
||||
test-unit: export SHADOW_OUTPUT_TO := target/unit_test/test.js
|
||||
test-unit: export SHADOW_NS_REGEXP := ^(?!tests\.integration-test)(?!tests\.contract-test).*-test$$
|
||||
test-unit: export SHADOW_NS_REGEXP := ^(?!tests\.integration-test)(?!tests-im\.contract-test).*-test$$
|
||||
test-unit: ##@test Run unit tests
|
||||
test-unit: _test-clojure
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ pipeline {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '20',
|
||||
artifactNumToKeepStr: '1',
|
||||
artifactNumToKeepStr: '10',
|
||||
))
|
||||
/* Allows combined build to copy */
|
||||
copyArtifactPermission('/status-mobile/*')
|
||||
|
||||
@@ -13,7 +13,7 @@ pipeline {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
artifactNumToKeepStr: '10',
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ pipeline {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ pipeline {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '20',
|
||||
artifactNumToKeepStr: '1',
|
||||
artifactNumToKeepStr: '10',
|
||||
))
|
||||
/* Allows combined build to copy */
|
||||
copyArtifactPermission('/status-mobile/*')
|
||||
|
||||
+2
-10
@@ -10,12 +10,12 @@ pipeline {
|
||||
options {
|
||||
timestamps()
|
||||
/* Prevent Jenkins jobs from running forever */
|
||||
timeout(time: 20, unit: 'MINUTES')
|
||||
timeout(time: 15, unit: 'MINUTES')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '20',
|
||||
artifactNumToKeepStr: '1',
|
||||
artifactNumToKeepStr: '10',
|
||||
))
|
||||
/* Abort old PR builds. */
|
||||
disableConcurrentBuilds(
|
||||
@@ -62,14 +62,6 @@ pipeline {
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Contract Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make test-contract 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('Integration Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
|
||||
@@ -29,11 +29,6 @@ pipeline {
|
||||
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
))
|
||||
}
|
||||
|
||||
stages {
|
||||
|
||||
@@ -47,11 +47,6 @@ pipeline {
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
timeout(time: 90, unit: 'MINUTES')
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
))
|
||||
}
|
||||
|
||||
stages {
|
||||
|
||||
@@ -28,11 +28,6 @@ pipeline {
|
||||
|
||||
options {
|
||||
disableConcurrentBuilds()
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -34,7 +34,6 @@ pipeline {
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '20',
|
||||
daysToKeepStr: '30',
|
||||
artifactNumToKeepStr: '1',
|
||||
))
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,7 @@
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
<true/>
|
||||
<key>com.apple.developer.nfc.readersession.iso7816.select-identifiers</key>
|
||||
<array>
|
||||
<string>A00000080400010101</string>
|
||||
|
||||
+136
-154
@@ -90,20 +90,20 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "cider/cider-nrepl/0.31.0/cider-nrepl-0.31.0",
|
||||
"path": "cider/cider-nrepl/0.25.3/cider-nrepl-0.25.3",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "1f28a4a834a7a46cf24def971b1a705a6795c73a",
|
||||
"sha256": "0h4pyzy8rzzh567khvimw2cs8jr640kqxgaxvbfx1s5yfp56fka2"
|
||||
"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"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -251,6 +251,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "c9ad4a0850ab676c5c64461a05ca524cdfff59f1",
|
||||
"sha256": "170rflxnqnah0265ik2aylmxkshyqbf2zas9bp2l32xqj9l6jsaf"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/errorprone/error_prone_annotations/2.15.0/error_prone_annotations-2.15.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -297,11 +306,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/google/javascript/closure-compiler-unshaded/v20230802/closure-compiler-unshaded-v20230802",
|
||||
"path": "com/google/javascript/closure-compiler-unshaded/v20230411/closure-compiler-unshaded-v20230411",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "0a2498a4d45bf5896042f31da0cd30c5e7b415af",
|
||||
"sha256": "0jvgqq0gnvm4jw2zac4677ds05klvsjalszdzcq3nw8g7fjyjv2x"
|
||||
"sha1": "2f5d7ab921f9cc07ffeb4e1c0f156f164c650eeb",
|
||||
"sha256": "0gphdrrhr88bcqa1scndachvhbayh7m11zm9hcsmvzn9bw72pabw"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -323,51 +332,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "c9ad4a0850ab676c5c64461a05ca524cdfff59f1",
|
||||
"sha256": "170rflxnqnah0265ik2aylmxkshyqbf2zas9bp2l32xqj9l6jsaf"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/taoensso/encore/3.68.0/encore-3.68.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "b098b58e27a7cf9ab5e46aedbb5ababc12805170",
|
||||
"sha256": "1i5bmm83y9wpgvl5h6ysjsw58qrqz4b4v5vqnsprq6f1pmakjfz2"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/taoensso/timbre/6.3.1/timbre-6.3.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "e1b04be262f38bbd9af8f1193b6b3f2c6a37129d",
|
||||
"sha256": "0p6rws5gpab5qldp739lyqvwdbak28vaxbjw2bg2slflkkahszc7"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/taoensso/truss/1.11.0/truss-1.11.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "4784f43191d5839448b58128bb455d62616086fd",
|
||||
"sha256": "16xqav4cv3cnfik2d8v3wn7zb2a97ybnrbp6v6nj8m1nmdhr16k7"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/taoensso/tufte/2.6.3/tufte-2.6.3",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "8862c6113ca743ebdcfa17bf4779a21fc08a7c7e",
|
||||
"sha256": "0i0wsv2g2hswgdik6zlgcs212clj1d7fvckxfcsmyfr0vvpc1dmd"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "commons-codec/commons-codec/1.15/commons-codec-1.15",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -404,6 +368,42 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/taoensso/encore/3.68.0/encore-3.68.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "b098b58e27a7cf9ab5e46aedbb5ababc12805170",
|
||||
"sha256": "1i5bmm83y9wpgvl5h6ysjsw58qrqz4b4v5vqnsprq6f1pmakjfz2"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/taoensso/timbre/6.3.1/timbre-6.3.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "e1b04be262f38bbd9af8f1193b6b3f2c6a37129d",
|
||||
"sha256": "0p6rws5gpab5qldp739lyqvwdbak28vaxbjw2bg2slflkkahszc7"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/taoensso/truss/1.11.0/truss-1.11.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "4784f43191d5839448b58128bb455d62616086fd",
|
||||
"sha256": "16xqav4cv3cnfik2d8v3wn7zb2a97ybnrbp6v6nj8m1nmdhr16k7"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "com/taoensso/tufte/2.6.3/tufte-2.6.3",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "8862c6113ca743ebdcfa17bf4779a21fc08a7c7e",
|
||||
"sha256": "0i0wsv2g2hswgdik6zlgcs212clj1d7fvckxfcsmyfr0vvpc1dmd"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "crypto-equality/crypto-equality/1.0.1/crypto-equality-1.0.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
@@ -449,15 +449,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "funcool/promesa/11.0.678/promesa-11.0.678",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "0ee1690ba74b2609c2d85b51edacad13046a18e2",
|
||||
"sha256": "1wif8nwdbpchwg56fz47ymjnflmva0fzy0bw1s6bacnac472pmza"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "hiccup/hiccup/1.0.5/hiccup-1.0.5",
|
||||
"host": "https://repo.clojars.org",
|
||||
@@ -513,11 +504,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "io/undertow/undertow-core/2.3.10.Final/undertow-core-2.3.10.Final",
|
||||
"path": "io/undertow/undertow-core/2.2.4.Final/undertow-core-2.2.4.Final",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "96d1d5ca6406a75a285b95ea8f4b39e0fb2d707e",
|
||||
"sha256": "1s1m5hfhmfr7jsp4bn4c6fhdbgiz72mz0a96494nyhfa0b4lql8l"
|
||||
"sha1": "78650b4029dd9280c4769d9425b5559f12cb83bf",
|
||||
"sha256": "1brpkd2l98byf76jga6hj5drv5sj2d93lxlq2xz0rxpqyqas1xm4"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -603,11 +594,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "nrepl/nrepl/0.9.0/nrepl-0.9.0",
|
||||
"path": "nrepl/nrepl/1.0.0/nrepl-1.0.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "49beada131959f08f9a20899affbd1b10c03a668",
|
||||
"sha256": "1phak0479s27ffw9wzz7pi8cqqs6ipsm15dhgw9szxxcfhx529qa"
|
||||
"sha1": "f47774c43493efdc879d36b95ebd67ea0d9c890a",
|
||||
"sha256": "1fx5ssmixgqmklliw0ng8fjz41kkhys56x8dbwv9yqrfzws9f2x3"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -620,15 +611,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "ea0a0475fb6dfcdcf48b30410fd9d4f5c80df07e",
|
||||
"sha256": "0mnj5v660qvmrsi1m6z0dnykw3df8f1213byzp45l2wqgbgk1dfs"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/apache/ant/ant/1.10.11/ant-1.10.11",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -639,11 +621,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/babashka/sci.impl.types/0.0.2/sci.impl.types-0.0.2",
|
||||
"host": "https://repo.clojars.org",
|
||||
"path": "org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "45a05ece33609c3ad26a6ea4e05130560da82306",
|
||||
"sha256": "0pwwqq11rcknpcwbwsbw7pgbgnd7hqiawn0r8yvk14qfwa6p7z46"
|
||||
"sha1": "ea0a0475fb6dfcdcf48b30410fd9d4f5c80df07e",
|
||||
"sha256": "0mnj5v660qvmrsi1m6z0dnykw3df8f1213byzp45l2wqgbgk1dfs"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -656,6 +638,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/babashka/sci.impl.types/0.0.2/sci.impl.types-0.0.2",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "45a05ece33609c3ad26a6ea4e05130560da82306",
|
||||
"sha256": "0pwwqq11rcknpcwbwsbw7pgbgnd7hqiawn0r8yvk14qfwa6p7z46"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -746,15 +737,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/google-closure-library-third-party/0.0-20230227-c7c0a541/google-closure-library-third-party-0.0-20230227-c7c0a541",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "f5ea82eb1309b81ada6a14371bb848323c65e38b",
|
||||
"sha256": "0jk9v4bfrxvz6wq1s86msry2mf47nwcjfplnn41yabqc44g82hva"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -764,6 +746,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/google-closure-library-third-party/0.0-20230227-c7c0a541/google-closure-library-third-party-0.0-20230227-c7c0a541",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "f5ea82eb1309b81ada6a14371bb848323c65e38b",
|
||||
"sha256": "0jk9v4bfrxvz6wq1s86msry2mf47nwcjfplnn41yabqc44g82hva"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -791,15 +782,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.analyzer.jvm/1.2.2/tools.analyzer.jvm-1.2.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "449691b55d7d526258ce02c69b4699f2897c494d",
|
||||
"sha256": "0phfs1z1scvdi00348zjh223xncmgrkmlrnbca4dh7lk701gy34i"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -809,6 +791,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.analyzer.jvm/1.2.2/tools.analyzer.jvm-1.2.2",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "449691b55d7d526258ce02c69b4699f2897c494d",
|
||||
"sha256": "0phfs1z1scvdi00348zjh223xncmgrkmlrnbca4dh7lk701gy34i"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.cli/1.0.206/tools.cli-1.0.206",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
@@ -837,11 +828,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/clojure/tools.reader/1.3.7/tools.reader-1.3.7",
|
||||
"path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "c60dfd3d79cbc5ec6264ba45c14b8d4c9b6708b2",
|
||||
"sha256": "1mr0qx3gw1myfls07vrx3arwsi5n95b2lwk74ijpj0z3lzpzlj7m"
|
||||
"sha1": "927809dcb44fa726e4969d993e3e733636d95ebb",
|
||||
"sha256": "1q5q7fmshybvp55f6qys8i5sbzfaix5v9f9b55dkbhv55hgv7l8i"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -855,38 +846,38 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jboss/logging/jboss-logging/3.4.3.Final/jboss-logging-3.4.3.Final",
|
||||
"path": "org/jboss/logging/jboss-logging/3.4.1.Final/jboss-logging-3.4.1.Final",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "c4bd7e12a745c0e7f6cf98c45cdcdf482fd827ea",
|
||||
"sha256": "0jdcziqbdzmah981zv3q88k2zrnclr2h1k3h3vjn002m9p54qchb"
|
||||
"sha1": "40fd4d696c55793e996d1ff3c475833f836c2498",
|
||||
"sha256": "1f7f4kjn3v6vibhgsr3k8hl0r2xq0c2rbcl82dx0bqg5jdyqgzlf"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jboss/threads/jboss-threads/3.5.0.Final/jboss-threads-3.5.0.Final",
|
||||
"path": "org/jboss/threads/jboss-threads/3.1.0.Final/jboss-threads-3.1.0.Final",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "dd23d4788b3eafe9597ef3fe028e46ceb293ba8d",
|
||||
"sha256": "1cchp54dw1578my27siim3h5jbf240aq8q6xd3z2b1ajgxxbcl71"
|
||||
"sha1": "9b260c0302f637a84a52d3d118214a3c59217615",
|
||||
"sha256": "0yc0p71y7yjhqjhkvqqi9xqgljavp3aslnik2k7dppbxnkrnlff9"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jboss/xnio/xnio-api/3.8.8.Final/xnio-api-3.8.8.Final",
|
||||
"path": "org/jboss/xnio/xnio-api/3.8.0.Final/xnio-api-3.8.0.Final",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "1ba9c8b9a8dea1c6cd656155943e6d4c2c631fa7",
|
||||
"sha256": "0wvqdcbardi55l77aw5404qgw70384hw155xvc66shn7l6z8h6bh"
|
||||
"sha1": "e2c29acf42ac6f42c34f0b74ba089e3f3d1b2394",
|
||||
"sha256": "041qnvb74bkgmfxyd23vdl26il55cmfbhi6a4bm3fcmyrpapjfjl"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/jboss/xnio/xnio-nio/3.8.8.Final/xnio-nio-3.8.8.Final",
|
||||
"path": "org/jboss/xnio/xnio-nio/3.8.0.Final/xnio-nio-3.8.0.Final",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "a5d2faf8d02e0a0bb9e9eabca8e38173cb640331",
|
||||
"sha256": "0pxw2iv1q1yzk39knc650rg4vflsyjzhf07mwm2s5aqn5h82sk3i"
|
||||
"sha1": "90c57dcf7f8c846b4da331d0e6e048c39842c92a",
|
||||
"sha256": "1zndnb5648wqw23gj80zjqk3yd8gq6grqhz9n4zrcqixx1z586jf"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -918,20 +909,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/slf4j/slf4j-api/2.0.9/slf4j-api-2.0.9",
|
||||
"path": "org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "7cf2726fdcfbc8610f9a71fb3ed639871f315340",
|
||||
"sha256": "0v1b7iydpnh2rvyzqvqbqm19vr2qva8icq84690bppnpr06r6608"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/slf4j/slf4j-nop/2.0.9/slf4j-nop-2.0.9",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "fa0627049304bf501bf6a0e4d1416bcaec9a72a9",
|
||||
"sha256": "10vdg9qkailjbzmf5mfnv328675swmnf1x3g9v7ymhxs29xkc4jn"
|
||||
"sha1": "6c62681a2f655b49963a5983b8b0950a6120ae14",
|
||||
"sha256": "1h512ry8g0nriazg3dqzs6s96502a77drw8vq26nfya97rg5gvyk"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -945,11 +927,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "org/wildfly/common/wildfly-common/1.5.4.Final/wildfly-common-1.5.4.Final",
|
||||
"path": "org/wildfly/common/wildfly-common/1.5.2.Final/wildfly-common-1.5.2.Final",
|
||||
"host": "https://repo1.maven.org/maven2",
|
||||
"jar": {
|
||||
"sha1": "735ceee5616d5143bac1bc740e444697073c002f",
|
||||
"sha256": "0sp48y3q7bmp3bjb7a6fpz8gb7ssizvxlw5wdv2xwa6mifpkrnlz"
|
||||
"sha1": "8eba40cfe86bcfcc223551e75201e6e7574c7c36",
|
||||
"sha256": "17rkkm9dqbxdzpamwl9jr8z285awsj6hzpavzmc87wcz9469hp5b"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -962,6 +944,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "reagent/reagent/1.2.0/reagent-1.2.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "1b9a181b5c7ed3557768d2ea0c66f5616aef5e97",
|
||||
"sha256": "0scvkzfqjs613z10rngh7427v3pxdqablf0fcl65pbpkzz16wgav"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "re-com/re-com/2.8.0/re-com-2.8.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
@@ -971,6 +962,15 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "6bc3441afc94f7ca024e41a864ca75e05df7e207",
|
||||
"sha256": "0w8hax99y98l53mixxzx2ja0vcnhjv8dnsaz1zj3vqk775ns5w6i"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "re-frame/re-frame/1.3.0/re-frame-1.3.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
@@ -998,24 +998,6 @@
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "reagent/reagent/1.2.0/reagent-1.2.0",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "1b9a181b5c7ed3557768d2ea0c66f5616aef5e97",
|
||||
"sha256": "0scvkzfqjs613z10rngh7427v3pxdqablf0fcl65pbpkzz16wgav"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "refactor-nrepl/refactor-nrepl/3.9.1/refactor-nrepl-3.9.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "f949af92dd1d6fef59d7447bd0cb62118e34eca1",
|
||||
"sha256": "0dml9yvjmji6xk2sk3cdmkvvnh13rw29szxxl363hap8yg28xcs1"
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"path": "ring-cors/ring-cors/0.1.8/ring-cors-0.1.8",
|
||||
"host": "https://repo.clojars.org",
|
||||
@@ -1053,11 +1035,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "thheller/shadow-cljs/2.26.2/shadow-cljs-2.26.2-aot",
|
||||
"path": "thheller/shadow-cljs/2.25.0/shadow-cljs-2.25.0-aot",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "ab6b31649cb03e352369698781207db4f6da6d5f",
|
||||
"sha256": "0mh28nykpillkym7hvplrr7vy5hn6a2ymafyf4yfl5y2kfx4yq42"
|
||||
"sha1": "013921db91ce4a3616aec9c72c1832a014a0fece",
|
||||
"sha256": "0ks380z7h8i2ylirvjgmlicq9jjpz9w71gjv521h4xs5fb273cl0"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -1071,11 +1053,11 @@
|
||||
},
|
||||
|
||||
{
|
||||
"path": "thheller/shadow-undertow/0.3.3/shadow-undertow-0.3.3",
|
||||
"path": "thheller/shadow-undertow/0.3.1/shadow-undertow-0.3.1",
|
||||
"host": "https://repo.clojars.org",
|
||||
"jar": {
|
||||
"sha1": "ba377c3b70fd942b3ca7e38f055412a441626711",
|
||||
"sha256": "10w2slj4znm93j0qq3ldj9hj0i7a50vbnmn6kv8i77fakikdjc48"
|
||||
"sha1": "9be444bea4037bb80b451cc52a8e80359c4c45be",
|
||||
"sha256": "174s2rdxvp7d4jg9kvzjadps42bdsbi05rs2pjy5i0ssq9n23zwa"
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
+25
-27
@@ -8,8 +8,8 @@ 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.31.0/cider-nrepl-0.31.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
|
||||
@@ -26,36 +26,35 @@ com/github/javaparser/javaparser-core/3.25.3/javaparser-core-3.25.3.jar
|
||||
com/google/auto/value/auto-value-annotations/1.6/auto-value-annotations-1.6.jar
|
||||
com/google/code/findbugs/jsr305/3.0.2/jsr305-3.0.2.jar
|
||||
com/google/code/gson/gson/2.9.1/gson-2.9.1.jar
|
||||
com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar
|
||||
com/google/errorprone/error_prone_annotations/2.15.0/error_prone_annotations-2.15.0.jar
|
||||
com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.jar
|
||||
com/google/guava/guava/31.0.1-jre/guava-31.0.1-jre.jar
|
||||
com/google/guava/listenablefuture/9999.0-empty-to-avoid-conflict-with-guava/listenablefuture-9999.0-empty-to-avoid-conflict-with-guava.jar
|
||||
com/google/j2objc/j2objc-annotations/1.3/j2objc-annotations-1.3.jar
|
||||
com/google/javascript/closure-compiler-unshaded/v20230802/closure-compiler-unshaded-v20230802.jar
|
||||
com/google/javascript/closure-compiler-unshaded/v20230411/closure-compiler-unshaded-v20230411.jar
|
||||
com/google/protobuf/protobuf-java/3.21.12/protobuf-java-3.21.12.jar
|
||||
com/google/re2j/re2j/1.3/re2j-1.3.jar
|
||||
com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar
|
||||
com/taoensso/encore/3.68.0/encore-3.68.0.jar
|
||||
com/taoensso/timbre/6.3.1/timbre-6.3.1.jar
|
||||
com/taoensso/truss/1.11.0/truss-1.11.0.jar
|
||||
com/taoensso/tufte/2.6.3/tufte-2.6.3.jar
|
||||
commons-codec/commons-codec/1.15/commons-codec-1.15.jar
|
||||
commons-fileupload/commons-fileupload/1.4/commons-fileupload-1.4.jar
|
||||
commons-io/commons-io/2.11.0/commons-io-2.11.0.jar
|
||||
compojure/compojure/1.5.2/compojure-1.5.2.jar
|
||||
com/taoensso/encore/3.68.0/encore-3.68.0.jar
|
||||
com/taoensso/timbre/6.3.1/timbre-6.3.1.jar
|
||||
com/taoensso/truss/1.11.0/truss-1.11.0.jar
|
||||
com/taoensso/tufte/2.6.3/tufte-2.6.3.jar
|
||||
crypto-equality/crypto-equality/1.0.1/crypto-equality-1.0.1.jar
|
||||
crypto-random/crypto-random/1.2.1/crypto-random-1.2.1.jar
|
||||
day8/re-frame/test/0.1.5/test-0.1.5.jar
|
||||
expound/expound/0.9.0/expound-0.9.0.jar
|
||||
fipp/fipp/0.6.26/fipp-0.6.26.jar
|
||||
funcool/promesa/11.0.678/promesa-11.0.678.jar
|
||||
hiccup/hiccup/1.0.5/hiccup-1.0.5.jar
|
||||
http-kit/http-kit/2.2.0/http-kit-2.2.0.jar
|
||||
instaparse/instaparse/1.4.0/instaparse-1.4.0.jar
|
||||
io/aviso/pretty/1.4.4/pretty-1.4.4.jar
|
||||
io/methvin/directory-watcher/0.17.1/directory-watcher-0.17.1.jar
|
||||
io/replikativ/datalog-parser/0.2.25/datalog-parser-0.2.25.jar
|
||||
io/undertow/undertow-core/2.3.10.Final/undertow-core-2.3.10.Final.jar
|
||||
io/undertow/undertow-core/2.2.4.Final/undertow-core-2.2.4.Final.jar
|
||||
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
|
||||
@@ -65,12 +64,12 @@ 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/0.9.0/nrepl-0.9.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-launcher/1.10.11/ant-launcher-1.10.11.jar
|
||||
org/apache/ant/ant/1.10.11/ant-1.10.11.jar
|
||||
org/babashka/sci.impl.types/0.0.2/sci.impl.types-0.0.2.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
|
||||
org/babashka/sci.impl.types/0.0.2/sci.impl.types-0.0.2.jar
|
||||
org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0.jar
|
||||
org/clojure/clojure/1.11.1/clojure-1.11.1.jar
|
||||
org/clojure/clojurescript/1.11.60/clojurescript-1.11.60.jar
|
||||
@@ -81,42 +80,41 @@ org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.jar
|
||||
org/clojure/core.specs.alpha/0.2.62/core.specs.alpha-0.2.62.jar
|
||||
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-third-party/0.0-20230227-c7c0a541/google-closure-library-third-party-0.0-20230227-c7c0a541.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.jvm/1.2.2/tools.analyzer.jvm-1.2.2.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
|
||||
org/clojure/tools.logging/1.1.0/tools.logging-1.1.0.jar
|
||||
org/clojure/tools.macro/0.1.5/tools.macro-0.1.5.jar
|
||||
org/clojure/tools.reader/1.3.7/tools.reader-1.3.7.jar
|
||||
org/clojure/tools.reader/1.3.6/tools.reader-1.3.6.jar
|
||||
org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.jar
|
||||
org/jboss/logging/jboss-logging/3.4.3.Final/jboss-logging-3.4.3.Final.jar
|
||||
org/jboss/threads/jboss-threads/3.5.0.Final/jboss-threads-3.5.0.Final.jar
|
||||
org/jboss/xnio/xnio-api/3.8.8.Final/xnio-api-3.8.8.Final.jar
|
||||
org/jboss/xnio/xnio-nio/3.8.8.Final/xnio-nio-3.8.8.Final.jar
|
||||
org/jboss/logging/jboss-logging/3.4.1.Final/jboss-logging-3.4.1.Final.jar
|
||||
org/jboss/threads/jboss-threads/3.1.0.Final/jboss-threads-3.1.0.Final.jar
|
||||
org/jboss/xnio/xnio-api/3.8.0.Final/xnio-api-3.8.0.Final.jar
|
||||
org/jboss/xnio/xnio-nio/3.8.0.Final/xnio-nio-3.8.0.Final.jar
|
||||
org/jspecify/jspecify/0.2.0/jspecify-0.2.0.jar
|
||||
org/msgpack/msgpack/0.6.12/msgpack-0.6.12.jar
|
||||
org/ow2/asm/asm/9.4/asm-9.4.jar
|
||||
org/slf4j/slf4j-api/2.0.9/slf4j-api-2.0.9.jar
|
||||
org/slf4j/slf4j-nop/2.0.9/slf4j-nop-2.0.9.jar
|
||||
org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36.jar
|
||||
org/wildfly/client/wildfly-client-config/1.0.1.Final/wildfly-client-config-1.0.1.Final.jar
|
||||
org/wildfly/common/wildfly-common/1.5.4.Final/wildfly-common-1.5.4.Final.jar
|
||||
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
|
||||
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
|
||||
reagent/reagent/1.2.0/reagent-1.2.0.jar
|
||||
refactor-nrepl/refactor-nrepl/3.9.1/refactor-nrepl-3.9.1.jar
|
||||
ring-cors/ring-cors/0.1.8/ring-cors-0.1.8.jar
|
||||
ring/ring-codec/1.2.0/ring-codec-1.2.0.jar
|
||||
ring/ring-core/1.9.6/ring-core-1.9.6.jar
|
||||
thheller/shadow-client/1.3.3/shadow-client-1.3.3.jar
|
||||
thheller/shadow-cljs/2.26.2/shadow-cljs-2.26.2-aot.jar
|
||||
thheller/shadow-cljs/2.25.0/shadow-cljs-2.25.0-aot.jar
|
||||
thheller/shadow-cljsjs/0.0.22/shadow-cljsjs-0.0.22.jar
|
||||
thheller/shadow-undertow/0.3.3/shadow-undertow-0.3.3.jar
|
||||
thheller/shadow-undertow/0.3.1/shadow-undertow-0.3.1.jar
|
||||
thheller/shadow-util/0.7.0/shadow-util-0.7.0.jar
|
||||
tigris/tigris/0.1.2/tigris-0.1.2.jar
|
||||
|
||||
@@ -10,7 +10,6 @@
|
||||
[com.cognitect/transit-cljs "0.8.280"]
|
||||
[camel-snake-kebab "0.4.3"]
|
||||
[metosin/malli "0.13.0"]
|
||||
[funcool/promesa "11.0.678"]
|
||||
|
||||
;; Dev dependencies
|
||||
[refactor-nrepl "3.9.1"]
|
||||
|
||||
@@ -72,3 +72,18 @@
|
||||
{:events [:show-tooltip]}
|
||||
[_ tooltip-id]
|
||||
{:show-tooltip tooltip-id})
|
||||
|
||||
(rf/defn show-profile
|
||||
{:events [:chat.ui/show-profile]}
|
||||
[{:keys [db]} identity ens-name]
|
||||
(let [my-public-key (get-in db [:profile/profile :public-key])]
|
||||
(if (not= my-public-key identity)
|
||||
{:db (-> db
|
||||
(assoc :contacts/identity identity)
|
||||
(assoc :contacts/ens-name ens-name))
|
||||
:dispatch [:contacts/build-contact
|
||||
{:pubkey identity
|
||||
:ens ens-name
|
||||
:success-fn (fn [_]
|
||||
{:dispatch [:open-modal :profile]})}]}
|
||||
{:dispatch [:navigate-to :my-profile]})))
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
current-fleet
|
||||
webview-debug
|
||||
test-networks-enabled?
|
||||
is-goerli-enabled?
|
||||
peer-syncing-enabled?]}]
|
||||
is-goerli-enabled?]}]
|
||||
(keep
|
||||
identity
|
||||
[{:size :small
|
||||
@@ -29,7 +28,7 @@
|
||||
:accessibility-label :network-button
|
||||
:container-margin-top 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:open-modal :network-settings])
|
||||
#(re-frame/dispatch [:navigate-to :network-settings])
|
||||
:accessory :text
|
||||
:accessory-text network-name
|
||||
:chevron true}
|
||||
@@ -38,13 +37,13 @@
|
||||
:accessibility-label :network-button
|
||||
:container-margin-top 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:open-modal :network-info])
|
||||
#(re-frame/dispatch [:navigate-to :network-info])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/log-level)
|
||||
:accessibility-label :log-level-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:open-modal :log-level-settings])
|
||||
#(re-frame/dispatch [:navigate-to :log-level-settings])
|
||||
:accessory :text
|
||||
:accessory-text current-log-level
|
||||
:chevron true}
|
||||
@@ -52,7 +51,7 @@
|
||||
:title (i18n/label :t/fleet)
|
||||
:accessibility-label :fleet-settings-button
|
||||
:on-press
|
||||
#(re-frame/dispatch [:open-modal :fleet-settings])
|
||||
#(re-frame/dispatch [:navigate-to :fleet-settings])
|
||||
:accessory :text
|
||||
:accessory-text current-fleet
|
||||
:chevron true}
|
||||
@@ -67,14 +66,14 @@
|
||||
:accessibility-label :rpc-usage-info
|
||||
:container-margin-top 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:open-modal :rpc-usage-info])
|
||||
#(re-frame/dispatch [:navigate-to :rpc-usage-info])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/peers-stats)
|
||||
:accessibility-label :peers-stats
|
||||
:container-margin-top 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:open-modal :peers-stats])
|
||||
#(re-frame/dispatch [:navigate-to :peers-stats])
|
||||
:chevron true}
|
||||
{:size :small
|
||||
:title (i18n/label :t/light-client-enabled)
|
||||
@@ -120,19 +119,11 @@
|
||||
#(re-frame/dispatch [:profile.settings/toggle-goerli-test-network])
|
||||
:accessory :switch
|
||||
:active is-goerli-enabled?}
|
||||
{:size :small
|
||||
:title "Peer syncing"
|
||||
:accessibility-label :peer-syncing
|
||||
:container-margin-bottom 8
|
||||
:on-press
|
||||
#(re-frame/dispatch [:profile.settings/toggle-peer-syncing])
|
||||
:accessory :switch
|
||||
:active peer-syncing-enabled?}
|
||||
{:size :small
|
||||
:title (i18n/label :t/set-currency)
|
||||
:accessibility-label :wallet-change-currency
|
||||
:on-press #(hide-sheet-and-dispatch
|
||||
[:open-modal :currency-settings])
|
||||
[:navigate-to :currency-settings])
|
||||
:chevron true}]))
|
||||
|
||||
(defn- flat-list-data
|
||||
@@ -154,8 +145,7 @@
|
||||
network-name [:network-name]
|
||||
transactions-management-enabled? [:wallet-legacy/transactions-management-enabled?]
|
||||
current-log-level [:log-level/current-log-level]
|
||||
current-fleet [:fleets/current-fleet]
|
||||
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
|
||||
current-fleet [:fleets/current-fleet]]
|
||||
[list/flat-list
|
||||
{:data (flat-list-data
|
||||
{:network-name network-name
|
||||
@@ -166,7 +156,6 @@
|
||||
:dev-mode? false
|
||||
:webview-debug webview-debug
|
||||
:test-networks-enabled? test-networks-enabled?
|
||||
:is-goerli-enabled? is-goerli-enabled?
|
||||
:peer-syncing-enabled? peer-syncing-enabled?})
|
||||
:is-goerli-enabled? is-goerli-enabled?})
|
||||
:key-fn (fn [_ i] (str i))
|
||||
:render-fn render-item}]))
|
||||
|
||||
@@ -8,6 +8,24 @@
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn local-notifications
|
||||
[]
|
||||
(let [{:keys [enabled?]} (rf/sub [:push-notifications/wallet-transactions])
|
||||
{:keys [notifications-enabled?]} (rf/sub [:profile/profile])]
|
||||
[:<>
|
||||
[quo/separator
|
||||
{:color (:ui-02 @colors/theme)
|
||||
:style {:margin-vertical 8}}]
|
||||
[quo/list-header (i18n/label :t/local-notifications)]
|
||||
[list.item/list-item
|
||||
{:size :small
|
||||
:title (i18n/label :t/notifications-transactions)
|
||||
:accessibility-label :notifications-button
|
||||
:active (and notifications-enabled? enabled?)
|
||||
:on-press #(rf/dispatch [:push-notifications.wallet/switch-transactions
|
||||
(not enabled?)])
|
||||
:accessory :switch}]]))
|
||||
|
||||
(defn notifications-settings-ios
|
||||
[]
|
||||
(let [{:keys [notifications-enabled?
|
||||
@@ -45,7 +63,8 @@
|
||||
:on-press #(rf/dispatch
|
||||
[:push-notifications/switch-block-mentions
|
||||
(not push-notifications-block-mentions?)])
|
||||
:accessory :switch}]]))
|
||||
:accessory :switch}]
|
||||
[local-notifications]]))
|
||||
|
||||
(defn notifications-settings-android
|
||||
[]
|
||||
@@ -57,7 +76,8 @@
|
||||
:subtitle (i18n/label :t/local-notifications-subtitle)
|
||||
:active notifications-enabled?
|
||||
:on-press #(rf/dispatch [:push-notifications/switch (not notifications-enabled?)])
|
||||
:accessory :switch}]]))
|
||||
:accessory :switch}]
|
||||
[local-notifications]]))
|
||||
|
||||
(defn notifications-settings
|
||||
[]
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
:chevron true
|
||||
:icon :main-icons/username}
|
||||
registrar
|
||||
(assoc :on-press #(re-frame/dispatch [:open-modal :ens-main registrar])))]
|
||||
(assoc :on-press #(re-frame/dispatch [:navigate-to :ens-main registrar])))]
|
||||
[list.item/list-item
|
||||
{:title (i18n/label :t/contacts)
|
||||
:icon :main-icons/in-contacts
|
||||
@@ -112,7 +112,7 @@
|
||||
(str active-contacts-count)
|
||||
(i18n/label :t/none))
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :contacts-list])}]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :contacts-list])}]
|
||||
[react/view {:padding-top 16}
|
||||
[quo/list-header (i18n/label :t/settings)]]
|
||||
[list.item/list-item
|
||||
@@ -122,71 +122,71 @@
|
||||
:chevron true
|
||||
:accessory (when mnemonic
|
||||
[components.common/counter {:size 22} 1])
|
||||
:on-press #(re-frame/dispatch [:open-modal :privacy-and-security])}]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :privacy-and-security])}]
|
||||
(when config/quo-preview-enabled?
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/appearance
|
||||
:title "Quo Preview"
|
||||
:accessibility-label :appearance-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :quo-preview])}])
|
||||
: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 [:open-modal :status-im-preview])}])
|
||||
:on-press #(re-frame/dispatch [:navigate-to :status-im-preview])}])
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/appearance
|
||||
:title (i18n/label :t/appearance)
|
||||
:accessibility-label :appearance-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :appearance])}]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :appearance])}]
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/notification
|
||||
:title (i18n/label :t/notifications)
|
||||
:accessibility-label :notifications-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :notifications])}]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :notifications])}]
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/mobile
|
||||
:title (i18n/label :t/sync-settings)
|
||||
:accessibility-label :sync-settings-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :sync-settings])}]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :sync-settings])}]
|
||||
(when keycard-pairing
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/keycard
|
||||
:title (i18n/label :t/keycard)
|
||||
:accessibility-label :keycard-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :keycard-settings])}])
|
||||
:on-press #(re-frame/dispatch [:navigate-to :keycard-settings])}])
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/settings-advanced
|
||||
:title (i18n/label :t/advanced)
|
||||
:accessibility-label :advanced-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :advanced-settings])}]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :advanced-settings])}]
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/help
|
||||
:title (i18n/label :t/need-help)
|
||||
:accessibility-label :help-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :help-center])}]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :help-center])}]
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/info
|
||||
:title (i18n/label :t/about-app)
|
||||
:accessibility-label :about-button
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :about-app])}]
|
||||
:on-press #(re-frame/dispatch [:navigate-to :about-app])}]
|
||||
(when local-pairing-mode-enabled?
|
||||
[list.item/list-item
|
||||
{:icon :i/mobile
|
||||
:title (i18n/label :t/syncing)
|
||||
:accessibility-label :syncing
|
||||
:chevron true
|
||||
:on-press #(re-frame/dispatch [:open-modal :settings-syncing])}])
|
||||
:on-press #(re-frame/dispatch [:navigate-to :settings-syncing])}])
|
||||
[react/view {:padding-vertical 24}
|
||||
[list.item/list-item
|
||||
{:icon :main-icons/log-out
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
:FlatList {}
|
||||
:SectionList {}
|
||||
:Text {}
|
||||
:StatusBar {:setBarStyle identity}
|
||||
:StatusBar {}
|
||||
:ScrollView {}
|
||||
:SafeAreaView {}
|
||||
:KeyboardAvoidingView {}
|
||||
|
||||
@@ -106,32 +106,6 @@ The convention is `:size-<number>`, e.g size `20` is `:size-20`
|
||||
- Try to make all other vars private because they should almost never be used
|
||||
directly.
|
||||
|
||||
## Default value when destructuring
|
||||
|
||||
Too often callers pass nil values because values can be wrapped in a `when` for example.
|
||||
In this case, the default value is not applied, because :or macro will use default only when the value is absent.
|
||||
Instead, use `(or (:value props) some-default-value)` in a `let` expression or as a parameter value.
|
||||
|
||||
```clojure
|
||||
;; bad (unreliable)
|
||||
(defn- view-internal
|
||||
[{:keys [auto-focus?
|
||||
init-value
|
||||
return-key-type]
|
||||
:or {auto-focus? false
|
||||
init-value 0
|
||||
return-key-type :done}}]
|
||||
...)
|
||||
|
||||
;; good
|
||||
(defn- view-internal
|
||||
[{:keys [theme size something] :as props}]
|
||||
(let [auto-focus? (or (:auto-focus? props) false)
|
||||
init-value (or (:init-value props) 0)
|
||||
return-key-type (or (:return-key-type props) :done)]
|
||||
...))
|
||||
```
|
||||
|
||||
## Component tests
|
||||
|
||||
We don't attempt to write component tests verifying how components look on the
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]))
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn remove-http-https-www
|
||||
[value]
|
||||
@@ -67,86 +68,78 @@
|
||||
[:cursor-color :placeholder-text-color :editable :on-change-text :on-focus
|
||||
:on-blur :on-clear :value :disabled? :blur? :customization-color :theme])
|
||||
|
||||
(defn view
|
||||
[{:keys [disabled? blur? on-change-text customization-color
|
||||
on-clear on-focus on-blur get-ref locked?
|
||||
favicon favicon-color favicon-size default-value]
|
||||
:or {default-value ""}
|
||||
:as props}]
|
||||
(let [ref (rn/use-ref-atom nil)
|
||||
on-ref (rn/use-callback
|
||||
(fn [r]
|
||||
(reset! ref r)
|
||||
(when get-ref (get-ref r)))
|
||||
[get-ref])
|
||||
theme (quo.theme/use-theme)
|
||||
[state set-state] (rn/use-state :default)
|
||||
[value set-value] (rn/use-state default-value)
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(.clear ^js @ref)
|
||||
(set-value "")
|
||||
(when on-clear (on-clear)))
|
||||
[on-clear])
|
||||
focus-input (rn/use-callback
|
||||
(fn []
|
||||
(set-state :active)
|
||||
(.focus ^js @ref)))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(set-state :default)
|
||||
(when on-blur (on-blur)))
|
||||
[on-blur])
|
||||
on-change-text (rn/use-callback
|
||||
(fn [new-text]
|
||||
(set-value new-text)
|
||||
(when on-change-text (on-change-text new-text)))
|
||||
[on-change-text])
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(set-state :active)
|
||||
(when on-focus (on-focus)))
|
||||
[on-focus])
|
||||
clean-props (apply dissoc props props-to-remove)]
|
||||
[rn/view {:style style/root-container}
|
||||
(when (and (seq value) (= state :default))
|
||||
[rn/touchable-opacity
|
||||
{:style style/default-container
|
||||
:on-press focus-input}
|
||||
(when favicon
|
||||
[icon/icon favicon
|
||||
{:accessibility-label :browser-input-favicon
|
||||
:color favicon-color
|
||||
:container-style style/favicon-icon-container
|
||||
:size favicon-size}])
|
||||
[rn/text
|
||||
{:accessibility-label :browser-input-label
|
||||
:style (style/text)}
|
||||
(remove-http-https-www value)]
|
||||
(when locked?
|
||||
[lock-icon {:blur? blur? :theme theme}])])
|
||||
[rn/view {:style (style/active-container (or (empty? value) (= state :active)))}
|
||||
[rn/text-input
|
||||
(merge
|
||||
clean-props
|
||||
{:accessibility-label :browser-input
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
:cursor-color (cursor-color customization-color theme)
|
||||
:editable (not disabled?)
|
||||
:keyboard-appearance (colors/theme-colors :light :dark theme)
|
||||
:keyboard-type :web-search
|
||||
:on-blur on-blur
|
||||
:on-change-text on-change-text
|
||||
:on-focus on-focus
|
||||
:placeholder-text-color (placeholder-color state blur? theme)
|
||||
:ref on-ref
|
||||
:selection-color (when platform/ios?
|
||||
(cursor-color customization-color theme))
|
||||
:select-text-on-focus true
|
||||
:style (style/input disabled?)})]
|
||||
(when (seq value)
|
||||
[clear-button
|
||||
{:blur? blur?
|
||||
:on-press on-clear
|
||||
:theme theme}])]]))
|
||||
(defn- view-internal
|
||||
[{:keys [default-value]
|
||||
:or {default-value ""}}]
|
||||
(let [state (reagent/atom :default)
|
||||
value (reagent/atom default-value)
|
||||
set-active #(reset! state :active)
|
||||
set-default #(reset! state :default)
|
||||
set-value #(reset! value %)
|
||||
ref (atom nil)
|
||||
clear-input (fn []
|
||||
(.clear ^js @ref)
|
||||
(reset! value ""))
|
||||
focus-input (fn []
|
||||
(set-active)
|
||||
(.focus ^js @ref))]
|
||||
(fn [{:keys [disabled? blur? on-change-text customization-color
|
||||
on-clear on-focus on-blur theme get-ref locked?
|
||||
favicon favicon-color favicon-size]
|
||||
:as props}]
|
||||
(let [clean-props (apply dissoc props props-to-remove)]
|
||||
[rn/view {:style style/root-container}
|
||||
(when (and (seq @value) (= @state :default))
|
||||
[rn/touchable-opacity
|
||||
{:style style/default-container
|
||||
:on-press focus-input}
|
||||
(when favicon
|
||||
[icon/icon favicon
|
||||
{:accessibility-label :browser-input-favicon
|
||||
:color favicon-color
|
||||
:container-style style/favicon-icon-container
|
||||
:size favicon-size}])
|
||||
[rn/text
|
||||
{:accessibility-label :browser-input-label
|
||||
:style (style/text)} (remove-http-https-www @value)]
|
||||
(when locked?
|
||||
[lock-icon
|
||||
{:blur? blur?
|
||||
:theme theme}])])
|
||||
[rn/view {:style (style/active-container (or (empty? @value) (= @state :active)))}
|
||||
[rn/text-input
|
||||
(merge
|
||||
clean-props
|
||||
{:accessibility-label :browser-input
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
:cursor-color (cursor-color customization-color theme)
|
||||
:editable (not disabled?)
|
||||
:keyboard-appearance (colors/theme-colors :light :dark theme)
|
||||
:keyboard-type :web-search
|
||||
:on-blur (fn []
|
||||
(set-default)
|
||||
(when on-blur (on-blur)))
|
||||
:on-change-text (fn [new-text]
|
||||
(set-value new-text)
|
||||
(when on-change-text (on-change-text new-text)))
|
||||
:on-focus (fn []
|
||||
(set-active)
|
||||
(when on-focus (on-focus)))
|
||||
:placeholder-text-color (placeholder-color @state blur? theme)
|
||||
:ref (fn [r]
|
||||
(reset! ref r)
|
||||
(when get-ref (get-ref r)))
|
||||
:selection-color (when platform/ios?
|
||||
(cursor-color customization-color theme))
|
||||
:select-text-on-focus true
|
||||
:style (style/input disabled?)})]
|
||||
(when (seq @value)
|
||||
[clear-button
|
||||
{:blur? blur?
|
||||
:on-press (fn []
|
||||
(clear-input)
|
||||
(when on-clear (on-clear)))
|
||||
:theme theme}])]]))))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
[quo.foundations.customization-colors :as customization-colors]
|
||||
[quo.theme :as theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn button
|
||||
(defn- button-internal
|
||||
"with label
|
||||
[button opts \"label\"]
|
||||
opts
|
||||
@@ -28,103 +29,102 @@
|
||||
:theme :light/:dark
|
||||
only icon
|
||||
[button {:icon-only? true} :i/close-circle]"
|
||||
[{:keys [on-press on-long-press disabled? type background size icon-left icon-right icon-top
|
||||
customization-color accessibility-label icon-only? container-style inner-style
|
||||
pressed? on-press-in on-press-out allow-multiple-presses?]
|
||||
:or {type :primary
|
||||
size 40
|
||||
customization-color (if (= type :primary) :blue nil)}}
|
||||
children]
|
||||
(let [[pressed-state? set-pressed-state] (rn/use-state false)
|
||||
theme (theme/use-theme-value)
|
||||
{:keys [icon-color background-color label-color border-color blur-type
|
||||
blur-overlay-color border-radius overlay-customization-color]}
|
||||
(button-properties/get-values {:customization-color customization-color
|
||||
:background background
|
||||
:type type
|
||||
:theme theme
|
||||
:pressed? (if pressed? pressed? pressed-state?)
|
||||
:icon-only? icon-only?})
|
||||
icon-size (when (= 24 size) 12)
|
||||
on-press-in-cb (rn/use-callback
|
||||
(fn []
|
||||
(set-pressed-state true)
|
||||
(when on-press-in (on-press-in))))
|
||||
on-press-out-cb (rn/use-callback
|
||||
(fn []
|
||||
(set-pressed-state nil)
|
||||
(when on-press-out (on-press-out))))]
|
||||
[rn/touchable-without-feedback
|
||||
{:disabled disabled?
|
||||
:accessibility-label accessibility-label
|
||||
:on-press-in on-press-in-cb
|
||||
:on-press-out on-press-out-cb
|
||||
:on-press on-press
|
||||
:allow-multiple-presses? allow-multiple-presses?
|
||||
:on-long-press on-long-press}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/shape-style-container size border-radius)
|
||||
container-style)}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/style-container {:size size
|
||||
:disabled? disabled?
|
||||
:border-radius border-radius
|
||||
:background-color background-color
|
||||
:border-color border-color
|
||||
:icon-only? icon-only?
|
||||
:icon-top icon-top
|
||||
:icon-left icon-left
|
||||
:icon-right icon-right})
|
||||
inner-style)}
|
||||
(when overlay-customization-color
|
||||
[customization-colors/overlay
|
||||
{:customization-color overlay-customization-color
|
||||
:theme theme
|
||||
:pressed? (if pressed? pressed? pressed-state?)}])
|
||||
(when (= background :photo)
|
||||
[blur/view
|
||||
{:blur-radius 20
|
||||
:blur-type blur-type
|
||||
:overlay-color blur-overlay-color
|
||||
:style style/blur-view}])
|
||||
(when icon-top
|
||||
[_ _]
|
||||
(let [pressed-state? (reagent/atom false)]
|
||||
(fn
|
||||
[{:keys [on-press on-long-press disabled? type background size icon-left icon-right icon-top
|
||||
customization-color theme accessibility-label icon-only? container-style inner-style
|
||||
pressed? on-press-in on-press-out allow-multiple-presses?]
|
||||
:or {type :primary
|
||||
size 40
|
||||
customization-color (if (= type :primary) :blue nil)}}
|
||||
children]
|
||||
(let [{:keys [icon-color background-color label-color border-color blur-type
|
||||
blur-overlay-color border-radius overlay-customization-color]}
|
||||
(button-properties/get-values {:customization-color customization-color
|
||||
:background background
|
||||
:type type
|
||||
:theme theme
|
||||
:pressed? (if pressed? pressed? @pressed-state?)
|
||||
:icon-only? icon-only?})
|
||||
icon-size (when (= 24 size) 12)]
|
||||
[rn/touchable-without-feedback
|
||||
{:disabled disabled?
|
||||
:accessibility-label accessibility-label
|
||||
:on-press-in (fn []
|
||||
(reset! pressed-state? true)
|
||||
(when on-press-in (on-press-in)))
|
||||
:on-press-out (fn []
|
||||
(reset! pressed-state? nil)
|
||||
(when on-press-out (on-press-out)))
|
||||
:on-press on-press
|
||||
:allow-multiple-presses? allow-multiple-presses?
|
||||
:on-long-press on-long-press}
|
||||
[rn/view
|
||||
[quo.icons/icon icon-top
|
||||
{:container-style {:margin-bottom 2}
|
||||
:color icon-color
|
||||
:size icon-size}]])
|
||||
(when icon-left
|
||||
[rn/view
|
||||
{:style (style/icon-left-icon-style
|
||||
{:size size
|
||||
:icon-size icon-size})}
|
||||
[quo.icons/icon icon-left
|
||||
{:color icon-color
|
||||
:size icon-size}]])
|
||||
[rn/view
|
||||
(cond
|
||||
icon-only?
|
||||
[quo.icons/icon children
|
||||
{:color label-color
|
||||
:size icon-size}]
|
||||
{:style (merge
|
||||
(style/shape-style-container size border-radius)
|
||||
container-style)}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
(style/style-container {:size size
|
||||
:disabled? disabled?
|
||||
:border-radius border-radius
|
||||
:background-color background-color
|
||||
:border-color border-color
|
||||
:icon-only? icon-only?
|
||||
:icon-top icon-top
|
||||
:icon-left icon-left
|
||||
:icon-right icon-right})
|
||||
inner-style)}
|
||||
(when overlay-customization-color
|
||||
[customization-colors/overlay
|
||||
{:customization-color overlay-customization-color
|
||||
:theme theme
|
||||
:pressed? (if pressed? pressed? @pressed-state?)}])
|
||||
(when (= background :photo)
|
||||
[blur/view
|
||||
{:blur-radius 20
|
||||
:blur-type blur-type
|
||||
:overlay-color blur-overlay-color
|
||||
:style style/blur-view}])
|
||||
(when icon-top
|
||||
[rn/view
|
||||
[quo.icons/icon icon-top
|
||||
{:container-style {:margin-bottom 2}
|
||||
:color icon-color
|
||||
:size icon-size}]])
|
||||
(when icon-left
|
||||
[rn/view
|
||||
{:style (style/icon-left-icon-style
|
||||
{:size size
|
||||
:icon-size icon-size})}
|
||||
[quo.icons/icon icon-left
|
||||
{:color icon-color
|
||||
:size icon-size}]])
|
||||
[rn/view
|
||||
(cond
|
||||
icon-only?
|
||||
[quo.icons/icon children
|
||||
{:color label-color
|
||||
:size icon-size}]
|
||||
|
||||
(string? children)
|
||||
[text/text
|
||||
{:size (when (#{56 24} size) :paragraph-2)
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style {:color label-color}}
|
||||
children]
|
||||
(string? children)
|
||||
[text/text
|
||||
{:size (when (#{56 24} size) :paragraph-2)
|
||||
:weight :medium
|
||||
:number-of-lines 1
|
||||
:style {:color label-color}}
|
||||
children]
|
||||
|
||||
(vector? children)
|
||||
children)]
|
||||
(when icon-right
|
||||
[rn/view
|
||||
{:style (style/icon-right-icon-style
|
||||
{:size size
|
||||
:icon-size icon-size})}
|
||||
[quo.icons/icon icon-right
|
||||
{:color icon-color
|
||||
:size icon-size}]])]]]))
|
||||
(vector? children)
|
||||
children)]
|
||||
(when icon-right
|
||||
[rn/view
|
||||
{:style (style/icon-right-icon-style
|
||||
{:size size
|
||||
:icon-size icon-size})}
|
||||
[quo.icons/icon icon-right
|
||||
{:color icon-color
|
||||
:size icon-size}]])]]]))))
|
||||
|
||||
(def button (theme/with-theme button-internal))
|
||||
|
||||
@@ -3,24 +3,28 @@
|
||||
[quo.components.buttons.composer-button.style :as style]
|
||||
[quo.components.icon :as quo.icons]
|
||||
[quo.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-press on-long-press disabled? blur? icon accessibility-label container-style]}]
|
||||
(let [[pressed? set-pressed] (rn/use-state false)
|
||||
theme (theme/use-theme-value)
|
||||
on-press-in (rn/use-callback #(set-pressed true))
|
||||
on-press-out (rn/use-callback #(set-pressed nil))]
|
||||
[rn/pressable
|
||||
{:accessibility-label (or accessibility-label :composer-button)
|
||||
:on-press on-press
|
||||
:on-press-in on-press-in
|
||||
:on-press-out on-press-out
|
||||
:on-long-press on-long-press
|
||||
:disabled disabled?
|
||||
:style (merge (style/main {:pressed? pressed?
|
||||
:blur? blur?
|
||||
:theme theme
|
||||
:disabled? disabled?})
|
||||
container-style)}
|
||||
[quo.icons/icon icon {:color (style/get-label-color {:blur? blur? :theme theme})}]]))
|
||||
(defn- view-internal
|
||||
[_ _]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
(fn
|
||||
[{:keys [on-press on-long-press disabled? theme blur? icon accessibility-label container-style]}]
|
||||
[rn/pressable
|
||||
{:accessibility-label (or accessibility-label :composer-button)
|
||||
:on-press on-press
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? nil)
|
||||
:on-long-press on-long-press
|
||||
:disabled disabled?
|
||||
:style (merge (style/main {:pressed? @pressed?
|
||||
:blur? blur?
|
||||
:theme theme
|
||||
:disabled? disabled?})
|
||||
container-style)}
|
||||
[quo.icons/icon icon
|
||||
{:color (style/get-label-color {:blur? blur?
|
||||
:theme theme})}]])))
|
||||
|
||||
(def view (theme/with-theme view-internal))
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- get-button-color
|
||||
[{:keys [type pressed? customization-color theme]}]
|
||||
@@ -44,48 +45,48 @@
|
||||
:color (get-icon-and-text-color type theme)
|
||||
:container-style (style/container type)}])
|
||||
|
||||
(defn view
|
||||
(defn- view-internal
|
||||
"[dynamic-button opts]
|
||||
opts
|
||||
{:type :jump-to/:mention/:notification-down/:notification-up/:search/:search-with-label/:scroll-to-bottom
|
||||
:on-press fn
|
||||
:count mentions or notifications count
|
||||
:customization-color customize jump-to and mention button color}"
|
||||
[{:keys [type label on-press customization-color style] :as args}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[pressed? set-pressed] (rn/use-state false)
|
||||
button-color (get-button-color {:type type
|
||||
:pressed? pressed?
|
||||
:customization-color (or customization-color :primary)
|
||||
:theme theme})
|
||||
on-press-in (rn/use-callback #(set-pressed true))
|
||||
on-press-out (rn/use-callback #(set-pressed false))]
|
||||
[rn/touchable-opacity
|
||||
{:on-press-in on-press-in
|
||||
:on-press-out on-press-out
|
||||
:on-press on-press
|
||||
:active-opacity 1
|
||||
:hit-slop {:top 5 :bottom 5 :left 5 :right 5}
|
||||
:pointer-events :auto
|
||||
:style {:height 24}
|
||||
:accessibility-label type}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
{:flex-direction :row
|
||||
:height 24
|
||||
:border-radius 12
|
||||
:background-color button-color}
|
||||
style)}
|
||||
(when (#{:mention :search :search-with-label :scroll-to-bottom} type)
|
||||
[icon-view type])
|
||||
(when (#{:jump-to :mention :notification-down :notification-up :search-with-label} type)
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (assoc (style/text type) :color (get-icon-and-text-color type theme))}
|
||||
(case type
|
||||
:jump-to label
|
||||
:search-with-label label
|
||||
(:mention :notification-down :notification-up) (str (:count args)))])
|
||||
(when (#{:jump-to :notification-down :notification-up} type)
|
||||
[icon-view type theme])]]))
|
||||
[_]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
(fn [{:keys [type label on-press customization-color style theme] :as args}]
|
||||
[rn/touchable-opacity
|
||||
{:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? false)
|
||||
:on-press on-press
|
||||
:active-opacity 1
|
||||
:hit-slop {:top 5 :bottom 5 :left 5 :right 5}
|
||||
:pointer-events :auto
|
||||
:style {:height 24}
|
||||
:accessibility-label type}
|
||||
[rn/view
|
||||
{:style (merge
|
||||
{:flex-direction :row
|
||||
:height 24
|
||||
:border-radius 12
|
||||
:background-color (get-button-color {:type type
|
||||
:pressed? @pressed?
|
||||
:customization-color (or customization-color
|
||||
:primary)
|
||||
:theme theme})}
|
||||
style)}
|
||||
(when (#{:mention :search :search-with-label :scroll-to-bottom} type)
|
||||
[icon-view type])
|
||||
(when (#{:jump-to :mention :notification-down :notification-up :search-with-label} type)
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (assoc (style/text type) :color (get-icon-and-text-color type theme))}
|
||||
(case type
|
||||
:jump-to label
|
||||
:search-with-label label
|
||||
(:mention :notification-down :notification-up) (str (:count args)))])
|
||||
(when (#{:jump-to :notification-down :notification-up} type)
|
||||
[icon-view type theme])]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -6,25 +6,29 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-press on-long-press disabled? container-style]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[pressed? set-pressed] (rn/use-state false)
|
||||
on-press-in (rn/use-callback #(set-pressed true))
|
||||
on-press-out (rn/use-callback #(set-pressed nil))]
|
||||
[rn/pressable
|
||||
{:accessibility-label :log-out-button
|
||||
:on-press on-press
|
||||
:on-press-in on-press-in
|
||||
:on-press-out on-press-out
|
||||
:on-long-press on-long-press
|
||||
:disabled disabled?
|
||||
:style (merge (style/main {:pressed? pressed?
|
||||
:theme theme
|
||||
:disabled? disabled?})
|
||||
container-style)}
|
||||
[icon/icon :i/log-out {:color (if pressed? colors/white-opa-40 colors/white-opa-70)}]
|
||||
[text/text {:weight :medium :size :paragraph-1}
|
||||
(i18n/label :t/logout)]]))
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(let [pressed? (reagent/atom false)
|
||||
on-press-in #(reset! pressed? true)
|
||||
on-press-out #(reset! pressed? nil)]
|
||||
(fn
|
||||
[{:keys [on-press on-long-press disabled? theme container-style]}]
|
||||
[rn/pressable
|
||||
{:accessibility-label :log-out-button
|
||||
:on-press on-press
|
||||
:on-press-in on-press-in
|
||||
:on-press-out on-press-out
|
||||
:on-long-press on-long-press
|
||||
:disabled disabled?
|
||||
:style (merge (style/main {:pressed? @pressed?
|
||||
:theme theme
|
||||
:disabled? disabled?})
|
||||
container-style)}
|
||||
[icon/icon :i/log-out {:color (if pressed? colors/white-opa-40 colors/white-opa-70)}]
|
||||
[text/text {:weight :medium :size :paragraph-1}
|
||||
(i18n/label :t/logout)]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
(ns quo.components.buttons.slide-button.animations
|
||||
(:require [react-native.reanimated :as reanimated]))
|
||||
(:require
|
||||
[oops.core :as oops]
|
||||
[quo.components.buttons.slide-button.utils :as utils]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(def ^:private extrapolation
|
||||
{:extrapolateLeft "clamp"
|
||||
@@ -62,6 +66,36 @@
|
||||
:damping 30
|
||||
:stiffness 400}))
|
||||
|
||||
(defn- complete-animation
|
||||
[sliding-complete?]
|
||||
(reset! sliding-complete? true))
|
||||
|
||||
(defn reset-track-position
|
||||
[x-pos]
|
||||
(animate-spring x-pos 0))
|
||||
|
||||
;; Gestures
|
||||
(defn drag-gesture
|
||||
[x-pos
|
||||
gestures-disabled?
|
||||
disabled?
|
||||
track-width
|
||||
sliding-complete?]
|
||||
(let [gestures-enabled? (not (or disabled? @gestures-disabled?))]
|
||||
(-> (gesture/gesture-pan)
|
||||
(gesture/with-test-ID :slide-button-gestures)
|
||||
(gesture/enabled gestures-enabled?)
|
||||
(gesture/min-distance 0)
|
||||
(gesture/on-update (fn [event]
|
||||
(let [x-translation (oops/oget event "translationX")
|
||||
clamped-x (utils/clamp-value x-translation 0 track-width)
|
||||
reached-end? (>= clamped-x track-width)]
|
||||
(reanimated/set-shared-value x-pos clamped-x)
|
||||
(when (and reached-end? (not @sliding-complete?))
|
||||
(reset! gestures-disabled? true)
|
||||
(complete-animation sliding-complete?)))))
|
||||
(gesture/on-end (fn [event]
|
||||
(let [x-translation (oops/oget event "translationX")
|
||||
reached-end? (>= x-translation track-width)]
|
||||
(when (not reached-end?)
|
||||
(reset-track-position x-pos))))))))
|
||||
|
||||
@@ -11,33 +11,94 @@
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn drag-gesture
|
||||
[x-pos disabled? track-width sliding-complete?
|
||||
set-sliding-complete
|
||||
on-complete reset-fn]
|
||||
(-> (gesture/gesture-pan)
|
||||
(gesture/with-test-ID :slide-button-gestures)
|
||||
(gesture/enabled (not disabled?))
|
||||
(gesture/min-distance 0)
|
||||
(gesture/on-update (fn [event]
|
||||
(let [x-translation (oops/oget event "translationX")
|
||||
clamped-x (utils/clamp-value x-translation 0 track-width)
|
||||
reached-end? (>= clamped-x track-width)]
|
||||
(reanimated/set-shared-value x-pos clamped-x)
|
||||
(when (and reached-end? (not sliding-complete?))
|
||||
(set-sliding-complete true)
|
||||
(when on-complete (on-complete reset-fn))))))
|
||||
(gesture/on-end (fn [event]
|
||||
(let [x-translation (oops/oget event "translationX")
|
||||
reached-end? (>= x-translation track-width)]
|
||||
(when (not reached-end?)
|
||||
(animations/reset-track-position x-pos)))))))
|
||||
(defn- f-slider
|
||||
[{:keys [disabled?]}]
|
||||
(let [track-width (reagent/atom nil)
|
||||
sliding-complete? (reagent/atom false)
|
||||
gestures-disabled? (reagent/atom disabled?)
|
||||
on-track-layout (fn [evt]
|
||||
(let [width (oops/oget evt "nativeEvent.layout.width")]
|
||||
(reset! track-width width)))]
|
||||
(fn [{:keys [on-reset
|
||||
on-complete
|
||||
track-text
|
||||
track-icon
|
||||
disabled?
|
||||
customization-color
|
||||
size
|
||||
container-style
|
||||
theme
|
||||
type
|
||||
blur?]}]
|
||||
(let [x-pos (reanimated/use-shared-value 0)
|
||||
dimensions (partial utils/get-dimensions
|
||||
(or @track-width constants/default-width)
|
||||
size)
|
||||
interpolate-track (partial animations/interpolate-track
|
||||
x-pos
|
||||
(dimensions :usable-track)
|
||||
(dimensions :thumb))
|
||||
custom-color (if (= type :danger) :danger customization-color)]
|
||||
(rn/use-effect (fn []
|
||||
(when @sliding-complete?
|
||||
(on-complete)))
|
||||
[@sliding-complete?])
|
||||
(rn/use-effect (fn []
|
||||
(when on-reset
|
||||
(reset! sliding-complete? false)
|
||||
(reset! gestures-disabled? false)
|
||||
(animations/reset-track-position x-pos)
|
||||
(on-reset)))
|
||||
[on-reset])
|
||||
[gesture/gesture-detector
|
||||
{:gesture (animations/drag-gesture x-pos
|
||||
gestures-disabled?
|
||||
disabled?
|
||||
(dimensions :usable-track)
|
||||
sliding-complete?)}
|
||||
[reanimated/view
|
||||
{:test-ID :slide-button-track
|
||||
:style (merge (style/track {:disabled? disabled?
|
||||
:customization-color custom-color
|
||||
:height (dimensions :track-height)
|
||||
:blur? blur?})
|
||||
container-style)
|
||||
:on-layout (when-not (some? @track-width)
|
||||
on-track-layout)}
|
||||
[reanimated/view {:style (style/track-cover interpolate-track)}
|
||||
[rn/view {:style (style/track-cover-text-container @track-width)}
|
||||
[icon/icon track-icon
|
||||
{:color (utils/text-color custom-color theme blur?)
|
||||
:size 20}]
|
||||
[rn/view {:width 4}]
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-1
|
||||
:style (style/track-text custom-color theme blur?)}
|
||||
track-text]]]
|
||||
[reanimated/view
|
||||
{:style (style/thumb-container {:interpolate-track interpolate-track
|
||||
:thumb-size (dimensions :thumb)
|
||||
:customization-color custom-color
|
||||
:theme theme
|
||||
:blur? blur?})}
|
||||
[reanimated/view {:style (style/arrow-icon-container interpolate-track)}
|
||||
[icon/icon :arrow-right
|
||||
{:color colors/white
|
||||
:size 20}]]
|
||||
[reanimated/view
|
||||
{:style (style/action-icon interpolate-track
|
||||
(dimensions :thumb))}
|
||||
[icon/icon track-icon
|
||||
{:color colors/white
|
||||
:size 20}]]]]]))))
|
||||
|
||||
(defn view
|
||||
(defn- view-internal
|
||||
"Options
|
||||
- `on-complete` Callback called when the sliding is complete, returns reset fn as a parameter
|
||||
- `on-complete` Callback called when the sliding is complete
|
||||
- `disabled?` Boolean that disables the button
|
||||
(_and gestures_)
|
||||
- `size` :size/s-40`/`:size/s-48`
|
||||
@@ -45,73 +106,9 @@
|
||||
- `track-icon` Key of the icon shown on the track
|
||||
(e.g. `:face-id`)
|
||||
- `customization-color` Customization color
|
||||
- `on-reset` A callback which can be used to reset the component and run required functionality
|
||||
"
|
||||
[{:keys [on-complete track-text track-icon disabled? customization-color size
|
||||
container-style type blur?]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
x-pos (reanimated/use-shared-value 0)
|
||||
[track-width set-track-width] (rn/use-state nil)
|
||||
[sliding-complete?
|
||||
set-sliding-complete] (rn/use-state false)
|
||||
on-track-layout (rn/use-callback
|
||||
#(set-track-width (oops/oget % "nativeEvent.layout.width")))
|
||||
reset-fn (rn/use-callback
|
||||
(fn []
|
||||
(set-sliding-complete false)
|
||||
(animations/reset-track-position x-pos)))
|
||||
dimensions (rn/use-callback
|
||||
(partial utils/get-dimensions
|
||||
(or track-width constants/default-width)
|
||||
size)
|
||||
[track-width])
|
||||
interpolate-track (rn/use-callback
|
||||
(partial animations/interpolate-track
|
||||
x-pos
|
||||
(dimensions :usable-track)
|
||||
(dimensions :thumb))
|
||||
[dimensions])
|
||||
custom-color (if (= type :danger) :danger customization-color)
|
||||
gesture (rn/use-memo #(drag-gesture x-pos
|
||||
disabled?
|
||||
(dimensions :usable-track)
|
||||
sliding-complete?
|
||||
set-sliding-complete
|
||||
on-complete
|
||||
reset-fn)
|
||||
[sliding-complete? disabled?])]
|
||||
[gesture/gesture-detector
|
||||
{:gesture gesture}
|
||||
[reanimated/view
|
||||
{:test-ID :slide-button-track
|
||||
:style (merge (style/track {:disabled? disabled?
|
||||
:customization-color custom-color
|
||||
:height (dimensions :track-height)
|
||||
:blur? blur?})
|
||||
container-style)
|
||||
:on-layout on-track-layout}
|
||||
[reanimated/view {:style (style/track-cover interpolate-track)}
|
||||
[rn/view {:style (style/track-cover-text-container track-width)}
|
||||
[icon/icon track-icon
|
||||
{:color (utils/text-color custom-color theme blur?)
|
||||
:size 20}]
|
||||
[rn/view {:width 4}]
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-1
|
||||
:style (style/track-text custom-color theme blur?)}
|
||||
track-text]]]
|
||||
[reanimated/view
|
||||
{:style (style/thumb-container {:interpolate-track interpolate-track
|
||||
:thumb-size (dimensions :thumb)
|
||||
:customization-color custom-color
|
||||
:theme theme
|
||||
:blur? blur?})}
|
||||
[reanimated/view {:style (style/arrow-icon-container interpolate-track)}
|
||||
[icon/icon :arrow-right
|
||||
{:color colors/white
|
||||
:size 20}]]
|
||||
[reanimated/view
|
||||
{:style (style/action-icon interpolate-track (dimensions :thumb))}
|
||||
[icon/icon track-icon
|
||||
{:color colors/white
|
||||
:size 20}]]]]]))
|
||||
[props]
|
||||
[:f> f-slider props])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -4,24 +4,26 @@
|
||||
[quo.components.icon :as quo.icons]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-press on-long-press disabled? icon accessibility-label container-style]}]
|
||||
(let [theme (theme/use-theme-value)
|
||||
[pressed? set-pressed] (rn/use-state false)
|
||||
on-press-in (rn/use-callback #(set-pressed true))
|
||||
on-press-out (rn/use-callback #(set-pressed nil))]
|
||||
[rn/pressable
|
||||
{:accessibility-label (or accessibility-label :wallet-button)
|
||||
:on-press on-press
|
||||
:on-press-in on-press-in
|
||||
:on-press-out on-press-out
|
||||
:on-long-press on-long-press
|
||||
:disabled disabled?
|
||||
:style (merge (style/main {:pressed? pressed?
|
||||
:theme theme
|
||||
:disabled? disabled?})
|
||||
container-style)}
|
||||
[quo.icons/icon icon
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)}]]))
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
(fn
|
||||
[{:keys [on-press on-long-press disabled? icon accessibility-label container-style theme]}]
|
||||
[rn/pressable
|
||||
{:accessibility-label (or accessibility-label :wallet-button)
|
||||
:on-press on-press
|
||||
:on-press-in #(reset! pressed? true)
|
||||
:on-press-out #(reset! pressed? nil)
|
||||
:on-long-press on-long-press
|
||||
:disabled disabled?
|
||||
:style (merge (style/main {:pressed? @pressed?
|
||||
:theme theme
|
||||
:disabled? disabled?})
|
||||
container-style)}
|
||||
[quo.icons/icon icon
|
||||
{:color (colors/theme-colors colors/neutral-100 colors/white theme)}]])))
|
||||
|
||||
(def view (theme/with-theme view-internal))
|
||||
|
||||
@@ -8,36 +8,36 @@
|
||||
[quo.components.calendar.calendar.years-list.view :as years-list]
|
||||
[quo.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[utils.number :as utils.number]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-change start-date end-date]}]
|
||||
(let [theme (theme/use-theme-value)
|
||||
[selected-year set-selected-year] (rn/use-state (utils/current-year))
|
||||
[selected-month set-selected-month] (rn/use-state (utils/current-month))
|
||||
on-change-year (rn/use-callback #(set-selected-year %))
|
||||
on-change-month (rn/use-callback
|
||||
(fn [new-date]
|
||||
(set-selected-year
|
||||
(utils.number/parse-int (:year new-date)))
|
||||
(set-selected-month
|
||||
(utils.number/parse-int (:month new-date)))))]
|
||||
[rn/view
|
||||
{:style (style/container theme)}
|
||||
[years-list/view
|
||||
{:on-change-year on-change-year
|
||||
:year selected-year}]
|
||||
[rn/view
|
||||
{:style style/container-main}
|
||||
[month-picker/view
|
||||
{:year selected-year
|
||||
:month selected-month
|
||||
:on-change on-change-month}]
|
||||
[weekdays-header/view]
|
||||
[days-grid/view
|
||||
{:year selected-year
|
||||
:month selected-month
|
||||
:start-date start-date
|
||||
:end-date end-date
|
||||
:on-change on-change
|
||||
:customization-color :blue}]]]))
|
||||
(defn- view-internal
|
||||
[]
|
||||
(let [selected-year (reagent/atom (utils/current-year))
|
||||
selected-month (reagent/atom (utils/current-month))
|
||||
on-change-year #(reset! selected-year %)
|
||||
on-change-month (fn [new-date]
|
||||
(reset! selected-year (utils.number/parse-int (:year new-date)))
|
||||
(reset! selected-month (utils.number/parse-int (:month new-date))))]
|
||||
(fn [{:keys [on-change start-date end-date theme]}]
|
||||
[rn/view
|
||||
{:style (style/container theme)}
|
||||
[years-list/view
|
||||
{:on-change-year on-change-year
|
||||
:year @selected-year}]
|
||||
[rn/view
|
||||
{:style style/container-main}
|
||||
[month-picker/view
|
||||
{:year @selected-year
|
||||
:month @selected-month
|
||||
:on-change on-change-month}]
|
||||
[weekdays-header/view]
|
||||
[days-grid/view
|
||||
{:year @selected-year
|
||||
:month @selected-month
|
||||
:start-date start-date
|
||||
:end-date end-date
|
||||
:on-change on-change
|
||||
:customization-color :blue}]]])))
|
||||
|
||||
(def view (theme/with-theme view-internal))
|
||||
|
||||
@@ -3,7 +3,13 @@
|
||||
[quo.components.colors.color.constants :as constants]
|
||||
[quo.components.colors.color.view :as color]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- on-change-handler
|
||||
[selected color-name on-change]
|
||||
(reset! selected color-name)
|
||||
(when on-change (on-change color-name)))
|
||||
|
||||
(defn get-item-layout
|
||||
[_ index]
|
||||
@@ -12,34 +18,15 @@
|
||||
:offset (* (+ constants/color-size 8) index)
|
||||
:index index})
|
||||
|
||||
(defn view
|
||||
(defn- view-internal
|
||||
"Options
|
||||
- `default-selected` Default selected color name.
|
||||
- `on-change` Callback called when a color is selected `(fn [color-name])`.
|
||||
- `blur?` Boolean to enable blur background support.}"
|
||||
[{:keys [default-selected blur? on-change feng-shui? container-style]}]
|
||||
(let [[selected set-selected] (rn/use-state default-selected)
|
||||
{window-width :width} (rn/get-window)
|
||||
ref (rn/use-ref-atom nil)
|
||||
on-ref (rn/use-callback #(reset! ref %))
|
||||
render-fn (rn/use-callback
|
||||
(fn [color idx]
|
||||
[color/view
|
||||
{:selected? (= color selected)
|
||||
:on-press (fn [color-name]
|
||||
(.scrollToIndex ^js @ref
|
||||
#js
|
||||
{:animated true
|
||||
:index idx
|
||||
:viewPosition 0.5})
|
||||
(set-selected color-name)
|
||||
(when on-change (on-change color-name)))
|
||||
:blur? blur?
|
||||
:key color
|
||||
:color color
|
||||
:idx idx
|
||||
:window-width window-width}])
|
||||
[selected blur? on-change @ref])]
|
||||
(let [selected (reagent/atom default-selected)
|
||||
{window-width :width} (rn/get-window)
|
||||
ref (atom nil)]
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
(js/setTimeout
|
||||
@@ -53,14 +40,32 @@
|
||||
:viewPosition 0.5})))))
|
||||
50)))
|
||||
[rn/flat-list
|
||||
{:ref on-ref
|
||||
{:ref #(reset! ref %)
|
||||
;; TODO: using :feng-shui? temporarily while b & w is being developed.
|
||||
;; https://github.com/status-im/status-mobile/discussions/16676
|
||||
:data (if feng-shui?
|
||||
(conj colors/account-colors :feng-shui)
|
||||
colors/account-colors)
|
||||
:render-fn render-fn
|
||||
:render-fn (fn [color idx]
|
||||
[color/view
|
||||
{:selected? (= color @selected)
|
||||
:on-press (fn [e]
|
||||
(.scrollToIndex ^js @ref
|
||||
#js
|
||||
{:animated true
|
||||
:index idx
|
||||
:viewPosition 0.5})
|
||||
(on-change-handler selected e on-change))
|
||||
:blur? blur?
|
||||
:key color
|
||||
:color color
|
||||
:idx idx
|
||||
:window-width window-width}])
|
||||
:get-item-layout get-item-layout
|
||||
:horizontal true
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:content-container-style container-style}]))
|
||||
|
||||
(defn view
|
||||
[props]
|
||||
[:f> view-internal props])
|
||||
|
||||
@@ -35,11 +35,12 @@
|
||||
(defn image
|
||||
"Same as rn/image but cache the image source in a js/Set, so the image won't
|
||||
flicker when re-render on android"
|
||||
[props]
|
||||
(let [[loaded-source set-loaded-source] (rn/use-state nil)
|
||||
on-source-loaded (rn/use-callback #(set-loaded-source %))]
|
||||
(if platform/ios?
|
||||
[rn/image props]
|
||||
[:<>
|
||||
[rn/image (assoc props :source loaded-source)]
|
||||
[caching-image props on-source-loaded]])))
|
||||
[]
|
||||
(let [loaded-source (reagent/atom nil)
|
||||
on-source-loaded #(reset! loaded-source %)]
|
||||
(fn [props]
|
||||
(if platform/ios?
|
||||
[rn/image props]
|
||||
[:<>
|
||||
[rn/image (assoc props :source @loaded-source)]
|
||||
[caching-image props on-source-loaded]]))))
|
||||
|
||||
@@ -65,7 +65,7 @@
|
||||
{:title "Title"
|
||||
:type :account
|
||||
:account-avatar-emoji "🍿"
|
||||
:networks [{:network-name :ethereum :short-name "eth"}]
|
||||
:networks [{:name :ethereum :short-name "eth"}]
|
||||
:description "0x62b...0a5"
|
||||
:customization-color :purple}]
|
||||
theme)
|
||||
|
||||
@@ -3,23 +3,25 @@
|
||||
[quo.components.dropdowns.network-dropdown.style :as style]
|
||||
[quo.components.list-items.preview-list.view :as preview-list]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn view
|
||||
[{:keys [on-press state] :as props} networks]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[pressed? set-pressed] (rn/use-state false)
|
||||
on-press-in (rn/use-callback #(set-pressed true))
|
||||
on-press-out (rn/use-callback #(set-pressed false))]
|
||||
[rn/pressable
|
||||
{:style (style/dropdown-container (merge props {:pressed? pressed? :theme theme}))
|
||||
:accessibility-label :network-dropdown
|
||||
:disabled (= state :disabled)
|
||||
:on-press on-press
|
||||
:on-press-in on-press-in
|
||||
:on-press-out on-press-out}
|
||||
[preview-list/view
|
||||
{:type :network
|
||||
:list-size (count networks)
|
||||
:size :size-20}
|
||||
networks]]))
|
||||
(defn- internal-view
|
||||
[_ _]
|
||||
(let [pressed? (reagent/atom false)]
|
||||
(fn
|
||||
[{:keys [on-press state] :as props} networks]
|
||||
[rn/pressable
|
||||
{:style (style/dropdown-container (merge props {:pressed? @pressed?}))
|
||||
:accessibility-label :network-dropdown
|
||||
:disabled (= state :disabled)
|
||||
:on-press on-press
|
||||
:on-press-in (fn [] (reset! pressed? true))
|
||||
:on-press-out (fn [] (reset! pressed? false))}
|
||||
[preview-list/view
|
||||
{:type :network
|
||||
:list-size (count networks)
|
||||
:size :size-20}
|
||||
networks]])))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
(def initial-spacing 56)
|
||||
(def end-spacing 22)
|
||||
(def y-axis-label-width -33)
|
||||
(def inspecting? (reagent/atom false))
|
||||
|
||||
(defn- pointer
|
||||
[customization-color]
|
||||
@@ -31,9 +32,14 @@
|
||||
:pointer-color customization-color
|
||||
:pointer-strip-enable-gradient true})
|
||||
|
||||
(defn- get-pointer-props
|
||||
[pointer-props]
|
||||
(let [pointer-index (.-pointerIndex ^js pointer-props)]
|
||||
(reset! inspecting? (not= pointer-index -1))))
|
||||
|
||||
(defn- get-line-color
|
||||
[state theme inspecting?]
|
||||
(if inspecting?
|
||||
[state theme]
|
||||
(if @inspecting?
|
||||
(colors/theme-colors colors/neutral-80-opa-40
|
||||
colors/white-opa-20
|
||||
theme)
|
||||
@@ -45,13 +51,11 @@
|
||||
colors/danger-60
|
||||
theme))))
|
||||
|
||||
(defn view
|
||||
[{:keys [data state customization-color reference-value reference-prefix decimal-separator]
|
||||
(defn- view-internal
|
||||
[{:keys [data state customization-color theme reference-value reference-prefix decimal-separator]
|
||||
:or {reference-prefix "$"
|
||||
decimal-separator :dot}}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[inspecting? set-inspecting] (rn/use-state false)
|
||||
data (if (> (count data) max-data-points)
|
||||
(let [data (if (> (count data) max-data-points)
|
||||
(utils/downsample-data data max-data-points)
|
||||
data)
|
||||
highest-value (utils/find-highest-value data)
|
||||
@@ -60,11 +64,7 @@
|
||||
max-value (- (utils/calculate-rounded-max highest-value) min-value)
|
||||
step-value (/ max-value 4)
|
||||
width (:width (rn/get-window))
|
||||
line-color (get-line-color state theme inspecting?)
|
||||
get-pointer-props (rn/use-callback
|
||||
(fn [pointer-props]
|
||||
(let [pointer-index (.-pointerIndex ^js pointer-props)]
|
||||
(set-inspecting (not= pointer-index -1)))))
|
||||
line-color (get-line-color state theme)
|
||||
rules-color (colors/theme-colors colors/neutral-80-opa-10
|
||||
colors/white-opa-5
|
||||
theme)
|
||||
@@ -119,7 +119,7 @@
|
||||
:show-strip-on-focus true
|
||||
:reference-line-1-config {:color rules-color}
|
||||
:reference-line-1-position 0
|
||||
:show-reference-line-2 (and (not inspecting?)
|
||||
:show-reference-line-2 (and (not @inspecting?)
|
||||
(<= reference-value highest-value)
|
||||
(>= reference-value lowest-value))
|
||||
:reference-line-2-config {:color y-axis-label-text-color
|
||||
@@ -138,3 +138,5 @@
|
||||
:x-axis-label-text-style (style/x-axis-label-text (/ width (count x-axis-label-texts))
|
||||
y-axis-label-text-color)
|
||||
:x-axis-label-texts x-axis-label-texts}]]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:placeholder-text-color
|
||||
colors/neutral-30)))
|
||||
colors/neutral-40)))
|
||||
|
||||
(h/test "on focus with blur? true"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
@@ -30,22 +30,27 @@
|
||||
(h/fire-event :on-focus (h/get-by-label-text :address-text-input))
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:placeholder-text-color
|
||||
colors/neutral-80-opa-20)))
|
||||
colors/neutral-80-opa-40)))
|
||||
|
||||
(h/test "default value is properly set"
|
||||
(let [default-value "default-value"]
|
||||
(h/test "scanned value is properly set"
|
||||
(let [on-change-text (h/mock-fn)
|
||||
scanned-value "scanned-value"]
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
(h/render [address-input/address-input
|
||||
{:default-value default-value
|
||||
:ens-regex ens-regex}])
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:value
|
||||
default-value))))
|
||||
{:scanned-value scanned-value
|
||||
:on-change-text on-change-text
|
||||
:ens-regex ens-regex}])
|
||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||
(.then (fn []
|
||||
(h/was-called-with on-change-text scanned-value)
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:default-value
|
||||
scanned-value)))))))
|
||||
|
||||
(h/test "clear icon is shown when input has text"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
(h/render [address-input/address-input
|
||||
{:default-value "default value"
|
||||
{:scanned-value "scanned value"
|
||||
:ens-regex ens-regex}])
|
||||
(-> (h/wait-for #(h/get-by-label-text :clear-button-container))
|
||||
(.then #(h/is-truthy (h/get-by-label-text :clear-button))))))
|
||||
@@ -53,7 +58,7 @@
|
||||
(h/test "on blur with text and blur? false"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
(h/render [address-input/address-input
|
||||
{:default-value "default value"
|
||||
{:scanned-value "scanned value"
|
||||
:ens-regex ens-regex}])
|
||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||
(.then (fn []
|
||||
@@ -66,7 +71,7 @@
|
||||
(h/test "on blur with text blur? true"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
(h/render [address-input/address-input
|
||||
{:default-value "default value"
|
||||
{:scanned-value "scanned value"
|
||||
:blur? true
|
||||
:ens-regex ens-regex}])
|
||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||
@@ -101,7 +106,7 @@
|
||||
(let [on-clear (h/mock-fn)]
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
(h/render [address-input/address-input
|
||||
{:default-value "default value"
|
||||
{:scanned-value "scanned value"
|
||||
:on-clear on-clear
|
||||
:ens-regex ens-regex}])
|
||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||
@@ -143,7 +148,7 @@
|
||||
(-> (h/wait-for #(h/get-by-label-text :clear-button))
|
||||
(.then (fn []
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:value
|
||||
:default-value
|
||||
clipboard)))))))
|
||||
|
||||
(h/test "ENS loading state and call on-detect-ens"
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
[react-native.clipboard :as clipboard]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(defn- icon-color
|
||||
@@ -54,135 +55,124 @@
|
||||
(and (not= status :default) (not blur?))
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)))
|
||||
|
||||
(defn address-input
|
||||
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan
|
||||
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
|
||||
valid-ens-or-address? container-style]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[status set-status] (rn/use-state :default)
|
||||
value (rn/use-ref-atom nil)
|
||||
[_ trigger-render-value] (rn/use-state @value)
|
||||
[focused? set-focused] (rn/use-state false)
|
||||
on-change (rn/use-callback
|
||||
(fn [text]
|
||||
(let [address? (when address-regex
|
||||
(boolean (re-matches address-regex text)))
|
||||
ens? (when ens-regex
|
||||
(boolean (re-matches ens-regex text)))]
|
||||
(reset! value text)
|
||||
(if (> (count text) 0)
|
||||
(set-status :typing)
|
||||
(set-status :active))
|
||||
(when on-change-text
|
||||
(on-change-text text))
|
||||
(when (and on-detect-ens ens?)
|
||||
(set-status :loading)
|
||||
(on-detect-ens text #(set-status :typing)))
|
||||
(when (and address? on-detect-address)
|
||||
(set-status :loading)
|
||||
(on-detect-address text))
|
||||
(when (and (not address?)
|
||||
(not ens?)
|
||||
on-detect-unclassified)
|
||||
(on-detect-unclassified text)))))
|
||||
set-value (rn/use-callback
|
||||
(fn [new-value]
|
||||
(reset! value new-value)
|
||||
(on-change new-value)
|
||||
(trigger-render-value new-value)))
|
||||
on-paste (rn/use-callback
|
||||
(fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard]
|
||||
(when-not (empty? clipboard)
|
||||
(set-value clipboard))))))
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(set-value "")
|
||||
(set-status (if focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
[focused?])
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(set-value "")
|
||||
(set-status (if focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
[focused?])
|
||||
on-scan (when on-scan (rn/use-callback #(on-scan set-value)))
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(when (= (count @value) 0)
|
||||
(set-status :active))
|
||||
(set-focused true)
|
||||
(when on-focus (on-focus))))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(when (= status :active)
|
||||
(set-status :default))
|
||||
(set-focused false)
|
||||
(when on-blur (on-blur)))
|
||||
[status])
|
||||
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
|
||||
[status theme blur?])]
|
||||
(rn/use-mount #(on-change (or default-value "")))
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/text-input
|
||||
{:accessibility-label :address-text-input
|
||||
:style (style/input-text theme)
|
||||
:placeholder (i18n/label :t/name-ens-or-address)
|
||||
:placeholder-text-color placeholder-text-color
|
||||
:value @value
|
||||
:auto-complete (when platform/ios? :off)
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
:spell-check false
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:on-change-text on-change}]
|
||||
(when (or (= status :default)
|
||||
(= status :active))
|
||||
[rn/view
|
||||
{:style style/buttons-container
|
||||
:accessibility-label :paste-scan-buttons-container}
|
||||
[button/button
|
||||
{:accessibility-label :paste-button
|
||||
:type :outline
|
||||
:size 24
|
||||
:container-style {:margin-right 8}
|
||||
:inner-style (style/accessory-button blur? theme)
|
||||
:on-press on-paste}
|
||||
(i18n/label :t/paste)]
|
||||
(when on-scan
|
||||
[button/button
|
||||
{:accessibility-label :scan-button
|
||||
:icon-only? true
|
||||
:type :outline
|
||||
:size 24
|
||||
:inner-style (style/accessory-button blur? theme)
|
||||
:on-press on-scan}
|
||||
:main-icons/scan])])
|
||||
(when (= status :typing)
|
||||
[rn/view
|
||||
{:style style/buttons-container
|
||||
:accessibility-label :clear-button-container}
|
||||
[clear-button
|
||||
{:on-press on-clear
|
||||
:blur? blur?
|
||||
:theme theme}]])
|
||||
(when (and (= status :loading) (not valid-ens-or-address?))
|
||||
[rn/view
|
||||
{:style style/buttons-container
|
||||
:accessibility-label :loading-button-container}
|
||||
[loading-icon blur? theme]])
|
||||
(when (and (= status :loading) valid-ens-or-address?)
|
||||
[rn/view
|
||||
{:style style/buttons-container
|
||||
:accessibility-label :positive-button-container}
|
||||
[positive-state-icon theme]])]))
|
||||
(defn- f-address-input-internal
|
||||
[]
|
||||
(let [status (reagent/atom :default)
|
||||
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 on-detect-unclassified address-regex ens-regex
|
||||
valid-ens-or-address? container-style]}]
|
||||
(let [on-change (fn [text]
|
||||
(when (not= @value text)
|
||||
(let [address? (when address-regex
|
||||
(boolean (re-matches address-regex text)))
|
||||
ens? (when ens-regex
|
||||
(boolean (re-matches ens-regex text)))]
|
||||
(if (> (count text) 0)
|
||||
(reset! status :typing)
|
||||
(reset! status :active))
|
||||
(reset! value text)
|
||||
(when on-change-text
|
||||
(on-change-text text))
|
||||
(when (and on-detect-ens ens?)
|
||||
(reset! status :loading)
|
||||
(on-detect-ens text #(reset! status :typing)))
|
||||
(when (and address? on-detect-address)
|
||||
(reset! status :loading)
|
||||
(on-detect-address text))
|
||||
(when (and (not address?)
|
||||
(not ens?)
|
||||
on-detect-unclassified)
|
||||
(on-detect-unclassified text)))))
|
||||
on-paste (fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard]
|
||||
(when-not (empty? clipboard)
|
||||
(on-change clipboard)
|
||||
(reset! value clipboard)))))
|
||||
on-clear (fn []
|
||||
(reset! value "")
|
||||
(reset! status (if @focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
on-scan #(when on-scan
|
||||
(on-scan))
|
||||
on-focus (fn []
|
||||
(when (= (count @value) 0)
|
||||
(reset! status :active))
|
||||
(reset! focused? true)
|
||||
(when on-focus (on-focus)))
|
||||
on-blur (fn []
|
||||
(when (= @status :active)
|
||||
(reset! status :default))
|
||||
(reset! focused? false)
|
||||
(when on-blur (on-blur)))
|
||||
placeholder-text-color (get-placeholder-text-color @status theme blur?)]
|
||||
(rn/use-effect (fn []
|
||||
(when-not (empty? scanned-value)
|
||||
(on-change scanned-value)))
|
||||
[scanned-value])
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/text-input
|
||||
{:accessibility-label :address-text-input
|
||||
:style (style/input-text theme)
|
||||
:placeholder (i18n/label :t/name-ens-or-address)
|
||||
:placeholder-text-color placeholder-text-color
|
||||
:default-value @value
|
||||
:auto-complete (when platform/ios? :off)
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
:spell-check false
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:on-change-text on-change}]
|
||||
(when (or (= @status :default)
|
||||
(= @status :active))
|
||||
[rn/view
|
||||
{:style style/buttons-container
|
||||
:accessibility-label :paste-scan-buttons-container}
|
||||
[button/button
|
||||
{:accessibility-label :paste-button
|
||||
:type :outline
|
||||
:size 24
|
||||
:container-style {:margin-right 8}
|
||||
:inner-style (style/accessory-button blur? theme)
|
||||
:on-press on-paste}
|
||||
(i18n/label :t/paste)]
|
||||
[button/button
|
||||
{:accessibility-label :scan-button
|
||||
:icon-only? true
|
||||
:type :outline
|
||||
:size 24
|
||||
:inner-style (style/accessory-button blur? theme)
|
||||
:on-press on-scan}
|
||||
:main-icons/scan]])
|
||||
(when (= @status :typing)
|
||||
[rn/view
|
||||
{:style style/buttons-container
|
||||
:accessibility-label :clear-button-container}
|
||||
[clear-button
|
||||
{:on-press on-clear
|
||||
:blur? blur?
|
||||
:theme theme}]])
|
||||
(when (and (= @status :loading) (not valid-ens-or-address?))
|
||||
[rn/view
|
||||
{:style style/buttons-container
|
||||
:accessibility-label :loading-button-container}
|
||||
[loading-icon blur? theme]])
|
||||
(when (and (= @status :loading) valid-ens-or-address?)
|
||||
[rn/view
|
||||
{:style style/buttons-container
|
||||
:accessibility-label :positive-button-container}
|
||||
[positive-state-icon theme]])]))))
|
||||
|
||||
(defn address-input-internal
|
||||
[props]
|
||||
[:f> f-address-input-internal props])
|
||||
|
||||
(def address-input
|
||||
(quo.theme/with-theme address-input-internal))
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]))
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- label-&-counter
|
||||
[{:keys [label current-chars char-limit variant-colors]}]
|
||||
@@ -60,104 +61,99 @@
|
||||
:container-style])
|
||||
|
||||
(defn- base-input
|
||||
[{:keys [blur? theme error? right-icon left-icon disabled? small? button
|
||||
label char-limit multiline? clearable? on-focus on-blur container-style
|
||||
on-change-text on-char-limit-reach weight default-value]
|
||||
:as props}]
|
||||
(let [[status set-status] (rn/use-state :default)
|
||||
internal-on-focus (rn/use-callback #(set-status :focus))
|
||||
internal-on-blur (rn/use-callback #(set-status :default))
|
||||
[multiple-lines?
|
||||
set-multiple-lines] (rn/use-state false)
|
||||
on-content-size-change (rn/use-callback
|
||||
(fn [event]
|
||||
(let [height (oops/oget event "nativeEvent.contentSize.height")
|
||||
;; In Android height comes with padding
|
||||
min-height (if platform/android? 40 22)]
|
||||
(if (> height min-height)
|
||||
(set-multiple-lines true)
|
||||
(set-multiple-lines false)))))
|
||||
[char-count
|
||||
set-char-count] (rn/use-state (count default-value))
|
||||
on-change-text (rn/use-callback
|
||||
(fn [new-text]
|
||||
(when on-change-text (on-change-text new-text))
|
||||
(let [amount-chars (count new-text)]
|
||||
(set-char-count amount-chars)
|
||||
(when (and (>= amount-chars char-limit) on-char-limit-reach)
|
||||
(on-char-limit-reach amount-chars)))))
|
||||
status-kw (cond
|
||||
disabled? :disabled
|
||||
error? :error
|
||||
:else status)
|
||||
colors-by-status (style/status-colors status-kw blur? theme)
|
||||
variant-colors (style/variants-colors blur? theme)
|
||||
clean-props (apply dissoc props custom-props)]
|
||||
[rn/view {:style container-style}
|
||||
(when (or label char-limit)
|
||||
[label-&-counter
|
||||
{:variant-colors variant-colors
|
||||
:label label
|
||||
:current-chars char-count
|
||||
:char-limit char-limit}])
|
||||
[rn/view {:style (style/input-container colors-by-status small? disabled?)}
|
||||
(when-let [{:keys [icon-name]} left-icon]
|
||||
[left-accessory
|
||||
{:variant-colors variant-colors
|
||||
:small? small?
|
||||
:icon-name icon-name}])
|
||||
[rn/text-input
|
||||
(cond-> {:style (style/input colors-by-status small? multiple-lines? weight)
|
||||
:accessibility-label :input
|
||||
:placeholder-text-color (:placeholder colors-by-status)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:cursor-color (:cursor variant-colors)
|
||||
:editable (not disabled?)
|
||||
:on-focus (fn []
|
||||
(when on-focus (on-focus))
|
||||
(internal-on-focus))
|
||||
:on-blur (fn []
|
||||
(when on-blur (on-blur))
|
||||
(internal-on-blur))}
|
||||
:always (merge clean-props)
|
||||
multiline? (assoc :multiline true
|
||||
:on-content-size-change on-content-size-change)
|
||||
char-limit (assoc :on-change-text on-change-text))]
|
||||
(when-let [{:keys [on-press icon-name style-fn]} right-icon]
|
||||
[right-accessory
|
||||
{:variant-colors variant-colors
|
||||
:small? small?
|
||||
:disabled? disabled?
|
||||
:icon-style-fn style-fn
|
||||
:icon-name icon-name
|
||||
:on-press (fn []
|
||||
(when clearable? (set-char-count 0))
|
||||
(on-press))}])
|
||||
(when-let [{:keys [on-press text]} button]
|
||||
[right-button
|
||||
{:colors-by-status colors-by-status
|
||||
:variant-colors variant-colors
|
||||
:small? small?
|
||||
:disabled? disabled?
|
||||
:on-press on-press
|
||||
:text text}])]]))
|
||||
[{:keys [on-change-text on-char-limit-reach weight default-value]}]
|
||||
(let [status (reagent/atom :default)
|
||||
internal-on-focus #(reset! status :focus)
|
||||
internal-on-blur #(reset! status :default)
|
||||
multiple-lines? (reagent/atom false)
|
||||
set-multiple-lines! #(let [height (oops/oget % "nativeEvent.contentSize.height")
|
||||
;; In Android height comes with padding
|
||||
min-height (if platform/android? 40 22)]
|
||||
(if (> height min-height)
|
||||
(reset! multiple-lines? true)
|
||||
(reset! multiple-lines? false)))
|
||||
char-count (reagent/atom (count default-value))
|
||||
update-char-limit! (fn [new-text char-limit]
|
||||
(when on-change-text (on-change-text new-text))
|
||||
(let [amount-chars (count new-text)]
|
||||
(reset! char-count amount-chars)
|
||||
(when (and (>= amount-chars char-limit) on-char-limit-reach)
|
||||
(on-char-limit-reach amount-chars))))]
|
||||
(fn [{:keys [blur? theme error? right-icon left-icon disabled? small? button
|
||||
label char-limit multiline? clearable? on-focus on-blur container-style]
|
||||
:as props}]
|
||||
(let [status-kw (cond
|
||||
disabled? :disabled
|
||||
error? :error
|
||||
:else @status)
|
||||
colors-by-status (style/status-colors status-kw blur? theme)
|
||||
variant-colors (style/variants-colors blur? theme)
|
||||
clean-props (apply dissoc props custom-props)]
|
||||
[rn/view {:style container-style}
|
||||
(when (or label char-limit)
|
||||
[label-&-counter
|
||||
{:variant-colors variant-colors
|
||||
:label label
|
||||
:current-chars @char-count
|
||||
:char-limit char-limit}])
|
||||
[rn/view {:style (style/input-container colors-by-status small? disabled?)}
|
||||
(when-let [{:keys [icon-name]} left-icon]
|
||||
[left-accessory
|
||||
{:variant-colors variant-colors
|
||||
:small? small?
|
||||
:icon-name icon-name}])
|
||||
[rn/text-input
|
||||
(cond-> {:style (style/input colors-by-status small? @multiple-lines? weight)
|
||||
:accessibility-label :input
|
||||
:placeholder-text-color (:placeholder colors-by-status)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:cursor-color (:cursor variant-colors)
|
||||
:editable (not disabled?)
|
||||
:on-focus (fn []
|
||||
(when on-focus (on-focus))
|
||||
(internal-on-focus))
|
||||
:on-blur (fn []
|
||||
(when on-blur (on-blur))
|
||||
(internal-on-blur))}
|
||||
:always (merge clean-props)
|
||||
multiline? (assoc :multiline true
|
||||
:on-content-size-change set-multiple-lines!)
|
||||
char-limit (assoc :on-change-text #(update-char-limit! % char-limit)))]
|
||||
(when-let [{:keys [on-press icon-name style-fn]} right-icon]
|
||||
[right-accessory
|
||||
{:variant-colors variant-colors
|
||||
:small? small?
|
||||
:disabled? disabled?
|
||||
:icon-style-fn style-fn
|
||||
:icon-name icon-name
|
||||
:on-press (fn []
|
||||
(when clearable? (reset! char-count 0))
|
||||
(on-press))}])
|
||||
(when-let [{:keys [on-press text]} button]
|
||||
[right-button
|
||||
{:colors-by-status colors-by-status
|
||||
:variant-colors variant-colors
|
||||
:small? small?
|
||||
:disabled? disabled?
|
||||
:on-press on-press
|
||||
:text text}])]]))))
|
||||
|
||||
(defn- password-input
|
||||
[{:keys [default-shown?]
|
||||
:or {default-shown? false}
|
||||
:as props}]
|
||||
(let [[password-shown? set-password-shown] (rn/use-state default-shown?)]
|
||||
[base-input
|
||||
(assoc props
|
||||
:accessibility-label :password-input
|
||||
:auto-capitalize :none
|
||||
:auto-complete :password
|
||||
:secure-text-entry (not password-shown?)
|
||||
:right-icon {:style-fn style/password-icon
|
||||
:icon-name (if password-shown? :i/hide-password :i/reveal)
|
||||
:on-press #(set-password-shown (not password-shown?))})]))
|
||||
:or {default-shown? false}}]
|
||||
(let [password-shown? (reagent/atom default-shown?)]
|
||||
(fn [props]
|
||||
[base-input
|
||||
(assoc props
|
||||
:accessibility-label :password-input
|
||||
:auto-capitalize :none
|
||||
:auto-complete :password
|
||||
:secure-text-entry (not @password-shown?)
|
||||
:right-icon {:style-fn style/password-icon
|
||||
:icon-name (if @password-shown? :i/hide-password :i/reveal)
|
||||
:on-press #(swap! password-shown? not)})])))
|
||||
|
||||
(defn input
|
||||
(defn input-internal
|
||||
"This input supports the following properties:
|
||||
- :type - Can be `:text`(default) or `:password`.
|
||||
- :blur? - Boolean to set the blur color variant.
|
||||
@@ -181,15 +177,21 @@
|
||||
- :on-change-text
|
||||
...
|
||||
"
|
||||
[{:keys [type clearable? on-clear icon-name]
|
||||
[{:keys [type clearable? on-clear on-change-text icon-name]
|
||||
:or {type :text}
|
||||
:as props}]
|
||||
(let [base-props (cond-> props
|
||||
icon-name (assoc-in [:left-icon :icon-name] icon-name)
|
||||
clearable? (assoc :right-icon
|
||||
{:style-fn style/clear-icon
|
||||
:icon-name :i/clear
|
||||
:on-press #(when on-clear (on-clear))}))]
|
||||
icon-name (assoc-in [:left-icon :icon-name] icon-name)
|
||||
clearable? (assoc :right-icon
|
||||
{:style-fn style/clear-icon
|
||||
:icon-name :i/clear
|
||||
:on-press #(when on-clear (on-clear))})
|
||||
on-change-text (assoc :on-change-text
|
||||
(fn [new-text]
|
||||
(on-change-text new-text)
|
||||
(reagent/flush))))]
|
||||
(if (= type :password)
|
||||
[password-input base-props]
|
||||
[base-input base-props])))
|
||||
|
||||
(def input (quo.theme/with-theme input-internal))
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
{:keys [ok-words error-words]} (group-by #(if (string? %) :ok-words :error-words)
|
||||
children-text-nodes)]
|
||||
(h/is-equal (apply str ok-words) "Text with some that the ")
|
||||
(h/is-truthy (= (map #(-> % :props :argv first) error-words)
|
||||
(h/is-truthy (= (map #(-> % :props :argv second) error-words)
|
||||
["error" "words" "don't" "satisfy" "predicate"]))))
|
||||
|
||||
(h/test "Marked when words exceed the limit given"
|
||||
@@ -55,7 +55,7 @@
|
||||
(h/is-equal (string/trim (apply str ok-words))
|
||||
"these are ok words,")
|
||||
(h/is-equal (->> error-words
|
||||
(map #(-> % :props :argv first))
|
||||
(map #(-> % :props :argv second))
|
||||
(interpose " ")
|
||||
(apply str))
|
||||
"these words exceed the limit")))))
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
[clojure.string :as string]
|
||||
[quo.components.inputs.recovery-phrase.style :as style]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def ^:private custom-props
|
||||
[:customization-color :theme :blur? :cursor-color :multiline :on-focus :on-blur
|
||||
@@ -37,42 +38,42 @@
|
||||
:idx 0})
|
||||
:result)))
|
||||
|
||||
(defn recovery-phrase-input
|
||||
[{:keys [customization-color blur? on-focus on-blur mark-errors?
|
||||
error-pred-current-word error-pred-written-words word-limit
|
||||
container-style]
|
||||
:or {customization-color :blue
|
||||
word-limit ##Inf
|
||||
error-pred-current-word (constantly false)
|
||||
error-pred-written-words (constantly false)}
|
||||
:as props}
|
||||
text]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[state set-state] (rn/use-state :default)
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(set-state :focused)
|
||||
(when on-focus (on-focus))))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(set-state :default)
|
||||
(when on-blur (on-blur))))
|
||||
extra-props (apply dissoc props custom-props)]
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/text-input
|
||||
(merge {:accessibility-label :recovery-phrase-input
|
||||
:style (style/input)
|
||||
:placeholder-text-color (style/placeholder-color state theme blur?)
|
||||
:cursor-color (style/cursor-color customization-color theme)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:multiline true
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur}
|
||||
extra-props)
|
||||
(if mark-errors?
|
||||
(mark-error-words {:pred-last-word error-pred-current-word
|
||||
:pred-previous-words error-pred-written-words
|
||||
:text text
|
||||
:word-limit word-limit
|
||||
:theme theme})
|
||||
text)]]))
|
||||
(defn recovery-phrase-input-internal
|
||||
[_ _]
|
||||
(let [state (reagent/atom :default)
|
||||
set-focused #(reset! state :focused)
|
||||
set-default #(reset! state :default)]
|
||||
(fn [{:keys [customization-color theme blur? on-focus on-blur mark-errors?
|
||||
error-pred-current-word error-pred-written-words word-limit
|
||||
container-style]
|
||||
:or {customization-color :blue
|
||||
word-limit ##Inf
|
||||
error-pred-current-word (constantly false)
|
||||
error-pred-written-words (constantly false)}
|
||||
:as props}
|
||||
text]
|
||||
(let [extra-props (apply dissoc props custom-props)]
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/text-input
|
||||
(merge {:accessibility-label :recovery-phrase-input
|
||||
:style (style/input)
|
||||
:placeholder-text-color (style/placeholder-color @state theme blur?)
|
||||
:cursor-color (style/cursor-color customization-color theme)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:multiline true
|
||||
:on-focus (fn []
|
||||
(set-focused)
|
||||
(when on-focus (on-focus)))
|
||||
:on-blur (fn []
|
||||
(set-default)
|
||||
(when on-blur (on-blur)))}
|
||||
extra-props)
|
||||
(if mark-errors?
|
||||
(mark-error-words {:pred-last-word error-pred-current-word
|
||||
:pred-previous-words error-pred-written-words
|
||||
:text text
|
||||
:word-limit word-limit
|
||||
:theme theme})
|
||||
text)]]))))
|
||||
|
||||
(def recovery-phrase-input (quo.theme/with-theme recovery-phrase-input-internal))
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.inputs.search-input.style :as style]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(def ^:private tag-separator [rn/view {:style style/tag-separator}])
|
||||
|
||||
@@ -40,52 +41,54 @@
|
||||
text-input))
|
||||
|
||||
(defn search-input
|
||||
[{:keys [value tags disabled? blur? on-change-text customization-color
|
||||
on-clear on-focus on-blur override-theme container-style]
|
||||
:or {customization-color :blue}
|
||||
:as props}
|
||||
& children]
|
||||
(let [[state set-state] (rn/use-state :default)
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(set-state :active)
|
||||
(when on-focus (on-focus))))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(set-state :default)
|
||||
(when on-blur (on-blur))))
|
||||
scroll-view-ref (rn/use-ref-atom nil)
|
||||
on-scroll-view-ref (rn/use-callback #(reset! scroll-view-ref %))
|
||||
on-key-press (rn/use-callback #(handle-backspace % @scroll-view-ref))
|
||||
use-value? (boolean value)
|
||||
clean-props (apply dissoc props props-to-remove)]
|
||||
[rn/view
|
||||
{:accessibility-label :search-input
|
||||
:style (style/container container-style)}
|
||||
[rn/scroll-view
|
||||
{:ref on-scroll-view-ref
|
||||
:style style/scroll-container
|
||||
:content-container-style style/scroll-content
|
||||
:horizontal true
|
||||
:shows-horizontal-scroll-indicator false}
|
||||
(when (seq tags)
|
||||
[inner-tags tags])
|
||||
(add-children
|
||||
[rn/text-input
|
||||
(cond-> {:style (style/input-text disabled?)
|
||||
:cursor-color (style/cursor customization-color override-theme)
|
||||
:placeholder-text-color (style/placeholder-color state blur? override-theme)
|
||||
:editable (not disabled?)
|
||||
:on-key-press on-key-press
|
||||
:keyboard-appearance (colors/theme-colors :light :dark override-theme)
|
||||
:on-change-text on-change-text
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur}
|
||||
use-value? (assoc :value value)
|
||||
(seq clean-props) (merge clean-props))]
|
||||
(when-not use-value? children))]
|
||||
(when (or (seq value) (seq children))
|
||||
[clear-button
|
||||
{:on-press on-clear
|
||||
:blur? blur?
|
||||
:override-theme override-theme}])]))
|
||||
[{:keys [value]}]
|
||||
(let [state (reagent/atom :default)
|
||||
set-active #(reset! state :active)
|
||||
set-default #(reset! state :default)
|
||||
scroll-view-ref (atom nil)
|
||||
use-value? (boolean value)]
|
||||
(fn [{:keys [value tags disabled? blur? on-change-text customization-color
|
||||
on-clear on-focus on-blur override-theme container-style]
|
||||
:or {customization-color :blue}
|
||||
:as props}
|
||||
& children]
|
||||
(let [clean-props (apply dissoc props props-to-remove)]
|
||||
[rn/view
|
||||
{:accessibility-label :search-input
|
||||
:style (style/container container-style)}
|
||||
[rn/scroll-view
|
||||
{:ref #(reset! scroll-view-ref %)
|
||||
:style style/scroll-container
|
||||
:content-container-style style/scroll-content
|
||||
:horizontal true
|
||||
:shows-horizontal-scroll-indicator false}
|
||||
(when (seq tags)
|
||||
[inner-tags tags])
|
||||
|
||||
(add-children
|
||||
[rn/text-input
|
||||
(cond-> {:style (style/input-text disabled?)
|
||||
:cursor-color (style/cursor customization-color override-theme)
|
||||
:placeholder-text-color (style/placeholder-color @state blur? override-theme)
|
||||
:editable (not disabled?)
|
||||
:on-key-press #(handle-backspace % @scroll-view-ref)
|
||||
:keyboard-appearance (colors/theme-colors :light :dark override-theme)
|
||||
:on-change-text (fn [new-text]
|
||||
(when on-change-text
|
||||
(on-change-text new-text))
|
||||
(reagent/flush))
|
||||
:on-focus (fn []
|
||||
(set-active)
|
||||
(when on-focus (on-focus)))
|
||||
:on-blur (fn []
|
||||
(set-default)
|
||||
(when on-blur (on-blur)))}
|
||||
use-value? (assoc :value value)
|
||||
(seq clean-props) (merge clean-props))]
|
||||
(when-not use-value? children))]
|
||||
|
||||
(when (or (seq value) (seq children))
|
||||
[clear-button
|
||||
{:on-press on-clear
|
||||
:blur? blur?
|
||||
:override-theme override-theme}])]))))
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
[quo.components.inputs.title-input.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- pad-0
|
||||
[value]
|
||||
@@ -12,70 +13,81 @@
|
||||
(str 0 value)
|
||||
value))
|
||||
|
||||
(defn view
|
||||
[{:keys [blur? on-change-text auto-focus placeholder max-length default-value return-key-type
|
||||
size on-focus on-blur container-style customization-color disabled?]
|
||||
(defn- view-internal
|
||||
[{:keys [blur?
|
||||
on-change-text
|
||||
auto-focus
|
||||
placeholder
|
||||
max-length
|
||||
default-value
|
||||
return-key-type
|
||||
size
|
||||
theme
|
||||
on-focus
|
||||
on-blur
|
||||
container-style]
|
||||
:or {max-length 0
|
||||
auto-focus false
|
||||
default-value ""}}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[focused? set-focused] (rn/use-state auto-focus)
|
||||
[value set-value] (rn/use-state default-value)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
on-inpur-ref (rn/use-callback #(reset! input-ref %))
|
||||
on-press (rn/use-callback
|
||||
#(when-not disabled? (.focus ^js @input-ref))
|
||||
[disabled?])
|
||||
on-change (rn/use-callback
|
||||
(fn [v]
|
||||
(set-value v)
|
||||
(when on-change-text (on-change-text v))))
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(when (fn? on-focus) (on-focus))
|
||||
(set-focused true)))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(when (fn? on-blur) (on-blur))
|
||||
(set-focused false)))]
|
||||
[rn/view
|
||||
{:style (merge (style/container disabled?) container-style)}
|
||||
[rn/view {:style style/text-input-container}
|
||||
[rn/text-input
|
||||
{:style (text/text-style
|
||||
{:size (or size :heading-1)
|
||||
:weight :semi-bold
|
||||
:style (style/title-text theme)})
|
||||
:default-value default-value
|
||||
:accessibility-label :profile-title-input
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:return-key-type return-key-type
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur
|
||||
:auto-focus auto-focus
|
||||
:input-mode :text
|
||||
:on-change-text on-change
|
||||
:editable (not disabled?)
|
||||
:max-length max-length
|
||||
:placeholder placeholder
|
||||
:ref on-inpur-ref
|
||||
:selection-color (style/get-selection-color customization-color blur? theme)
|
||||
:placeholder-text-color (if focused?
|
||||
(style/get-focused-placeholder-color blur? theme)
|
||||
(style/get-placeholder-color blur? theme))}]]
|
||||
[rn/view
|
||||
{:style (style/counter-container focused?)}
|
||||
(if focused?
|
||||
[text/text
|
||||
[text/text
|
||||
{:style (style/char-count blur? theme)
|
||||
:size :paragraph-2}
|
||||
(pad-0
|
||||
(str
|
||||
(count value)))]
|
||||
[text/text
|
||||
{:style (style/char-count blur? theme)
|
||||
:size :paragraph-2}
|
||||
(str "/" (pad-0 (str max-length)))]]
|
||||
[rn/pressable {:on-press on-press}
|
||||
[icon/icon :i/edit {:color (style/get-char-count-color blur? theme)}]])]]))
|
||||
(let [focused? (reagent/atom auto-focus)
|
||||
value (reagent/atom default-value)
|
||||
input-ref (atom nil)
|
||||
on-change (fn [v]
|
||||
(reset! value v)
|
||||
(when on-change-text
|
||||
(on-change-text v)))]
|
||||
(fn [{:keys [customization-color disabled?]}]
|
||||
[rn/view
|
||||
{:style (merge (style/container disabled?) container-style)}
|
||||
[rn/view {:style style/text-input-container}
|
||||
[rn/text-input
|
||||
{:style
|
||||
(text/text-style
|
||||
{:size (or size :heading-1)
|
||||
:weight :semi-bold
|
||||
:style (style/title-text theme)})
|
||||
:default-value default-value
|
||||
:accessibility-label :profile-title-input
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:return-key-type return-key-type
|
||||
:on-focus (fn []
|
||||
(when (fn? on-focus)
|
||||
(on-focus))
|
||||
(reset! focused? true))
|
||||
:on-blur (fn []
|
||||
(when (fn? on-blur)
|
||||
(on-blur))
|
||||
(reset! focused? false))
|
||||
:auto-focus auto-focus
|
||||
:input-mode :text
|
||||
:on-change-text on-change
|
||||
:editable (not disabled?)
|
||||
:max-length max-length
|
||||
:placeholder placeholder
|
||||
:ref #(reset! input-ref %)
|
||||
:selection-color (style/get-selection-color customization-color blur? theme)
|
||||
:placeholder-text-color (if @focused?
|
||||
(style/get-focused-placeholder-color blur? theme)
|
||||
(style/get-placeholder-color blur? theme))}]]
|
||||
[rn/view
|
||||
{:style (style/counter-container @focused?)}
|
||||
(if @focused?
|
||||
[text/text
|
||||
[text/text
|
||||
{:style (style/char-count blur? theme)
|
||||
:size :paragraph-2}
|
||||
(pad-0
|
||||
(str
|
||||
(count @value)))]
|
||||
[text/text
|
||||
{:style (style/char-count blur? theme)
|
||||
:size :paragraph-2}
|
||||
(str "/"
|
||||
(pad-0
|
||||
(str max-length)))]]
|
||||
[rn/pressable
|
||||
{:on-press #(when-not disabled?
|
||||
(.focus ^js @input-ref))}
|
||||
[icon/icon :i/edit {:color (style/get-char-count-color blur? theme)}]])]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -6,101 +6,71 @@
|
||||
|
||||
(def ^:private theme :light)
|
||||
|
||||
(def ^:private default-props
|
||||
{:account-props {:name "Account name"
|
||||
:address "0x1234567890"
|
||||
:emoji "🍑"
|
||||
:customization-color "blue"}})
|
||||
|
||||
(defn- with-defaults
|
||||
([] default-props)
|
||||
([props] (merge default-props props)))
|
||||
|
||||
(h/describe "List items: account"
|
||||
(h/test "default render'"
|
||||
(h/render-with-theme-provider [account/view (with-defaults)] theme)
|
||||
(h/render-with-theme-provider [account/view] theme)
|
||||
(h/is-truthy (h/query-by-label-text :container)))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed"
|
||||
(h/render-with-theme-provider [account/view (with-defaults)] theme)
|
||||
(h/render-with-theme-provider [account/view] theme)
|
||||
(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)})))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed with blur? enabled"
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:blur? true})] theme)
|
||||
(h/render-with-theme-provider [account/view {:blur? true}] theme)
|
||||
(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/white-opa-5})))
|
||||
|
||||
(h/test "render with state :active"
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:state :active})] theme)
|
||||
(h/render-with-theme-provider [account/view {:state :active}] theme)
|
||||
(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/resolve-color :blue :light 10)}))
|
||||
|
||||
(h/test "render with state :active and blur? enabled"
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults
|
||||
{:blur? true
|
||||
:state :active})]
|
||||
{:blur? true
|
||||
:state :active}]
|
||||
theme)
|
||||
(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor colors/white-opa-10}))
|
||||
|
||||
(h/test "render with state :selected"
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:state :selected})] theme)
|
||||
(h/render-with-theme-provider [account/view {:state :selected}] theme)
|
||||
(h/is-truthy (h/query-by-label-text :check-icon)))
|
||||
|
||||
(h/test "calls on-press"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:on-press on-press})] theme)
|
||||
(h/render-with-theme-provider [account/view {:on-press on-press}] theme)
|
||||
(h/fire-event :on-press (h/get-by-label-text :container))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "renders token props if type :tag"
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults {:type :tag
|
||||
:token-props {:symbol "SNT"
|
||||
:value "1,000"}})]
|
||||
theme)
|
||||
(h/render-with-theme-provider [account/view {:type :tag}] theme)
|
||||
(h/is-truthy (h/query-by-label-text :tag-container)))
|
||||
|
||||
(h/test "renders keycard icon if title-icon is present"
|
||||
(h/render-with-theme-provider [account/view (with-defaults {:title-icon :i/placeholder})] theme)
|
||||
(h/render-with-theme-provider [account/view {:title-icon :i/placeholder}] theme)
|
||||
(h/is-truthy (h/query-by-label-text :title-icon)))
|
||||
|
||||
(h/test "doesn't render keycard icon if title-icon is missing"
|
||||
(h/render-with-theme-provider [account/view (with-defaults)] theme)
|
||||
(h/render-with-theme-provider [account/view] theme)
|
||||
(h/is-falsy (h/query-by-label-text :title-icon)))
|
||||
|
||||
(h/test "renders balance container but not arrow icon if type :balance-neutral"
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults {:type :balance-neutral
|
||||
:balance-props {:fiat-value "€0.00"
|
||||
:percentage-change "0.0"
|
||||
:fiat-change "€0.00"}})]
|
||||
theme)
|
||||
(h/render-with-theme-provider [account/view {:type :balance-neutral}] theme)
|
||||
(h/is-truthy (h/query-by-label-text :balance-container))
|
||||
(h/is-falsy (h/query-by-label-text :arrow-icon)))
|
||||
|
||||
(h/test "renders balance container and negative arrow icon if type :balance-negative"
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults {:type :balance-negative
|
||||
:balance-props {:fiat-value "€0.00"
|
||||
:percentage-change "0.0"
|
||||
:fiat-change "€0.00"}})]
|
||||
theme)
|
||||
(h/render-with-theme-provider [account/view {:type :balance-negative}] theme)
|
||||
(h/is-truthy (h/query-by-label-text :balance-container))
|
||||
(h/is-truthy (h/query-by-label-text :icon-negative))
|
||||
(h/is-falsy (h/query-by-label-text :icon-positive)))
|
||||
|
||||
(h/test "renders balance container and positive arrow icon if type :balance-positive"
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults {:type :balance-positive
|
||||
:balance-props {:fiat-value "€0.00"
|
||||
:percentage-change "0.0"
|
||||
:fiat-change "€0.00"}})]
|
||||
theme)
|
||||
(h/render-with-theme-provider [account/view {:type :balance-positive}] theme)
|
||||
(h/is-truthy (h/query-by-label-text :balance-container))
|
||||
(h/is-falsy (h/query-by-label-text :icon-negative))
|
||||
(h/is-truthy (h/query-by-label-text :icon-positive)))
|
||||
@@ -108,9 +78,8 @@
|
||||
(h/test "renders options button if type :action"
|
||||
(let [on-options-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider [account/view
|
||||
(with-defaults
|
||||
{:type :action
|
||||
:on-options-press on-options-press})]
|
||||
{:type :action
|
||||
:on-options-press on-options-press}]
|
||||
theme)
|
||||
(h/is-truthy (h/query-by-label-text :options-button))
|
||||
(h/fire-event :on-press (h/get-by-label-text :options-button))
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
(ns quo.components.list-items.account.schema)
|
||||
|
||||
(def ^:private ?balance
|
||||
[:map
|
||||
[:balance-props
|
||||
[:map
|
||||
[:fiat-value :string]
|
||||
[:percentage-change :string]
|
||||
[:fiat-change :string]]]])
|
||||
|
||||
(def ^:private ?tag
|
||||
[:map
|
||||
[:token-props
|
||||
[:map
|
||||
[:symbol :string]
|
||||
[:value :string]]]])
|
||||
|
||||
(def ^:private ?action
|
||||
[:map
|
||||
[:on-options-press {:optional true} [:maybe fn?]]])
|
||||
|
||||
(def ^:private ?base
|
||||
[:map
|
||||
[:type {:optional true}
|
||||
[:enum :default :tag :action :balance-neutral :balance-negative :balance-positive]]
|
||||
[:state {:optional true} [:enum :default :selected :active]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:theme :schema.common/theme]
|
||||
[:title-icon {:optional true} [:maybe :keyword]]
|
||||
[:account-props
|
||||
[:map
|
||||
[:name :string]
|
||||
[:address :string]
|
||||
[:emoji :string]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:multi {:dispatch :type}
|
||||
[:balance-neutral [:merge ?base ?balance]]
|
||||
[:balance-negative [:merge ?base ?balance]]
|
||||
[:balance-positive [:merge ?base ?balance]]
|
||||
[:tag [:merge ?base ?tag]]
|
||||
[:action [:merge ?base ?action]]
|
||||
[:default ?base]
|
||||
[:malli.core/default ?base]]]
|
||||
:any])
|
||||
@@ -2,15 +2,13 @@
|
||||
(:require
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.account.schema :as component-schema]
|
||||
[quo.components.list-items.account.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.wallet.address-text.view :as address-text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]))
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- account-view
|
||||
[{:keys [account-props title-icon blur? theme]}]
|
||||
@@ -132,6 +130,4 @@
|
||||
(and (= type :default) (= state :selected))
|
||||
[check-icon props])]])))
|
||||
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -13,9 +13,9 @@
|
||||
|
||||
(h/describe "List items: account list card"
|
||||
(h/test "Test icon renders for ':action :icon'"
|
||||
(h/render-with-theme-provider [account-list-card/view
|
||||
{:account-props account-props
|
||||
:network :ethereum
|
||||
:action :icon
|
||||
:on-options-press (fn [])}])
|
||||
(h/render [account-list-card/view
|
||||
{:account-props account-props
|
||||
:network :ethereum
|
||||
:state :default
|
||||
:action :icon}])
|
||||
(h/is-truthy (h/get-by-label-text :icon))))
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
(ns quo.components.list-items.account-list-card.schema)
|
||||
|
||||
(def ^:private ?base
|
||||
[:map
|
||||
[:action {:optional true} [:enum :icon :none]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:theme :schema.common/theme]
|
||||
[:account-props
|
||||
[:map {:closed true}
|
||||
[:type [:enum :default :watch-only]]
|
||||
[:name :string]
|
||||
[:address :string]
|
||||
[:emoji :string]
|
||||
[:size {:optional true} [:enum 80 :size-64 48 32 28 24 20 16]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]
|
||||
[:networks {:optional true} [:* [:map [:network-name :keyword] [:short-name :string]]]]])
|
||||
|
||||
(def ^:private ?on-option-press
|
||||
[:map
|
||||
[:on-options-press [:maybe fn?]]])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:multi {:dispatch :action}
|
||||
[:icon [:merge ?base ?on-option-press]]
|
||||
[:none ?base]
|
||||
[:malli.core/default ?base]]]
|
||||
:any])
|
||||
@@ -2,15 +2,13 @@
|
||||
(:require
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.account-list-card.schema :as component-schema]
|
||||
[quo.components.list-items.account-list-card.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.wallet.address-text.view :as address-text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]))
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- internal-view
|
||||
[]
|
||||
@@ -41,6 +39,4 @@
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))
|
||||
:accessibility-label :icon}]])])))
|
||||
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -4,36 +4,32 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn- with-defaults
|
||||
([] (with-defaults {}))
|
||||
([props] (merge {:address "0x0ah...78b"} props)))
|
||||
|
||||
(h/describe "List items: address"
|
||||
(h/test "default render"
|
||||
(h/render-with-theme-provider [address/view (with-defaults)])
|
||||
(h/render [address/view])
|
||||
(h/is-truthy (h/query-by-label-text :container)))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed"
|
||||
(h/render-with-theme-provider [address/view (with-defaults)])
|
||||
(h/render [address/view])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/custom-color :blue 50 5)})))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed with blur? enabled"
|
||||
(h/render-with-theme-provider [address/view (with-defaults {:blur? true})])
|
||||
(h/render [address/view {:blur? true}])
|
||||
(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/white-opa-5})))
|
||||
|
||||
(h/test "on-press-out changes state to :active"
|
||||
(h/render-with-theme-provider [address/view (with-defaults {:active-state? true})])
|
||||
(h/render [address/view {:active-state? 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/custom-color :blue 50 10)})))
|
||||
|
||||
(h/test "on-press-out changes state to :active with blur? enabled"
|
||||
(h/render-with-theme-provider [address/view (with-defaults {:active-state? true :blur? true})])
|
||||
(h/render [address/view {:active-state? true :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)
|
||||
@@ -41,6 +37,6 @@
|
||||
|
||||
(h/test "on-press event is called"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider [address/view (with-defaults {:on-press on-press})])
|
||||
(h/render [address/view {:on-press on-press}])
|
||||
(h/fire-event :on-press (h/get-by-label-text :container))
|
||||
(h/was-called on-press))))
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
(ns quo.components.list-items.address.schema)
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map
|
||||
[:address :string]
|
||||
[:networks {:optional true} [:* [:map [:network-name :keyword] [:short-name :string]]]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:blur? {:optional true} [:maybe :boolean]]
|
||||
[:theme :schema.common/theme]
|
||||
[:active-state? {:optional true} [:maybe :boolean]]]]
|
||||
:any])
|
||||
@@ -1,14 +1,12 @@
|
||||
(ns quo.components.list-items.address.view
|
||||
(:require
|
||||
[quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar]
|
||||
(quo.components.list-items.address.schema :as component-schema)
|
||||
[quo.components.list-items.address.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]
|
||||
[utils.address :as address]))
|
||||
|
||||
(defn- left-container
|
||||
@@ -66,7 +64,4 @@
|
||||
:address address
|
||||
:blur? blur?}]]))))
|
||||
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -4,10 +4,6 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[test-helpers.component :as h]))
|
||||
|
||||
(defn- with-defaults
|
||||
([] (with-defaults {}))
|
||||
([props] (merge {:contact-props {:full-name "Thomas Anderson"}} props)))
|
||||
|
||||
(def account
|
||||
{:name "New House"
|
||||
:address "0x21a...49e"
|
||||
@@ -16,33 +12,25 @@
|
||||
|
||||
(h/describe "List items: saved contact address"
|
||||
(h/test "default render"
|
||||
(h/render-with-theme-provider [saved-contact-address/view (with-defaults)])
|
||||
(h/render-with-theme-provider [saved-contact-address/view])
|
||||
(h/is-truthy (h/query-by-label-text :container)))
|
||||
|
||||
(h/test "renders account detail when passing one account"
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 1 account)})])
|
||||
(h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}])
|
||||
(h/is-truthy (h/query-by-label-text :account-container)))
|
||||
|
||||
(h/test "renders account count when passing multiple accounts"
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 2 account)})])
|
||||
(h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 2 account)}])
|
||||
(h/is-truthy (h/query-by-label-text :accounts-count)))
|
||||
|
||||
(h/test "on-press-in changes state to :pressed"
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 1 account)})])
|
||||
(h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :container))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :container)
|
||||
{:backgroundColor (colors/custom-color :blue 50 5)})))
|
||||
|
||||
(h/test "on-press-out changes state to :active if active-state? is true (default value)"
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 1 account)})])
|
||||
(h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}])
|
||||
(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)
|
||||
@@ -50,9 +38,8 @@
|
||||
|
||||
(h/test "on-press-out changes state to :default if active-state? is false"
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:accounts (repeat 1 account)
|
||||
:active-state? false})])
|
||||
{:accounts (repeat 1 account)
|
||||
:active-state? false}])
|
||||
(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)
|
||||
@@ -60,9 +47,9 @@
|
||||
|
||||
(h/test "on-press calls on-press"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider [saved-contact-address/view
|
||||
(with-defaults
|
||||
{:on-press on-press
|
||||
:accounts (repeat 1 account)})])
|
||||
(h/render-with-theme-provider
|
||||
[saved-contact-address/view
|
||||
{:on-press on-press
|
||||
:accounts (repeat 1 account)}])
|
||||
(h/fire-event :on-press (h/get-by-label-text :container))
|
||||
(h/was-called on-press))))
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
(ns quo.components.list-items.saved-contact-address.schema)
|
||||
|
||||
(def ^:private ?contact
|
||||
[:map
|
||||
[:full-name :string]
|
||||
[:profile-picture {:optional true} [:maybe [:or :schema.common/image-source :string]]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]])
|
||||
|
||||
(def ^:private ?account
|
||||
[:map
|
||||
[:name :string]
|
||||
[:address :string]
|
||||
[:emoji {:optional true} :string]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]])
|
||||
|
||||
(def ^:private ?accounts
|
||||
[:+ ?account])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map
|
||||
[:contact-props ?contact]
|
||||
[:accounts {:optional true} ?accounts]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:theme :schema.common/theme]
|
||||
[:active-state? {:optional true} [:maybe :boolean]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]
|
||||
:any])
|
||||
@@ -3,14 +3,12 @@
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.saved-contact-address.schema :as component-schema]
|
||||
[quo.components.list-items.saved-contact-address.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]
|
||||
[utils.address :as address]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
@@ -94,6 +92,4 @@
|
||||
colors/neutral-40
|
||||
theme)}])]))))
|
||||
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -8,36 +8,40 @@
|
||||
{:token :snt
|
||||
:state :default
|
||||
:label "Status"
|
||||
:networks [{:source (resources/get-network :ethereum)}]
|
||||
:networks [(resources/get-network :ethereum)]
|
||||
:token-value "100.00 SNT"
|
||||
:fiat-value "€0.00"})
|
||||
|
||||
(h/describe "List items: Token network"
|
||||
(h/test "default state"
|
||||
(h/render-with-theme-provider [token-network/view (dissoc props :state)])
|
||||
(h/render [token-network/view (dissoc props :state)])
|
||||
(h/is-truthy (h/get-by-text "Status")))
|
||||
|
||||
(h/test "default state explicit"
|
||||
(h/render-with-theme-provider [token-network/view props])
|
||||
(h/render [token-network/view props])
|
||||
(h/is-truthy (h/get-by-text "Status")))
|
||||
|
||||
(h/test "Pressed state"
|
||||
(h/render-with-theme-provider [token-network/view props])
|
||||
(h/render [token-network/view props])
|
||||
(h/fire-event :on-press-in (h/get-by-label-text :token-network))
|
||||
(h/wait-for #(h/has-style (h/query-by-label-text :token-network)
|
||||
{:backgroundColor (colors/resolve-color :blue :light 5)})))
|
||||
|
||||
(h/test "Active state"
|
||||
(h/render-with-theme-provider [token-network/view (assoc props :state :active)])
|
||||
(h/render [token-network/view (assoc props :state :active)])
|
||||
(h/has-style (h/query-by-label-text :token-network)
|
||||
{:backgroundColor (colors/resolve-color :blue :light 10)}))
|
||||
|
||||
(h/test "Selected state"
|
||||
(h/render-with-theme-provider [token-network/view (assoc props :state :selected)])
|
||||
(h/render [token-network/view (assoc props :state :selected)])
|
||||
(h/is-truthy (h/query-by-label-text :check-icon)))
|
||||
|
||||
(h/test "Call on-press"
|
||||
(let [on-press (h/mock-fn)]
|
||||
(h/render-with-theme-provider [token-network/view (assoc props :on-press on-press)])
|
||||
(h/render [token-network/view (assoc props :on-press on-press)])
|
||||
(h/fire-event :on-press (h/get-by-label-text :token-network))
|
||||
(h/was-called on-press))))
|
||||
(h/was-called on-press)))
|
||||
|
||||
(h/test "Empty props"
|
||||
(h/render [token-network/view {}])
|
||||
(h/is-truthy (h/get-by-label-text :token-network))))
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
(ns quo.components.list-items.token-network.schema)
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map
|
||||
[:token :keyword]
|
||||
[:label :string]
|
||||
[:token-value :string]
|
||||
[:fiat-value :string]
|
||||
[:networks [:* [:map [:source :schema.common/image-source]]]]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:state {:optional true} [:enum :default :active :selected]]
|
||||
[:theme :schema.common/theme]]]
|
||||
:any])
|
||||
@@ -2,14 +2,12 @@
|
||||
(:require
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.preview-list.view :as preview-list]
|
||||
[quo.components.list-items.token-network.schema :as component-schema]
|
||||
[quo.components.list-items.token-network.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]))
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- info
|
||||
[{:keys [token label networks]}]
|
||||
@@ -69,6 +67,4 @@
|
||||
[info props]
|
||||
[values props]]))))
|
||||
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'view-internal component-schema/?schema)))
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -5,29 +5,29 @@
|
||||
|
||||
(h/describe "List Items: Token Value"
|
||||
(h/test "Token label renders"
|
||||
(h/render-with-theme-provider [token-value/view
|
||||
{:token :snt
|
||||
:token-name "Status"
|
||||
:state :default
|
||||
:status :empty
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:values {:crypto-value "0.00"
|
||||
:fiat-value "€0.00"
|
||||
:percentage-change "0.00"
|
||||
:fiat-change "€0.00"}}])
|
||||
(h/render [token-value/view
|
||||
{:token :snt
|
||||
:token-name "Status"
|
||||
:state :default
|
||||
:status :empty
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:values {:crypto-value "0.00"
|
||||
:fiat-value "€0.00"
|
||||
:percentage-change "0.00"
|
||||
:fiat-change "€0.00"}}])
|
||||
(h/is-truthy (h/get-by-text "Status")))
|
||||
|
||||
(h/test "Status change"
|
||||
(h/render-with-theme-provider [token-value/view
|
||||
{:token :snt
|
||||
:token-name "Status"
|
||||
:state :default
|
||||
:status :positive
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:values {:crypto-value "0.00"
|
||||
:fiat-value "€0.00"
|
||||
:percentage-change "0.00"
|
||||
:fiat-change "€0.00"}}])
|
||||
(h/render [token-value/view
|
||||
{:token :snt
|
||||
:token-name "Status"
|
||||
:state :default
|
||||
:status :positive
|
||||
:customization-color :blue
|
||||
:metrics? true
|
||||
:values {:crypto-value "0.00"
|
||||
:fiat-value "€0.00"
|
||||
:percentage-change "0.00"
|
||||
:fiat-change "€0.00"}}])
|
||||
(h/is-truthy (h/get-by-label-text :arrow-icon))))
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
(ns quo.components.list-items.token-value.schema)
|
||||
|
||||
(def ^:private ?values
|
||||
[:map
|
||||
[:crypto-value :string]
|
||||
[:fiat-value :string]
|
||||
[:percentage-change {:optional true} :string]
|
||||
[:fiat-change {:optional true} :string]])
|
||||
|
||||
(def ?schema
|
||||
[:=>
|
||||
[:cat
|
||||
[:map
|
||||
[:token [:or keyword? string?]]
|
||||
[:token-name :string]
|
||||
[:status [:enum :empty :positive :negative]]
|
||||
[:values ?values]
|
||||
[:on-press {:optional true} [:maybe fn?]]
|
||||
[:on-long-press {:optional true} [:maybe fn?]]
|
||||
[:theme :schema.common/theme]
|
||||
[:customization-color {:optional true} [:maybe :schema.common/customization-color]]
|
||||
[:metrics? {:optional true} [:maybe :boolean]]]]
|
||||
:any])
|
||||
@@ -2,15 +2,13 @@
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[quo.components.icon :as icon]
|
||||
[quo.components.list-items.token-value.schema :as component-schema]
|
||||
[quo.components.list-items.token-value.style :as style]
|
||||
[quo.components.markdown.text :as text]
|
||||
[quo.components.utilities.token.view :as token]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[schema.core :as schema]))
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn- internal-view
|
||||
[]
|
||||
@@ -67,6 +65,4 @@
|
||||
[icon/icon (if (= status :positive) :i/positive :i/negative)
|
||||
(style/arrow-icon status theme)]])])]]))))
|
||||
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
(schema/instrument #'internal-view component-schema/?schema)))
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
(reagent/flush))
|
||||
|
||||
(defn- reorder-category-internal
|
||||
[{:keys [label data blur? theme container-style]}]
|
||||
[{:keys [label data blur? theme]}]
|
||||
(reagent/with-let [atom-data (reagent/atom data)]
|
||||
[rn/view {:style (merge (style/container label) container-style)}
|
||||
[rn/view {:style style/container}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns quo.components.wallet.account-permissions.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
(:require [quo.components.avatars.account-avatar.view :as account-avatar]
|
||||
[quo.components.dividers.divider-line.view :as divider-line]
|
||||
[quo.components.icon :as icons]
|
||||
[quo.components.markdown.text :as text]
|
||||
@@ -29,24 +28,17 @@
|
||||
(i18n/label :t/no-relevant-tokens)]
|
||||
|
||||
(let [token-length (dec (count tokens))]
|
||||
(map-indexed
|
||||
(fn [idx
|
||||
{:keys [type token amount collectible-name collectible-img-src
|
||||
token-img-src]
|
||||
collectible-symbol :symbol}]
|
||||
^{:key idx}
|
||||
[required-tokens/view
|
||||
{:container-style style/token-and-text
|
||||
:type type
|
||||
:amount amount
|
||||
:token token
|
||||
:token-img-src token-img-src
|
||||
:collectible-img-src collectible-img-src
|
||||
:collectible-name (if (string/blank? collectible-name)
|
||||
collectible-symbol
|
||||
collectible-name)
|
||||
:divider? (not= token-length idx)}])
|
||||
tokens)))]]))
|
||||
(map-indexed (fn [idx {:keys [type token amount collectible-name collectible-img-src]}]
|
||||
^{:key idx}
|
||||
[required-tokens/view
|
||||
{:container-style style/token-and-text
|
||||
:type type
|
||||
:amount amount
|
||||
:token token
|
||||
:collectible-img-src collectible-img-src
|
||||
:collectible-name collectible-name
|
||||
:divider? (not= token-length idx)}])
|
||||
tokens)))]]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys
|
||||
|
||||
@@ -10,5 +10,5 @@
|
||||
[:format {:optional true} [:enum :short :long]]
|
||||
[:theme :schema.common/theme]
|
||||
[:networks {:optional true}
|
||||
[:maybe [:sequential [:map [:network-name :keyword] [:short-name :string]]]]]]]]
|
||||
[:maybe [:sequential [:map [:name :keyword] [:short-name :string]]]]]]]]
|
||||
:any])
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
(let [network-text-xf (map #(colored-network-text theme %))
|
||||
address-text [text/text
|
||||
{:size :paragraph-2
|
||||
;; TODO: monospace font
|
||||
;; https://github.com/status-im/status-mobile/issues/17009
|
||||
;; TODO: monospace font https://github.com/status-im/status-mobile/issues/17009
|
||||
:weight :monospace
|
||||
:style (style/address-text format blur? theme)}
|
||||
(if (= format :short)
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
:type :default
|
||||
:name "Trip to Vegas"
|
||||
:address "0x0ah...71a"}
|
||||
:networks [{:network-name :ethereum :short-name "eth"}
|
||||
{:network-name :optimism :short-name "opt"}]
|
||||
:networks [{:name :ethereum :short-name "eth"}
|
||||
{:name :optimism :short-name "opt"}]
|
||||
:state :default
|
||||
:action :none}])
|
||||
|
||||
(def default-details
|
||||
@@ -54,7 +55,7 @@
|
||||
:action :selector
|
||||
:details other-details}]
|
||||
theme)
|
||||
(h/is-truthy (h/get-by-label-text :radio-off)))
|
||||
(h/is-truthy (h/get-by-label-text :radio-on)))
|
||||
|
||||
(h/test "Options action renders"
|
||||
(h/render-with-theme-provider [keypair/view
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns quo.components.wallet.keypair.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]))
|
||||
[quo.foundations.colors :as colors]))
|
||||
|
||||
(defn container
|
||||
[{:keys [blur? customization-color theme selected?]}]
|
||||
@@ -35,8 +34,3 @@
|
||||
{:color (if blur?
|
||||
colors/white-opa-40
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
|
||||
|
||||
(defn dot
|
||||
[blur? theme]
|
||||
(merge (subtitle blur? theme)
|
||||
{:bottom (if platform/ios? 2 -2)}))
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
@@ -59,7 +60,7 @@
|
||||
:accessibility-label :options-button}]])]))
|
||||
|
||||
(defn details-view
|
||||
[{:keys [details stored type blur? theme]}]
|
||||
[{:keys [details stored blur? theme]}]
|
||||
(let [{:keys [address]} details]
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
@@ -69,11 +70,10 @@
|
||||
{:size :paragraph-2
|
||||
:style (style/subtitle blur? theme)}
|
||||
address]
|
||||
(when (= type :default-keypair)
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (style/dot blur? theme)}
|
||||
" ∙ "])
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (merge (style/subtitle blur? theme) {:bottom (if platform/ios? 2 -2)})}
|
||||
" ∙ "]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:style (style/subtitle blur? theme)}
|
||||
@@ -86,13 +86,9 @@
|
||||
colors/white-opa-40
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}]])]))
|
||||
|
||||
(defn- acc-list-card
|
||||
[item & _rest]
|
||||
[account-list-card/view item])
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [default-selected?]}]
|
||||
(let [selected? (reagent/atom default-selected?)]
|
||||
[]
|
||||
(let [selected? (reagent/atom true)]
|
||||
(fn [{:keys [accounts action container-style] :as props}]
|
||||
[rn/pressable
|
||||
{:style (merge (style/container (merge props {:selected? @selected?})) container-style)
|
||||
@@ -106,7 +102,7 @@
|
||||
[details-view props]]]
|
||||
[rn/flat-list
|
||||
{:data accounts
|
||||
:render-fn acc-list-card
|
||||
:render-fn account-list-card/view
|
||||
:separator [rn/view {:style {:height 8}}]
|
||||
:style {:padding-horizontal 8}}]])))
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
:style {:margin-left 4}}
|
||||
(case type
|
||||
:token (str amount " " token)
|
||||
:collectible (str amount " " collectible-name)
|
||||
:collectible collectible-name
|
||||
nil)]
|
||||
(when divider?
|
||||
[rn/view
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
(defn networks
|
||||
[values theme]
|
||||
(let [{:keys [ethereum optimism arbitrum]} values
|
||||
show-optimism? (and optimism (pos? (:amount optimism)))
|
||||
show-arbitrum? (and arbitrum (pos? (:amount arbitrum)))]
|
||||
show-optimism? (pos? optimism)
|
||||
show-arbitrum? (pos? arbitrum)]
|
||||
[rn/view
|
||||
{:style style/networks-container
|
||||
:accessibility-label :networks}
|
||||
|
||||
@@ -35,7 +35,6 @@
|
||||
(def ^:private networks
|
||||
{:arbitrum (js/require "../resources/images/networks/Arbitrum.png")
|
||||
:ethereum (js/require "../resources/images/networks/Ethereum.png")
|
||||
:mainnet (js/require "../resources/images/networks/Ethereum.png")
|
||||
:gnosis (js/require "../resources/images/networks/Gnosis.png")
|
||||
:hermez (js/require "../resources/images/networks/Hermez.png")
|
||||
:optimism (js/require "../resources/images/networks/Optimism.png")
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
["react" :as react]
|
||||
["react-native" :as react-native]
|
||||
[oops.core :as oops]
|
||||
[promesa.core :as p]
|
||||
[react-native.flat-list :as flat-list]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.section-list :as section-list]
|
||||
@@ -30,13 +29,7 @@
|
||||
(assoc props :source {:uri source})
|
||||
props)])
|
||||
|
||||
(defn image-get-size
|
||||
[uri]
|
||||
(p/create (fn [res rej]
|
||||
(.getSize ^js (.-Image ^js react-native)
|
||||
uri
|
||||
(fn [width height] (res [width height]))
|
||||
rej))))
|
||||
(defn image-get-size [uri callback] (.getSize ^js (.-Image ^js react-native) uri callback))
|
||||
(def text (reagent/adapt-react-class (.-Text ^js react-native)))
|
||||
(def text-input (reagent/adapt-react-class (.-TextInput ^js react-native)))
|
||||
|
||||
@@ -129,8 +122,6 @@
|
||||
|
||||
(def memo react/memo)
|
||||
|
||||
(def use-state react/useState)
|
||||
|
||||
(def create-ref react/createRef)
|
||||
|
||||
(def use-ref react/useRef)
|
||||
@@ -188,10 +179,6 @@
|
||||
([handler deps]
|
||||
(react/useCallback handler (get-js-deps deps))))
|
||||
|
||||
(defn use-memo
|
||||
[handler deps]
|
||||
(react/useMemo handler (get-js-deps deps)))
|
||||
|
||||
(def layout-animation (.-LayoutAnimation ^js react-native))
|
||||
(def configure-next (.-configureNext ^js layout-animation))
|
||||
|
||||
@@ -217,5 +204,3 @@
|
||||
(def linking (.-Linking react-native))
|
||||
|
||||
(defn open-url [link] (.openURL ^js linking link))
|
||||
|
||||
(def set-status-bar-style react-native/StatusBar.setBarStyle)
|
||||
|
||||
@@ -3,5 +3,7 @@
|
||||
["react-native-image-resizer" :default image-resizer]))
|
||||
|
||||
(defn resize
|
||||
[{:keys [path max-width max-height quality]}]
|
||||
(.createResizedImage image-resizer path max-width max-height "JPEG" quality 0 nil false))
|
||||
[path max-width max-height quality on-resize on-error]
|
||||
(-> (.createResizedImage image-resizer path max-width max-height "JPEG" quality 0 nil false)
|
||||
(.then on-resize)
|
||||
(.catch on-error)))
|
||||
|
||||
@@ -3,18 +3,18 @@
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]))
|
||||
|
||||
(def ^:private sheet-border-radius 20)
|
||||
|
||||
(defn sheet
|
||||
[{:keys [max-height]}]
|
||||
[{:keys [top]} window-height selected-item]
|
||||
{:position :absolute
|
||||
:max-height (- window-height top)
|
||||
:z-index 1
|
||||
:bottom 0
|
||||
:left 0
|
||||
:right 0
|
||||
:z-index 1
|
||||
:max-height max-height
|
||||
:border-top-left-radius sheet-border-radius
|
||||
:border-top-right-radius sheet-border-radius})
|
||||
:border-top-left-radius 20
|
||||
:border-top-right-radius 20
|
||||
:overflow (when-not selected-item :hidden)
|
||||
:flex 1})
|
||||
|
||||
(def gradient-bg
|
||||
{:position :absolute
|
||||
@@ -31,11 +31,10 @@
|
||||
:bottom 0})
|
||||
|
||||
(defn sheet-content
|
||||
[{:keys [theme padding-bottom shell?]}]
|
||||
{:overflow :scroll
|
||||
:padding-bottom padding-bottom
|
||||
:border-top-left-radius sheet-border-radius
|
||||
:border-top-right-radius sheet-border-radius
|
||||
[theme padding-bottom-override {:keys [bottom]} shell? bottom-margin]
|
||||
{:border-top-left-radius 20
|
||||
:border-top-right-radius 20
|
||||
:padding-bottom (or padding-bottom-override (+ bottom bottom-margin))
|
||||
:background-color (if shell?
|
||||
:transparent
|
||||
(colors/theme-colors colors/white colors/neutral-95 theme))})
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.bottom-sheet.style :as style]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
@@ -56,86 +57,83 @@
|
||||
(show translate-y bg-opacity)
|
||||
(hide translate-y bg-opacity window-height on-close))))))
|
||||
|
||||
(defn- get-layout-height
|
||||
[event]
|
||||
(oops/oget event "nativeEvent.layout.height"))
|
||||
(defn- f-view
|
||||
[_ _]
|
||||
(let [sheet-height (reagent/atom 0)
|
||||
item-height (reagent/atom 0)]
|
||||
(fn [{:keys [hide? insets theme]}
|
||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||
gradient-cover? customization-color hide-handle? blur-radius]
|
||||
:or {border-radius 12}}]
|
||||
(let [{window-height :height} (rn/get-window)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
translate-y (reanimated/use-shared-value window-height)
|
||||
sheet-gesture (get-sheet-gesture translate-y
|
||||
bg-opacity
|
||||
window-height
|
||||
on-close)
|
||||
selected-item-smaller-than-sheet? (< @item-height
|
||||
(- window-height
|
||||
@sheet-height
|
||||
(:top insets)
|
||||
(:bottom insets)
|
||||
bottom-margin))
|
||||
top (- window-height (:top insets) @sheet-height)
|
||||
bottom (if selected-item-smaller-than-sheet?
|
||||
(+ @sheet-height bottom-margin)
|
||||
(:bottom insets))]
|
||||
(rn/use-effect
|
||||
#(if hide?
|
||||
(hide translate-y bg-opacity window-height on-close)
|
||||
(show translate-y bg-opacity))
|
||||
[hide?])
|
||||
(hooks/use-back-handler (fn []
|
||||
(when (fn? on-close)
|
||||
(on-close))
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
true))
|
||||
[rn/view {:style {:flex 1}}
|
||||
;; backdrop
|
||||
[rn/pressable
|
||||
{:on-press #(rf/dispatch [:hide-bottom-sheet])
|
||||
:style {:flex 1}}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity bg-opacity}
|
||||
{:flex 1 :background-color colors/neutral-100-opa-70})}]]
|
||||
;; sheet
|
||||
[gesture/gesture-detector {:gesture sheet-gesture}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
(style/sheet insets window-height selected-item))}
|
||||
(when shell?
|
||||
[blur/ios-view
|
||||
{:style style/shell-bg
|
||||
:blur-radius (or blur-radius 20)
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}])
|
||||
(when selected-item
|
||||
[rn/view
|
||||
{:on-layout #(reset! item-height (.-nativeEvent.layout.height ^js %))
|
||||
:style
|
||||
(style/selected-item theme top bottom selected-item-smaller-than-sheet? border-radius)}
|
||||
[selected-item]])
|
||||
|
||||
(defn view
|
||||
[{:keys [hide? insets]}
|
||||
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
|
||||
gradient-cover? customization-color hide-handle? blur-radius]
|
||||
:or {border-radius 12}}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
sheet-height (rn/use-ref-atom 0)
|
||||
item-height (rn/use-ref-atom 0)
|
||||
set-sheet-height (rn/use-callback #(reset! sheet-height (get-layout-height %)))
|
||||
set-item-height (rn/use-callback #(reset! item-height (get-layout-height %)))
|
||||
{window-height :height} (rn/get-window)
|
||||
bg-opacity (reanimated/use-shared-value 0)
|
||||
translate-y (reanimated/use-shared-value window-height)
|
||||
sheet-gesture (get-sheet-gesture translate-y
|
||||
bg-opacity
|
||||
window-height
|
||||
on-close)
|
||||
selected-item-smaller-than-sheet? (< @item-height
|
||||
(- window-height
|
||||
@sheet-height
|
||||
(:top insets)
|
||||
(:bottom insets)
|
||||
bottom-margin))
|
||||
top (- window-height (:top insets) @sheet-height)
|
||||
bottom (if selected-item-smaller-than-sheet?
|
||||
(+ @sheet-height bottom-margin)
|
||||
(:bottom insets))
|
||||
sheet-max-height (- window-height (:top insets))
|
||||
content-padding-bottom (or padding-bottom-override
|
||||
(+ (:bottom insets) bottom-margin))]
|
||||
(rn/use-effect
|
||||
#(if hide?
|
||||
(hide translate-y bg-opacity window-height on-close)
|
||||
(show translate-y bg-opacity))
|
||||
[hide?])
|
||||
(hooks/use-back-handler (fn []
|
||||
(when (fn? on-close)
|
||||
(on-close))
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
true))
|
||||
[rn/view {:style {:flex 1}}
|
||||
;; backdrop
|
||||
[rn/pressable
|
||||
{:on-press #(rf/dispatch [:hide-bottom-sheet])
|
||||
:style {:flex 1}}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:opacity bg-opacity}
|
||||
{:flex 1 :background-color colors/neutral-100-opa-70})}]]
|
||||
;; sheet
|
||||
[gesture/gesture-detector {:gesture sheet-gesture}
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:transform [{:translateY translate-y}]}
|
||||
(style/sheet {:max-height sheet-max-height}))}
|
||||
(when shell?
|
||||
[blur/ios-view
|
||||
{:style style/shell-bg
|
||||
:blur-radius (or blur-radius 20)
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}])
|
||||
(when selected-item
|
||||
[rn/view
|
||||
{:on-layout set-item-height
|
||||
:style (style/selected-item theme top bottom selected-item-smaller-than-sheet? border-radius)}
|
||||
[selected-item]])
|
||||
[rn/view
|
||||
{:on-layout set-sheet-height
|
||||
:style (style/sheet-content {:theme theme
|
||||
:shell? shell?
|
||||
:padding-bottom content-padding-bottom})}
|
||||
(when (and gradient-cover? customization-color)
|
||||
[rn/view {:style style/gradient-bg}
|
||||
[quo/gradient-cover
|
||||
{:customization-color customization-color
|
||||
:opacity 0.4}]])
|
||||
(when-not hide-handle?
|
||||
[quo/drawer-bar])
|
||||
[content]]]]]))
|
||||
[rn/view
|
||||
{:style (style/sheet-content theme padding-bottom-override insets shell? bottom-margin)
|
||||
:on-layout #(reset! sheet-height (.-nativeEvent.layout.height ^js %))}
|
||||
(when (and gradient-cover? customization-color)
|
||||
[rn/view {:style style/gradient-bg}
|
||||
[quo/gradient-cover
|
||||
{:customization-color customization-color
|
||||
:opacity 0.4}]])
|
||||
(when-not hide-handle?
|
||||
[quo/drawer-bar])
|
||||
[content]]]]]))))
|
||||
|
||||
(defn- internal-view
|
||||
[args sheet]
|
||||
[:f> f-view args sheet])
|
||||
|
||||
(def view (quo.theme/with-theme internal-view))
|
||||
|
||||
@@ -52,8 +52,7 @@
|
||||
:remove-listeners remove-listeners}))
|
||||
|
||||
(defn view
|
||||
[{:keys [header footer customization-color footer-container-padding header-container-style
|
||||
gradient-cover?]
|
||||
[{:keys [header footer customization-color footer-container-padding gradient-cover?]
|
||||
:or {footer-container-padding (safe-area/get-top)}} &
|
||||
children]
|
||||
(reagent/with-let [window-height (:height (rn/get-window))
|
||||
@@ -86,9 +85,7 @@
|
||||
[:<>
|
||||
(when gradient-cover? [quo/gradient-cover {:customization-color customization-color}])
|
||||
[rn/view {:style style/page-container}
|
||||
[rn/view
|
||||
{:on-layout set-header-height
|
||||
:style header-container-style}
|
||||
[rn/view {:on-layout set-header-height}
|
||||
header]
|
||||
[rn/scroll-view
|
||||
{:on-scroll set-content-y-scroll
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
(ns status-im.common.parallax.blacklist
|
||||
(:require
|
||||
[native-module.core :as native-module]))
|
||||
|
||||
(def ^:private device-id (:device-id (native-module/get-device-model-info)))
|
||||
|
||||
(defn- get-model-code
|
||||
[model]
|
||||
(if-let [[_ code] (and model (re-find #"iPhone(\d+)" model))]
|
||||
(js/parseInt code 10)
|
||||
0))
|
||||
|
||||
(def ^:private minimum-device-code 11)
|
||||
|
||||
(def blacklisted?
|
||||
(-> device-id
|
||||
get-model-code
|
||||
(< minimum-device-code)))
|
||||
@@ -0,0 +1,13 @@
|
||||
(ns status-im.common.parallax.whitelist
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]))
|
||||
|
||||
(def ^:const device-id (:device-id (native-module/get-device-model-info)))
|
||||
|
||||
;; iPhone 14 is 15 for some reason
|
||||
(def ^:const whitelist #{"iPhone11" "iPhone12" "iPhone13" "iPhone14" "iPhone15"})
|
||||
|
||||
(def whitelisted?
|
||||
(let [device-type (first (string/split (str device-id) ","))]
|
||||
(whitelist device-type)))
|
||||
@@ -1,11 +0,0 @@
|
||||
(ns status-im.common.scalable-avatar.style)
|
||||
|
||||
(defn wrapper
|
||||
[{:keys [scale margin-top margin border-color]}]
|
||||
[{:transform [{:scale scale}]
|
||||
:margin-top margin-top
|
||||
:margin-left margin
|
||||
:margin-bottom margin}
|
||||
{:border-width 4
|
||||
:border-color border-color
|
||||
:border-radius 100}])
|
||||
@@ -75,9 +75,3 @@
|
||||
:width picture-diameter
|
||||
:height picture-diameter
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
|
||||
|
||||
(defn cover-background
|
||||
[cover-color]
|
||||
{:background-color cover-color
|
||||
:height 167
|
||||
:margin-bottom -16})
|
||||
|
||||
@@ -98,9 +98,9 @@
|
||||
(defn scroll-page
|
||||
[_ _ _]
|
||||
(let [scroll-height (reagent/atom negative-scroll-position-0)]
|
||||
(fn [{:keys [theme cover-image cover-color logo on-scroll
|
||||
(fn [{:keys [theme cover-image logo on-scroll
|
||||
collapsed? height top-nav title-colum background-color navigate-back? page-nav-props
|
||||
overlay-shown? sticky-header children-style]}
|
||||
overlay-shown? sticky-header]}
|
||||
children]
|
||||
[:<>
|
||||
[:f> f-scroll-page-header
|
||||
@@ -125,8 +125,6 @@
|
||||
"nativeEvent.contentOffset.y")))
|
||||
(when on-scroll
|
||||
(on-scroll @scroll-height)))}
|
||||
(when cover-color
|
||||
[rn/view {:style (style/cover-background cover-color)}])
|
||||
(when cover-image
|
||||
[rn/view {:style {:height (if collapsed? 110 151)}}
|
||||
[rn/image
|
||||
@@ -138,10 +136,8 @@
|
||||
:flex 1}}]])
|
||||
(when children
|
||||
[rn/view
|
||||
{:style (style/children-container (merge
|
||||
children-style
|
||||
{:border-radius (diff-with-max-min @scroll-height 16 0)
|
||||
:background-color background-color}))}
|
||||
{:style (style/children-container {:border-radius (diff-with-max-min @scroll-height 16 0)
|
||||
:background-color background-color})}
|
||||
(when (and (not collapsed?) cover-image)
|
||||
[:f> f-display-picture @scroll-height logo theme])
|
||||
children])]])))
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
[utils.re-frame :as rf]
|
||||
[utils.security.core :as security]))
|
||||
|
||||
(defn- get-error-message
|
||||
(defn get-error-message
|
||||
[error]
|
||||
(if (and (some? error)
|
||||
(or (= error "file is not a database")
|
||||
@@ -21,62 +21,31 @@
|
||||
(i18n/label :t/oops-wrong-password)
|
||||
error))
|
||||
|
||||
(defn- error-info
|
||||
[error-message processing shell?]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
on-press (rn/use-callback
|
||||
(fn []
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content #(forgot-password-doc/view {:shell? shell?})
|
||||
:theme theme
|
||||
:shell? shell?}]))
|
||||
[theme])]
|
||||
[rn/view {:style style/error-message}
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
error-message]
|
||||
[rn/pressable
|
||||
{:hit-slop {:top 6 :bottom 20 :left 0 :right 0}
|
||||
:disabled processing
|
||||
:on-press on-press}
|
||||
[rn/text
|
||||
{:style {:text-decoration-line :underline
|
||||
:color (colors/resolve-color :danger theme)}
|
||||
:size :paragraph-2
|
||||
:suppress-highlighting true}
|
||||
(i18n/label :t/forgot-password)]]]))
|
||||
(defn- on-change-password
|
||||
[entered-password]
|
||||
(debounce/debounce-and-dispatch [:profile/on-password-input-changed
|
||||
{:password (security/mask-data entered-password)
|
||||
:error ""}]
|
||||
100))
|
||||
|
||||
(defn view
|
||||
[{:keys [shell? on-press-biometrics blur?]}]
|
||||
(defn- view-internal
|
||||
[{:keys [default-password theme shell? on-press-biometrics blur?]}]
|
||||
(let [{:keys [error processing]} (rf/sub [:profile/login])
|
||||
error-message (rn/use-memo #(get-error-message error) [error])
|
||||
error? (boolean (seq error-message))
|
||||
default-value (rn/use-ref-atom "") ;;bug on Android
|
||||
;;https://github.com/status-im/status-mobile/issues/19004
|
||||
on-change-password (rn/use-callback
|
||||
(fn [entered-password]
|
||||
(reset! default-value entered-password)
|
||||
(debounce/debounce-and-dispatch [:profile/on-password-input-changed
|
||||
{:password (security/mask-data
|
||||
entered-password)
|
||||
:error ""}]
|
||||
100)))]
|
||||
error-message (get-error-message error)
|
||||
error? (boolean (seq error-message))]
|
||||
[:<>
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
[quo/input
|
||||
{:container-style {:flex 1}
|
||||
:type :password
|
||||
:default-value @default-value
|
||||
:blur? blur?
|
||||
:disabled? processing
|
||||
:placeholder (i18n/label :t/type-your-password)
|
||||
:auto-focus true
|
||||
:error? error?
|
||||
:label (i18n/label :t/profile-password)
|
||||
:on-change-text on-change-password}]
|
||||
:on-change-text on-change-password
|
||||
:default-value (security/safe-unmask-data default-password)}]
|
||||
(when on-press-biometrics
|
||||
[quo/button
|
||||
{:container-style style/auth-button
|
||||
@@ -86,5 +55,26 @@
|
||||
:type :outline}
|
||||
:i/face-id])]
|
||||
(when error?
|
||||
[error-info error-message processing shell?])]))
|
||||
[rn/view {:style style/error-message}
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:size :default
|
||||
:icon :i/info}
|
||||
error-message]
|
||||
[rn/pressable
|
||||
{:hit-slop {:top 6 :bottom 20 :left 0 :right 0}
|
||||
:disabled processing
|
||||
:on-press (fn []
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content #(forgot-password-doc/view {:shell? shell?})
|
||||
:theme theme
|
||||
:shell? shell?}]))}
|
||||
[rn/text
|
||||
{:style {:text-decoration-line :underline
|
||||
:color (colors/resolve-color :danger theme)}
|
||||
:size :paragraph-2
|
||||
:suppress-highlighting true}
|
||||
(i18n/label :t/forgot-password)]]])]))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -3,33 +3,45 @@
|
||||
[quo.core :as quo]
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.common.standard-authentication.standard-auth.authorize :as authorize]
|
||||
[status-im.constants :as constants]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn view
|
||||
[{:keys [track-text customization-color auth-button-label on-auth-success on-auth-fail
|
||||
auth-button-icon-left size blur? container-style disabled?]
|
||||
:or {container-style {:flex 1}}}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
(defn- view-internal
|
||||
[_]
|
||||
(let [reset-slider? (reagent/atom false)
|
||||
on-close (fn []
|
||||
(js/setTimeout
|
||||
#(reset! reset-slider? true)
|
||||
200))
|
||||
auth-method (rf/sub [:auth-method])
|
||||
biometric-auth? (= auth-method constants/auth-method-biometric)
|
||||
on-complete (rn/use-callback
|
||||
(fn [reset]
|
||||
(authorize/authorize {:on-close #(js/setTimeout reset 200)
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:biometric-auth? biometric-auth?
|
||||
:on-auth-success on-auth-success
|
||||
:on-auth-fail on-auth-fail
|
||||
:auth-button-label auth-button-label}))
|
||||
[theme])]
|
||||
[quo/slide-button
|
||||
{:container-style container-style
|
||||
:size size
|
||||
:customization-color customization-color
|
||||
:on-complete on-complete
|
||||
:track-icon (if biometric-auth? :i/face-id :password)
|
||||
:track-text track-text
|
||||
:disabled? disabled?}]))
|
||||
biometric-auth? (= auth-method constants/auth-method-biometric)]
|
||||
(fn [{:keys [track-text
|
||||
customization-color
|
||||
auth-button-label
|
||||
on-auth-success
|
||||
on-auth-fail
|
||||
auth-button-icon-left
|
||||
size
|
||||
theme
|
||||
blur?
|
||||
container-style]
|
||||
:or {container-style {:flex 1}}}]
|
||||
[rn/view {:style container-style}
|
||||
[quo/slide-button
|
||||
{:size size
|
||||
:customization-color customization-color
|
||||
:on-reset (when @reset-slider? #(reset! reset-slider? false))
|
||||
:on-complete #(authorize/authorize {:on-close on-close
|
||||
:auth-button-icon-left auth-button-icon-left
|
||||
:theme theme
|
||||
:blur? blur?
|
||||
:biometric-auth? biometric-auth?
|
||||
:on-auth-success on-auth-success
|
||||
:on-auth-fail on-auth-fail
|
||||
:auth-button-label auth-button-label})
|
||||
:track-icon (if biometric-auth? :i/face-id :password)
|
||||
:track-text track-text}]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
(def ^:const command-state-transaction-sent 7)
|
||||
|
||||
(def ^:const profile-default-color :blue)
|
||||
(def ^:const profile-name-max-length 20)
|
||||
(def ^:const profile-name-max-length 24)
|
||||
(def ^:const profile-bio-max-length 240)
|
||||
(def ^:const profile-default-currency :usd)
|
||||
|
||||
@@ -429,11 +429,7 @@
|
||||
(def ^:const optimism-short-name "opt")
|
||||
(def ^:const arbitrum-short-name "arb1")
|
||||
|
||||
(def ^:const mainnet-abbreviated-name "Eth.")
|
||||
(def ^:const optimism-abbreviated-name "Opt.")
|
||||
(def ^:const arbitrum-abbreviated-name "Arb1.")
|
||||
|
||||
(def ^:const mainnet-network-name :mainnet)
|
||||
(def ^:const mainnet-network-name :ethereum)
|
||||
(def ^:const optimism-network-name :optimism)
|
||||
(def ^:const arbitrum-network-name :arbitrum)
|
||||
|
||||
|
||||
@@ -75,26 +75,20 @@
|
||||
[{:keys [db]} contacts]
|
||||
{:db (assoc db :contacts/contacts (into {} (map #(vector (:public-key %) %) contacts)))})
|
||||
|
||||
(defn send-contact-request
|
||||
[{:keys [db]} [id message]]
|
||||
(rf/defn send-contact-request
|
||||
{:events [:contact.ui/send-contact-request]}
|
||||
[{:keys [db]} id]
|
||||
(when (not= id (get-in db [:profile/profile :public-key]))
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_sendContactRequest"
|
||||
:js-response true
|
||||
:params [{:id id :message (or message (i18n/label :t/add-me-to-your-contacts))}]
|
||||
:on-error [:contact.ui/send-contact-request-failure id]
|
||||
:on-success [:transport/message-sent]}]]]}))
|
||||
|
||||
(rf/reg-event-fx :contact.ui/send-contact-request send-contact-request)
|
||||
|
||||
(defn send-contact-request-failure
|
||||
[_ [id error]]
|
||||
(log/error "Failed to send contact request"
|
||||
{:error error
|
||||
:event :contact.ui/send-contact-request
|
||||
:id id}))
|
||||
|
||||
(rf/reg-event-fx :contact.ui/send-contact-request-failure send-contact-request-failure)
|
||||
{:json-rpc/call
|
||||
[{:method "wakuext_sendContactRequest"
|
||||
:js-response true
|
||||
:params [{:id id :message (i18n/label :t/add-me-to-your-contacts)}]
|
||||
:on-error (fn [error]
|
||||
(log/error "Failed to send contact request"
|
||||
{:error error
|
||||
:event :contact.ui/send-contact-request
|
||||
:id id}))
|
||||
:on-success #(rf/dispatch [:transport/message-sent %])}]}))
|
||||
|
||||
(rf/defn remove-contact
|
||||
"Remove a contact from current account's contact list"
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
(ns status-im.contexts.chat.contacts.events-test
|
||||
(:require
|
||||
[cljs.test :refer [deftest is testing]]
|
||||
matcher-combinators.test
|
||||
[status-im.contexts.chat.contacts.events :as chat.contacts]
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
(deftest send-contact-request-test
|
||||
(testing "creates nothing when attempting send contact request to self"
|
||||
(let [profile-public-key "0x1"
|
||||
cofx {:db {:profile/profile {:public-key profile-public-key}}}]
|
||||
(is (match? nil (chat.contacts/send-contact-request cofx [profile-public-key])))))
|
||||
|
||||
(testing "creates contact request rpc with default message"
|
||||
(let [profile-public-key "0x1"
|
||||
contact-public-key "0x2"
|
||||
cofx {:db {:profile/profile {:public-key profile-public-key}}}]
|
||||
(is (match?
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_sendContactRequest"
|
||||
:js-response true
|
||||
:params [{:id contact-public-key
|
||||
:message (i18n/label :t/add-me-to-your-contacts)}]
|
||||
:on-error [:contact.ui/send-contact-request-failure contact-public-key]
|
||||
:on-success [:transport/message-sent]}]]]}
|
||||
(chat.contacts/send-contact-request cofx [contact-public-key])))))
|
||||
|
||||
(testing "creates contact request rpc with custom message"
|
||||
(let [profile-public-key "0x1"
|
||||
contact-public-key "0x2"
|
||||
custom-message "Hey there!"
|
||||
cofx {:db {:profile/profile {:public-key profile-public-key}}}]
|
||||
(is (match?
|
||||
{:fx [[:json-rpc/call
|
||||
[{:method "wakuext_sendContactRequest"
|
||||
:js-response true
|
||||
:params [{:id contact-public-key
|
||||
:message custom-message}]
|
||||
:on-error [:contact.ui/send-contact-request-failure contact-public-key]
|
||||
:on-success [:transport/message-sent]}]]]}
|
||||
(chat.contacts/send-contact-request cofx [contact-public-key custom-message]))))))
|
||||
@@ -14,7 +14,6 @@
|
||||
[status-im.contexts.chat.messenger.messages.delete-message-for-me.events :as delete-for-me]
|
||||
[status-im.contexts.chat.messenger.messages.delete-message.events :as delete-message]
|
||||
[status-im.contexts.chat.messenger.messages.list.state :as chat.state]
|
||||
[status-im.feature-flags :as ff]
|
||||
[status-im.navigation.events :as navigation]
|
||||
[taoensso.timbre :as log]
|
||||
[utils.datetime :as datetime]
|
||||
@@ -432,20 +431,3 @@
|
||||
[:chat/inputs current-chat-id :metadata :sending-image]
|
||||
dissoc
|
||||
(:uri original))})))
|
||||
|
||||
(rf/reg-event-fx :chat.ui/show-profile
|
||||
(fn [{:keys [db]} [public-key ens-name]]
|
||||
(let [my-public-key (get-in db [:profile/profile :public-key])]
|
||||
(if (not= my-public-key public-key)
|
||||
{:db (-> db
|
||||
(assoc :contacts/identity public-key)
|
||||
(assoc :contacts/ens-name ens-name))
|
||||
:dispatch [:contacts/build-contact
|
||||
{:pubkey public-key
|
||||
:ens ens-name
|
||||
:success-fn (fn [_]
|
||||
{:dispatch [:open-modal
|
||||
(if (ff/enabled? ::ff/profile.new-contact-ui)
|
||||
:contact-profile
|
||||
:profile)]})}]}
|
||||
{:dispatch [:navigate-to :my-profile]}))))
|
||||
|
||||
@@ -26,13 +26,15 @@
|
||||
[message/message message context (atom false)])
|
||||
|
||||
(defn empty-pinned-messages-state
|
||||
[{:keys [theme]}]
|
||||
[{:keys [theme community?]}]
|
||||
[rn/view {:style style/no-pinned-messages-container}
|
||||
[quo/empty-state
|
||||
{:blur? false
|
||||
:image (resources/get-themed-image :no-pinned-messages theme)
|
||||
:title (i18n/label :t/no-pinned-messages)
|
||||
:description (i18n/label :t/no-pinned-messages-desc)}]])
|
||||
:description (i18n/label (if community?
|
||||
:t/no-pinned-messages-community-desc
|
||||
:t/no-pinned-messages-desc))}]])
|
||||
|
||||
(defn f-pinned-messages
|
||||
[{:keys [theme chat-id]}]
|
||||
@@ -75,7 +77,8 @@
|
||||
:key-fn list-key-fn
|
||||
:separator [quo/separator {:style {:margin-vertical 8}}]}]
|
||||
[empty-pinned-messages-state
|
||||
{:theme theme}])]))
|
||||
{:community? (boolean community)
|
||||
:theme theme}])]))
|
||||
|
||||
(defn- internal-pinned-messages
|
||||
[params]
|
||||
|
||||
@@ -167,7 +167,7 @@
|
||||
muted?)))}]}]))
|
||||
|
||||
(defn f-list-footer
|
||||
[{:keys [chat distance-from-list-top theme customization-color]}]
|
||||
[{:keys [chat distance-from-list-top cover-bg-color theme]}]
|
||||
(let [{:keys [chat-id chat-name emoji chat-type
|
||||
group-chat]} chat
|
||||
display-name (cond
|
||||
@@ -185,8 +185,8 @@
|
||||
messages.constants/top-bar-height
|
||||
messages.constants/header-container-top-margin)
|
||||
background-color (colors/theme-colors
|
||||
(colors/resolve-color customization-color theme 20)
|
||||
(colors/resolve-color customization-color theme 40)
|
||||
(colors/custom-color cover-bg-color 50 20)
|
||||
(colors/custom-color cover-bg-color 50 40)
|
||||
theme)
|
||||
border-radius (reanimated/interpolate
|
||||
distance-from-list-top
|
||||
@@ -224,7 +224,7 @@
|
||||
(when bio
|
||||
[quo/text {:style style/bio}
|
||||
bio])
|
||||
[actions chat-id customization-color]]]))
|
||||
[actions chat-id cover-bg-color]]]))
|
||||
|
||||
(defn list-footer
|
||||
[props]
|
||||
@@ -285,15 +285,10 @@
|
||||
(reset! distance-atom new-distance)))
|
||||
|
||||
(defn f-messages-list-content
|
||||
[{:keys [insets distance-from-list-top content-height layout-height distance-atom
|
||||
[{:keys [insets distance-from-list-top content-height layout-height cover-bg-color distance-atom
|
||||
chat-screen-layout-calculations-complete? chat-list-scroll-y]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
chat (rf/sub [:chats/current-chat-chat-view])
|
||||
community-channel? (= constants/community-chat-type (:chat-type chat))
|
||||
customization-color (if community-channel?
|
||||
(or (:color chat)
|
||||
(rf/sub [:communities/community-color (:community-id chat)]))
|
||||
:turquoise)
|
||||
{:keys [keyboard-shown]} (hooks/use-keyboard)
|
||||
{window-height :height} (rn/get-window)
|
||||
context (rf/sub [:chats/current-chat-message-list-view-context])
|
||||
@@ -315,7 +310,7 @@
|
||||
:chat chat
|
||||
:window-height window-height
|
||||
:distance-from-list-top distance-from-list-top
|
||||
:customization-color customization-color}]
|
||||
:cover-bg-color cover-bg-color}]
|
||||
:data messages
|
||||
:render-data {:theme theme
|
||||
:context context
|
||||
|
||||
@@ -34,7 +34,8 @@
|
||||
:distance-atom distance-atom
|
||||
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?
|
||||
:distance-from-list-top distance-from-list-top
|
||||
:chat-list-scroll-y chat-list-scroll-y}]
|
||||
:chat-list-scroll-y chat-list-scroll-y
|
||||
:cover-bg-color :turquoise}]
|
||||
[composer.view/composer
|
||||
{:insets insets
|
||||
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
(ns status-im.contexts.chat.messenger.photo-selector.effects
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[promesa.core :as p]
|
||||
[react-native.cameraroll :as cameraroll]
|
||||
[react-native.core :as rn]
|
||||
[react-native.image-resizer :as image-resizer]
|
||||
@@ -30,30 +29,27 @@
|
||||
#(rf/dispatch [:on-camera-roll-get-photos (:edges %) (:page_info %) end-cursor])))})))
|
||||
|
||||
(defn- resize-photo
|
||||
[uri]
|
||||
(p/let [[width height] (rn/image-get-size uri)
|
||||
resize? (> (max width height)
|
||||
maximum-image-size-px)
|
||||
resized-uri (-> (image-resizer/resize
|
||||
{:max-width (if resize? maximum-image-size-px width)
|
||||
:max-height (if resize? maximum-image-size-px height)
|
||||
:path uri
|
||||
:quality 60})
|
||||
(p/then (fn [^js resized-image]
|
||||
(let [path (.-path resized-image)]
|
||||
(if (string/starts-with? path "file")
|
||||
path
|
||||
(str "file://" path))))))]
|
||||
{:resized-uri resized-uri
|
||||
:width width
|
||||
:height height}))
|
||||
[uri callback]
|
||||
(rn/image-get-size
|
||||
uri
|
||||
(fn [width height]
|
||||
(let [resize? (> (max width height) maximum-image-size-px)]
|
||||
(image-resizer/resize
|
||||
uri
|
||||
(if resize? maximum-image-size-px width)
|
||||
(if resize? maximum-image-size-px height)
|
||||
60
|
||||
(fn [^js resized-image]
|
||||
(let [path (.-path resized-image)
|
||||
path (if (string/starts-with? path "file") path (str "file://" path))]
|
||||
(callback {:resized-uri path
|
||||
:width width
|
||||
:height height})))
|
||||
#(log/error "could not resize image" %))))))
|
||||
|
||||
(rf/reg-fx :effects.camera-roll/image-selected
|
||||
(fn [[image chat-id]]
|
||||
(-> (resize-photo (:uri image))
|
||||
(p/then #(rf/dispatch
|
||||
[:photo-selector/image-selected chat-id image %]))
|
||||
(p/catch #(log/error "could not resize image" %)))))
|
||||
(resize-photo (:uri image) #(rf/dispatch [:photo-selector/image-selected chat-id image %]))))
|
||||
|
||||
(defn- get-albums
|
||||
[callback]
|
||||
|
||||
@@ -5,92 +5,81 @@
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.common.password-authentication.view :as password-authentication]
|
||||
[status-im.contexts.communities.actions.accounts-selection.style :as style]
|
||||
[status-im.contexts.communities.actions.addresses-for-permissions.view :as addresses-for-permissions]
|
||||
[status-im.contexts.communities.actions.airdrop-addresses.view :as airdrop-addresses]
|
||||
[status-im.contexts.communities.actions.community-rules.view :as community-rules]
|
||||
[status-im.contexts.communities.utils :as communities.utils]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- join-community-and-navigate-back
|
||||
[id]
|
||||
(rf/dispatch [:password-authentication/show {:content (fn [] [password-authentication/view])}
|
||||
{:label (i18n/label :t/join-open-community)
|
||||
:on-press #(rf/dispatch [:communities/request-to-join-with-addresses
|
||||
{:community-id id :password %}])}])
|
||||
(rf/dispatch [:navigate-back]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||
show-addresses-for-permissions (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:community-id id
|
||||
:content addresses-for-permissions/view}]))
|
||||
show-airdrop-addresses (fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:community-id id
|
||||
:content airdrop-addresses/view}]))
|
||||
navigate-back #(rf/dispatch [:navigate-back])
|
||||
join-and-go-back (fn []
|
||||
(rf/dispatch [:password-authentication/show
|
||||
{:content (fn [] [password-authentication/view])}
|
||||
{:label (i18n/label :t/join-open-community)
|
||||
:on-press
|
||||
#(rf/dispatch
|
||||
[:communities/request-to-join-with-addresses
|
||||
{:community-id id :password %}])}])
|
||||
(navigate-back))]
|
||||
(fn []
|
||||
(let [{:keys [name color images]} (rf/sub [:communities/community id])
|
||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||
selected-accounts (rf/sub [:communities/selected-permission-accounts id])
|
||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||
highest-permission-role
|
||||
:t/member))]
|
||||
[rn/safe-area-view {:style style/container}
|
||||
[quo/page-nav
|
||||
{:text-align :left
|
||||
:icon-name :i/close
|
||||
:on-press navigate-back
|
||||
:accessibility-label :back-button}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/request-to-join)
|
||||
:description :context-tag
|
||||
:context-tag {:type :community
|
||||
:size 24
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:community-name name}}]
|
||||
[gesture/scroll-view
|
||||
[:<>
|
||||
[quo/text
|
||||
{:style style/section-title
|
||||
:accessibility-label :community-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/address-to-share)]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:data [{:title (i18n/label :t/join-as-a {:role highest-role-text})
|
||||
:on-press show-addresses-for-permissions
|
||||
:description :text
|
||||
:action :arrow
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data selected-accounts}
|
||||
:description-props {:text (i18n/label :t/all-addresses)}}
|
||||
{:title (i18n/label :t/for-airdrops)
|
||||
:on-press show-airdrop-addresses
|
||||
:description :text
|
||||
:action :arrow
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data [airdrop-account]}
|
||||
:description-props {:text (:name airdrop-account)}}]}]
|
||||
[quo/text
|
||||
{:style style/section-title
|
||||
:accessibility-label :community-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/community-rules)]
|
||||
[community-rules/view id]]]
|
||||
[rn/view {:style (style/bottom-actions)}
|
||||
[quo/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-request-to-join)
|
||||
:track-icon :i/face-id
|
||||
:customization-color color
|
||||
:on-complete join-and-go-back}]]]))))
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||
{:keys [name color images]} (rf/sub [:communities/community id])
|
||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||
selected-accounts (rf/sub [:communities/selected-permission-accounts id])
|
||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||
highest-permission-role
|
||||
:t/member))]
|
||||
[rn/safe-area-view {:style style/container}
|
||||
[quo/page-nav
|
||||
{:text-align :left
|
||||
:icon-name :i/close
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:accessibility-label :back-button}]
|
||||
[quo/page-top
|
||||
{:title (i18n/label :t/request-to-join)
|
||||
:description :context-tag
|
||||
:context-tag {:type :community
|
||||
:size 24
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:community-name name}}]
|
||||
[gesture/scroll-view
|
||||
[:<>
|
||||
[quo/text
|
||||
{:style style/section-title
|
||||
:accessibility-label :community-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/address-to-share)]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:data [{:title (i18n/label :t/join-as-a {:role highest-role-text})
|
||||
:on-press #(rf/dispatch [:open-modal :addresses-for-permissions
|
||||
{:community-id id}])
|
||||
:description :text
|
||||
:action :arrow
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data selected-accounts}
|
||||
:description-props {:text (i18n/label :t/all-addresses)}}
|
||||
{:title (i18n/label :t/for-airdrops)
|
||||
:on-press #(rf/dispatch [:open-modal :airdrop-addresses
|
||||
{:community-id id}])
|
||||
:description :text
|
||||
:action :arrow
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data [airdrop-account]}
|
||||
:description-props {:text (:name airdrop-account)}}]}]
|
||||
[quo/text
|
||||
{:style style/section-title
|
||||
:accessibility-label :community-rules-title
|
||||
:weight :semi-bold
|
||||
:size :paragraph-1}
|
||||
(i18n/label :t/community-rules)]
|
||||
[community-rules/view id]]]
|
||||
[rn/view {:style (style/bottom-actions)}
|
||||
[quo/slide-button
|
||||
{:size :size-48
|
||||
:track-text (i18n/label :t/slide-to-request-to-join)
|
||||
:track-icon :i/face-id
|
||||
:customization-color color
|
||||
:on-complete #(join-community-and-navigate-back id)}]]]))
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
(ns status-im.contexts.communities.actions.addresses-for-permissions.style)
|
||||
|
||||
(def container {:flex 1})
|
||||
@@ -1,8 +1,11 @@
|
||||
(ns status-im.contexts.communities.actions.addresses-for-permissions.view
|
||||
(:require [quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.communities.actions.addresses-for-permissions.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]
|
||||
[utils.re-frame :as rf]))
|
||||
@@ -17,8 +20,8 @@
|
||||
nil))
|
||||
|
||||
(defn- balances->components-props
|
||||
[balances images-by-symbol]
|
||||
(for [{:keys [amount decimals type name] sym :symbol :as balance} balances]
|
||||
[balances]
|
||||
(for [{:keys [amount decimals type name] :as balance} balances]
|
||||
(cond-> balance
|
||||
true
|
||||
(assoc :type
|
||||
@@ -29,24 +32,22 @@
|
||||
|
||||
(= type constants/community-token-type-erc721)
|
||||
(assoc :collectible-name name
|
||||
:collectible-img-src (images-by-symbol sym))
|
||||
:collectible-img-src (resources/get-mock-image :collectible))
|
||||
|
||||
(= type constants/community-token-type-erc20)
|
||||
(assoc :amount (str (money/token->unit amount decimals))
|
||||
:token (:symbol balance)
|
||||
:token-img-src (images-by-symbol sym)))))
|
||||
(assoc :amount (str (money/token->unit amount decimals))
|
||||
:token (:symbol balance)))))
|
||||
|
||||
(defn- account-item
|
||||
[{:keys [color address name emoji]} _ _
|
||||
{:keys [selected-addresses community-id share-all-addresses? community-color]}]
|
||||
(let [balances (rf/sub [:communities/permissioned-balances-by-address community-id address])
|
||||
images-by-symbol (rf/sub [:communities/token-images-by-symbol community-id])]
|
||||
(let [balances (rf/sub [:communities/permissioned-balances-by-address community-id address])]
|
||||
[quo/account-permissions
|
||||
{:account {:name name
|
||||
:address address
|
||||
:emoji emoji
|
||||
:customization-color color}
|
||||
:token-details (balances->components-props balances images-by-symbol)
|
||||
:token-details (balances->components-props balances)
|
||||
:checked? (contains? selected-addresses address)
|
||||
:disabled? share-all-addresses?
|
||||
:on-change #(rf/dispatch [:communities/toggle-selected-permission-address
|
||||
@@ -55,15 +56,8 @@
|
||||
:customization-color community-color}]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||
toggle-share-all-addresses #(rf/dispatch [:communities/toggle-share-all-addresses id])
|
||||
update-previous-addresses (fn []
|
||||
(rf/dispatch [:communities/update-previous-permission-addresses id])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
reset-selected-addresses (fn []
|
||||
(rf/dispatch [:communities/reset-selected-permission-addresses id])
|
||||
(rf/dispatch [:hide-bottom-sheet]))]
|
||||
[{:keys [scroll-enabled? on-scroll]}]
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])]
|
||||
(rf/dispatch [:communities/get-permissioned-balances id])
|
||||
(fn []
|
||||
(let [{:keys [name color images]} (rf/sub [:communities/community id])
|
||||
@@ -73,7 +67,7 @@
|
||||
selected-addresses (rf/sub [:communities/selected-permission-addresses id])
|
||||
share-all-addresses? (rf/sub [:communities/share-all-addresses? id])
|
||||
unsaved-address-changes? (rf/sub [:communities/unsaved-address-changes? id])]
|
||||
[:<>
|
||||
[rn/safe-area-view {:style style/container}
|
||||
[quo/drawer-top
|
||||
{:type :context-tag
|
||||
:title (i18n/label :t/addresses-for-permissions)
|
||||
@@ -85,24 +79,26 @@
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:customization-color color}]
|
||||
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
:data [{:title (i18n/label :t/share-all-current-and-future-addresses)
|
||||
:action :selector
|
||||
:action-props {:on-change #(rf/dispatch
|
||||
[:communities/toggle-share-all-addresses
|
||||
id])
|
||||
:customization-color color
|
||||
:checked? share-all-addresses?}}]
|
||||
:container-style {:padding-bottom 16}}]
|
||||
|
||||
[gesture/flat-list
|
||||
{:render-fn account-item
|
||||
:render-data {:selected-addresses selected-addresses
|
||||
:community-id id
|
||||
:share-all-addresses? share-all-addresses?
|
||||
:community-color color}
|
||||
:header [quo/category
|
||||
{:list-type :settings
|
||||
:data [{:title
|
||||
(i18n/label
|
||||
:t/share-all-current-and-future-addresses)
|
||||
:action :selector
|
||||
:action-props
|
||||
{:on-change toggle-share-all-addresses
|
||||
:customization-color color
|
||||
:checked? share-all-addresses?}}]
|
||||
:container-style {:padding-bottom 16 :padding-horizontal 0}}]
|
||||
:content-container-style {:padding-horizontal 20}
|
||||
:scroll-enabled @scroll-enabled?
|
||||
:on-scroll on-scroll
|
||||
:key-fn :address
|
||||
:data accounts}]
|
||||
|
||||
@@ -114,18 +110,25 @@
|
||||
(empty? selected-addresses)
|
||||
(not highest-permission-role)
|
||||
(not unsaved-address-changes?))
|
||||
:on-press update-previous-addresses}
|
||||
:on-press (fn []
|
||||
(rf/dispatch
|
||||
[:communities/update-previous-permission-addresses
|
||||
id])
|
||||
(rf/dispatch [:navigate-back]))}
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press reset-selected-addresses}
|
||||
:on-press (fn []
|
||||
(rf/dispatch
|
||||
[:communities/reset-selected-permission-addresses id])
|
||||
(rf/dispatch [:navigate-back]))}
|
||||
:description (if (or (empty? selected-addresses)
|
||||
(not highest-permission-role))
|
||||
:top-error
|
||||
:top)
|
||||
:role (when-not checking? (role-keyword highest-permission-role))
|
||||
:error-message (cond
|
||||
(empty? selected-addresses)
|
||||
(i18n/label :t/no-addresses-selected)
|
||||
(empty? selected-addresses) (i18n/label :t/no-addresses-selected)
|
||||
(not highest-permission-role) (i18n/label
|
||||
:t/addresses-dont-contain-tokens-needed)
|
||||
:else nil)}]]))))
|
||||
|
||||
(not highest-permission-role)
|
||||
(i18n/label :t/addresses-dont-contain-tokens-needed))}]]))))
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns status-im.contexts.communities.actions.airdrop-addresses.view
|
||||
(:require
|
||||
[quo.core :as quo]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.contexts.communities.actions.airdrop-addresses.style :as style]
|
||||
[utils.i18n :as i18n]
|
||||
@@ -14,7 +14,7 @@
|
||||
:state (when (= airdrop-address (:address item)) :selected)
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:communities/set-airdrop-address (:address item) community-id])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
(rf/dispatch [:navigate-back]))
|
||||
:emoji (:emoji item)}])
|
||||
|
||||
(defn view
|
||||
@@ -33,7 +33,7 @@
|
||||
:on-button-press not-implemented/alert
|
||||
:community-logo (get-in images [:thumbnail :uri])
|
||||
:customization-color color}]
|
||||
[gesture/flat-list
|
||||
[rn/flat-list
|
||||
{:data selected-accounts
|
||||
:render-fn render-item
|
||||
:render-data [airdrop-address id]
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.biometric.events :as biometric]
|
||||
[status-im.common.parallax.blacklist :as blacklist]
|
||||
[status-im.common.parallax.view :as parallax]
|
||||
[status-im.common.parallax.whitelist :as whitelist]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.onboarding.enable-biometrics.style :as style]
|
||||
[status-im.navigation.state :as state]
|
||||
@@ -71,9 +71,9 @@
|
||||
(let [insets (safe-area/get-insets)]
|
||||
[rn/view {:style (style/page-container insets)}
|
||||
[page-title]
|
||||
(if blacklist/blacklisted?
|
||||
[enable-biometrics-simple]
|
||||
[enable-biometrics-parallax])
|
||||
(if whitelist/whitelisted?
|
||||
[enable-biometrics-parallax]
|
||||
[enable-biometrics-simple])
|
||||
[enable-biometrics-buttons insets]]))
|
||||
|
||||
(defn view
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.parallax.blacklist :as blacklist]
|
||||
[status-im.common.parallax.view :as parallax]
|
||||
[status-im.common.parallax.whitelist :as whitelist]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.onboarding.enable-notifications.style :as style]
|
||||
[status-im.contexts.shell.jump-to.utils :as shell.utils]
|
||||
@@ -78,9 +78,9 @@
|
||||
:icon-name :i/arrow-left
|
||||
:on-press #(rf/dispatch [:navigate-back-within-stack :enable-biometrics])}]
|
||||
[page-title]]
|
||||
(if blacklist/blacklisted?
|
||||
[enable-notifications-simple]
|
||||
[enable-notifications-parallax])
|
||||
(if whitelist/whitelisted?
|
||||
[enable-notifications-parallax]
|
||||
[enable-notifications-simple])
|
||||
[enable-notification-buttons {:insets insets}]]))
|
||||
|
||||
(defn view
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im.common.parallax.blacklist :as blacklist]
|
||||
[status-im.common.parallax.view :as parallax]
|
||||
[status-im.common.parallax.whitelist :as whitelist]
|
||||
[status-im.common.resources :as resources]
|
||||
[status-im.contexts.onboarding.generating-keys.style :as style]
|
||||
[utils.i18n :as i18n]))
|
||||
@@ -149,9 +149,9 @@
|
||||
[]
|
||||
(let [insets (safe-area/get-insets)]
|
||||
[rn/view {:style (style/page-container insets)}
|
||||
(if blacklist/blacklisted?
|
||||
[:f> f-simple-page insets]
|
||||
[parallax-page insets])]))
|
||||
(if whitelist/whitelisted?
|
||||
[parallax-page insets]
|
||||
[:f> f-simple-page insets])]))
|
||||
|
||||
(defn generating-keys
|
||||
[]
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user