Compare commits

...
Author SHA1 Message Date
Brian Sztamfater 4d381bd866 add more tests 2024-03-05 11:43:19 -03:00
Brian Sztamfater ba68ccdbac fix address input scan 2024-03-05 11:43:18 -03:00
Brian Sztamfater 178dd93a3b try to fix tests 2024-03-05 11:43:18 -03:00
Brian Sztamfater f7d4645946 fix navigate-back 2024-03-05 11:43:18 -03:00
Brian Sztamfater 1285d3f874 add unit tests 2024-03-05 11:43:17 -03:00
Brian Sztamfater 80fd9e00b0 naming refactor 2024-03-05 11:43:17 -03:00
Brian Sztamfater d667e826b2 fix: add support for multiple modals when tracking modal-view-ids in app-db 2024-03-05 11:43:15 -03:00
Sean Hagstrom f788d7bc85 [#19035] Add status tag for pending contact request to contact profile (#19075)
* chore: add english translation for contact-profile-request-pending

* feature: integrate status-tag for pending contact-request
2024-03-05 14:07:45 +00:00
Lungu Cristian 7415ebdc78 Updated placeholder for no pinned messages in chat (#18923)
* fix: same placeholder for chat & community pins

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>

* fix: text linebreak

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>

---------

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>
2024-03-05 15:47:48 +02:00
Alexander 58e9ae0334 Add peer syncing toggle in "Advanced settings" (#18906)
* Add peer syncing toggle in "Advanced settings"

* status-go-version.json

* Fixes
2024-03-05 12:59:06 +01:00
Sean Hagstrom e783deb5af [#18964] Support custom message when sending contact request (#18998)
* tweak: allow for optional message to be sent when making a contact request

* chore: migrate contact-request event handler from `rf/defn` to `rf/reg-event-fx`

* test: add tests for sending a contact request

* chore: make it easier to test on-success and on-error behaviour after sending a contact request

* tidy: use reframe fx for declaring json-rpc/call

* tidy: remove unused success event handler for send a contact request
2024-03-05 10:45:16 +00:00
Parvesh Monu e771d056a0 fix multiple set view-id events dispatched (#19083) 2024-03-05 11:50:00 +05:30
Omar Basem 62f68ff44b Fix: slide button (#18922)
* fix: slide button
2024-03-05 07:50:03 +04:00
Icaro Motta 5d1e1f8005 Make integration tests more enjoyable to use (#19025)
This commit brings numerous improvements to integration tests. The next step
will be to apply the same improvements to contract tests.

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

Improvements:

- Setting up the application and logged account per test is now done with an
  async test fixture, which is a very idiomatic way to solve this problem. No
  need anymore to write macros to wrap day8.re-frame.test/wait-for. The macros
  in test-helpers.integration will be removed once we apply the same
  improvements to contract tests.
- Integration test timeouts can be controlled per test, with a configurable,
  global default (60s).
- Now the integration test suite will fail-fast by default, i.e. a test failure
  short-circuits the entire suite immediately. This option can be overridden on
  a test-by-test basis. This improvement is very useful when investigating
  failures because the error will be shown on the spot, with no need to search
  backwards across lots of logs.
- Noisy messages from re-frame can be silenced with a test fixture. We can
  silence even more in the future if we remove the hardcoded printf call from
  C++ on every signal and control it with Clojure. We can disable most logs as
  well with the more direct (status-im.common.log/setup "ERROR") at the top of
  tests.integration-test.core. We can make verbosity even more convenient to
  control, but I think this should be designed outside this PR.
- Removed dependency on lib day8.re-frame/test for integration tests (see
  detailed explanation below).
- Each call to (our) wait-for can customize the timeout to process re-frame
  event IDs passed to it.
- Syntax is now flat, instead of being nested on every call to wait-for. You
  can now compose other async operations anywhere in a test.

Notes:

- promesa.core/do is essential in the integration test suite, as it makes sync &
  async operations play nice with each other without the developer having to
  promisify anything manually.
- There are lots of logs related to async storage ("unexpected token u in JSON at
  position..."). This isn't fixed yet.

Are we not going to use day8.re-frame.test?

We don't need this library in integration tests and we won't need it in contract
tests. Whether it will be useful after we remove it from integration and
contract tests is yet to be seen (probably not).

A few reasons:

- The async model of promises is well understood and battle tested. The one
  devised in the lib is poorly understood and rigid.
- There's basically no way to correctly integrate other async operations in the
  test, unless they can be fully controlled via re-frame events. For instance,
  how would you control timeouts? How would you retry in a test? How would
  forcefully delay an operation by a few seconds? These things are useful (to me
  at least) when developing integration/contract tests.
- Every call to day8.re-frame.test/wait-for forces you to nest code one more
  level. Code readability suffers from that choice.
- Have you ever looked up the implementation of wait-for? It's quite convoluted.
  One could say the source code is not that important, but many times I had to
  look it up because I couldn't understand the async model they built with their
  macro approach. The de facto primitive in JS for asynchronicity is promises,
  and we fully leverage it in this PR.
- The lib has an interesting macro run-test-sync, but we have no usage for it. I
  used it in status-mobile for a while. At one point, all event unit tests for
  the Activity Center used it (e.g. commit
  08fb0de7b0), but I replaced them with the
  simpler pure function style.
2024-03-04 22:38:42 -03:00
Jamie Caprani 191c876f47 chore(wallet): some minor cleanups: move sheets to appropriate level, remove unused rf event, improve one rf event api (#18895) 2024-03-04 12:34:21 -08:00
Ibrahem Khalil 0be66e28c1 Fix collectible/token icon and name on addresses for permissions screen (#18897) 2024-03-04 18:34:10 +02:00
Nazarii F fcdd6c5a79 Added destructuring section to new-guidelines.md (#18731)
Adds a section explaining the use cases of destructuring function parameters to
improve code style and reduce the chance of bugs.
2024-03-04 11:38:50 -03:00
Icaro Motta 27e177f18b Account selection: Use bottom sheet component (#18919)
Use bottom sheet component as designed in
Figma https://www.figma.com/file/h9wo4GipgZURbqqr1vShFN/Communities-for-Mobile?type=design&node-id=16409-98076&mode=design&t=jrVNb3JnWNurJwP8-0

- Fixes no animation when closing Addresses For Permissions modal:
  https://github.com/status-im/status-mobile/issues/18617
- Fixes drawer is always expanded:
  https://github.com/status-im/status-mobile/issues/18619

Additionally:

- Fixed incorrect code passing a function instance to a style prop, which leads
  to incorrect appearance for settings.category.reorder.view/view.
- Optimized Reagent a little bit by extracting functions that need to close over
  the community ID to the mount phase. That way, we avoid regenerating function
  instances on every re-render and Reagent can avoid a bit of re-work.

The challenge was to make the scrollable content work inside a
bottom sheet, while supporting the designs for a fixed (always visible) header
and footer.
2024-03-04 09:23:30 -03:00
Lungu Cristian f8cd14296f Add Promesa to simplify working with promises (#18767)
* added promesa (clj)

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>

* ref(resize): using promesa instead of passing cb

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>

---------

Signed-off-by: Cristian Lungu <lungucristian95@gmail.com>
2024-03-04 13:59:52 +02:00
Parvesh Monu 851eb6ea8f fix settings navigation (#19080) 2024-03-04 16:06:59 +05:30
72 changed files with 1240 additions and 811 deletions
+1
View File
@@ -26,6 +26,7 @@
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}}
+9
View File
@@ -0,0 +1,9 @@
{: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}}
+31 -28
View File
@@ -22,34 +22,37 @@
: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
"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"}
{"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"}
:style-map
{:no-comma {:map {:comma? false}}
+148 -130
View File
@@ -90,20 +90,20 @@
},
{
"path": "cider/cider-nrepl/0.25.3/cider-nrepl-0.25.3",
"path": "cider/cider-nrepl/0.31.0/cider-nrepl-0.31.0",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "5ae0efd9377a5e60c084bdaf4a2ce094f759ce23",
"sha256": "0drxf9nm23i1pcgrkwbcr09msq37csilzww38709add0hz8spjhq"
"sha1": "1f28a4a834a7a46cf24def971b1a705a6795c73a",
"sha256": "0h4pyzy8rzzh567khvimw2cs8jr640kqxgaxvbfx1s5yfp56fka2"
}
},
{
"path": "cider/piggieback/0.4.1/piggieback-0.4.1",
"path": "cider/piggieback/0.5.2/piggieback-0.5.2",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "0a02a3e2ecd7a126ab60d8a44793342f20ced79b",
"sha256": "142vl5np33akcrnn6pksi0rjfsmmi528villxsj6cwcndvybiw4m"
"sha1": "ecfd5c286a85db3f059e75c37fca5722d9e26f79",
"sha256": "1ps9yf3cxmlm447hqkidjb5xry90n0wl3jk0jn28fagq31lzylkl"
}
},
@@ -251,15 +251,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/google/errorprone/error_prone_annotations/2.15.0/error_prone_annotations-2.15.0",
"host": "https://repo1.maven.org/maven2",
@@ -306,11 +297,11 @@
},
{
"path": "com/google/javascript/closure-compiler-unshaded/v20230411/closure-compiler-unshaded-v20230411",
"path": "com/google/javascript/closure-compiler-unshaded/v20230802/closure-compiler-unshaded-v20230802",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "2f5d7ab921f9cc07ffeb4e1c0f156f164c650eeb",
"sha256": "0gphdrrhr88bcqa1scndachvhbayh7m11zm9hcsmvzn9bw72pabw"
"sha1": "0a2498a4d45bf5896042f31da0cd30c5e7b415af",
"sha256": "0jvgqq0gnvm4jw2zac4677ds05klvsjalszdzcq3nw8g7fjyjv2x"
}
},
@@ -333,38 +324,11 @@
},
{
"path": "commons-codec/commons-codec/1.15/commons-codec-1.15",
"path": "com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "49d94806b6e3dc933dacbd8acb0fdbab8ebd1e5d",
"sha256": "0qzd8v96j4x7jjcfpvvdh9ar1xhwxpxi2rh51nzhj0br7bbgdsdk"
}
},
{
"path": "commons-fileupload/commons-fileupload/1.4/commons-fileupload-1.4",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "f95188e3d372e20e7328706c37ef366e5d7859b0",
"sha256": "1xyyl54sfxsdcwxdyq6b0azmr31b4dwqns850jjkw9a9dwrh5v54"
}
},
{
"path": "commons-io/commons-io/2.11.0/commons-io-2.11.0",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "a2503f302b11ebde7ebc3df41daebe0e4eea3689",
"sha256": "020946yakki3qzc652arfndzi594drxanidz9bawbb6vhxnjy6wn"
}
},
{
"path": "compojure/compojure/1.5.2/compojure-1.5.2",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "0b5258d0616ffc5f64c2b6d95f09de56d24df439",
"sha256": "1s2k05lwnlm9a66mxnsss437i9gp70dny8y2rlfkl090s6mdqsaf"
"sha1": "c9ad4a0850ab676c5c64461a05ca524cdfff59f1",
"sha256": "170rflxnqnah0265ik2aylmxkshyqbf2zas9bp2l32xqj9l6jsaf"
}
},
@@ -404,6 +368,42 @@
}
},
{
"path": "commons-codec/commons-codec/1.15/commons-codec-1.15",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "49d94806b6e3dc933dacbd8acb0fdbab8ebd1e5d",
"sha256": "0qzd8v96j4x7jjcfpvvdh9ar1xhwxpxi2rh51nzhj0br7bbgdsdk"
}
},
{
"path": "commons-fileupload/commons-fileupload/1.4/commons-fileupload-1.4",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "f95188e3d372e20e7328706c37ef366e5d7859b0",
"sha256": "1xyyl54sfxsdcwxdyq6b0azmr31b4dwqns850jjkw9a9dwrh5v54"
}
},
{
"path": "commons-io/commons-io/2.11.0/commons-io-2.11.0",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "a2503f302b11ebde7ebc3df41daebe0e4eea3689",
"sha256": "020946yakki3qzc652arfndzi594drxanidz9bawbb6vhxnjy6wn"
}
},
{
"path": "compojure/compojure/1.5.2/compojure-1.5.2",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "0b5258d0616ffc5f64c2b6d95f09de56d24df439",
"sha256": "1s2k05lwnlm9a66mxnsss437i9gp70dny8y2rlfkl090s6mdqsaf"
}
},
{
"path": "crypto-equality/crypto-equality/1.0.1/crypto-equality-1.0.1",
"host": "https://repo.clojars.org",
@@ -449,6 +449,15 @@
}
},
{
"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",
@@ -504,11 +513,11 @@
},
{
"path": "io/undertow/undertow-core/2.2.4.Final/undertow-core-2.2.4.Final",
"path": "io/undertow/undertow-core/2.3.10.Final/undertow-core-2.3.10.Final",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "78650b4029dd9280c4769d9425b5559f12cb83bf",
"sha256": "1brpkd2l98byf76jga6hj5drv5sj2d93lxlq2xz0rxpqyqas1xm4"
"sha1": "96d1d5ca6406a75a285b95ea8f4b39e0fb2d707e",
"sha256": "1s1m5hfhmfr7jsp4bn4c6fhdbgiz72mz0a96494nyhfa0b4lql8l"
}
},
@@ -594,11 +603,11 @@
},
{
"path": "nrepl/nrepl/1.0.0/nrepl-1.0.0",
"path": "nrepl/nrepl/0.9.0/nrepl-0.9.0",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "f47774c43493efdc879d36b95ebd67ea0d9c890a",
"sha256": "1fx5ssmixgqmklliw0ng8fjz41kkhys56x8dbwv9yqrfzws9f2x3"
"sha1": "49beada131959f08f9a20899affbd1b10c03a668",
"sha256": "1phak0479s27ffw9wzz7pi8cqqs6ipsm15dhgw9szxxcfhx529qa"
}
},
@@ -611,15 +620,6 @@
}
},
{
"path": "org/apache/ant/ant/1.10.11/ant-1.10.11",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "b875cd48a0bc955ae9c5c477ad991e1f26fb24d2",
"sha256": "0m07pifkdpwghpp8wvqh14sbxazmjbkkpsfakw6ixq5apfdvih48"
}
},
{
"path": "org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11",
"host": "https://repo1.maven.org/maven2",
@@ -630,11 +630,11 @@
},
{
"path": "org/babashka/sci/0.7.38/sci-0.7.38",
"host": "https://repo.clojars.org",
"path": "org/apache/ant/ant/1.10.11/ant-1.10.11",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "ef2d8c74065b9a7d685a11bff017676db308a923",
"sha256": "04pkxwcgkd1p4f4rszsr6pp18fl0vni1az47a390llrhyyrjcckn"
"sha1": "b875cd48a0bc955ae9c5c477ad991e1f26fb24d2",
"sha256": "0m07pifkdpwghpp8wvqh14sbxazmjbkkpsfakw6ixq5apfdvih48"
}
},
@@ -647,6 +647,15 @@
}
},
{
"path": "org/babashka/sci/0.7.38/sci-0.7.38",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "ef2d8c74065b9a7d685a11bff017676db308a923",
"sha256": "04pkxwcgkd1p4f4rszsr6pp18fl0vni1az47a390llrhyyrjcckn"
}
},
{
"path": "org/checkerframework/checker-qual/3.12.0/checker-qual-3.12.0",
"host": "https://repo1.maven.org/maven2",
@@ -737,15 +746,6 @@
}
},
{
"path": "org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "533ce2bdbb7925db781449abb6527af1e6c5e782",
"sha256": "0js19lw8bp9gym3pn47h867vhf65j18qc6x1pfn883vkwyasm18l"
}
},
{
"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",
@@ -755,6 +755,15 @@
}
},
{
"path": "org/clojure/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "533ce2bdbb7925db781449abb6527af1e6c5e782",
"sha256": "0js19lw8bp9gym3pn47h867vhf65j18qc6x1pfn883vkwyasm18l"
}
},
{
"path": "org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0",
"host": "https://repo1.maven.org/maven2",
@@ -782,15 +791,6 @@
}
},
{
"path": "org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "692882a35d7b50947d6e4852fba8a51d8d5e3646",
"sha256": "08fzw3srrppgq1d11sh1ghnyvi24ixa10kbqsncc7xyx7fybcs0k"
}
},
{
"path": "org/clojure/tools.analyzer.jvm/1.2.2/tools.analyzer.jvm-1.2.2",
"host": "https://repo1.maven.org/maven2",
@@ -800,6 +800,15 @@
}
},
{
"path": "org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "692882a35d7b50947d6e4852fba8a51d8d5e3646",
"sha256": "08fzw3srrppgq1d11sh1ghnyvi24ixa10kbqsncc7xyx7fybcs0k"
}
},
{
"path": "org/clojure/tools.cli/1.0.206/tools.cli-1.0.206",
"host": "https://repo1.maven.org/maven2",
@@ -828,11 +837,11 @@
},
{
"path": "org/clojure/tools.reader/1.3.6/tools.reader-1.3.6",
"path": "org/clojure/tools.reader/1.3.7/tools.reader-1.3.7",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "927809dcb44fa726e4969d993e3e733636d95ebb",
"sha256": "1q5q7fmshybvp55f6qys8i5sbzfaix5v9f9b55dkbhv55hgv7l8i"
"sha1": "c60dfd3d79cbc5ec6264ba45c14b8d4c9b6708b2",
"sha256": "1mr0qx3gw1myfls07vrx3arwsi5n95b2lwk74ijpj0z3lzpzlj7m"
}
},
@@ -846,38 +855,38 @@
},
{
"path": "org/jboss/logging/jboss-logging/3.4.1.Final/jboss-logging-3.4.1.Final",
"path": "org/jboss/logging/jboss-logging/3.4.3.Final/jboss-logging-3.4.3.Final",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "40fd4d696c55793e996d1ff3c475833f836c2498",
"sha256": "1f7f4kjn3v6vibhgsr3k8hl0r2xq0c2rbcl82dx0bqg5jdyqgzlf"
"sha1": "c4bd7e12a745c0e7f6cf98c45cdcdf482fd827ea",
"sha256": "0jdcziqbdzmah981zv3q88k2zrnclr2h1k3h3vjn002m9p54qchb"
}
},
{
"path": "org/jboss/threads/jboss-threads/3.1.0.Final/jboss-threads-3.1.0.Final",
"path": "org/jboss/threads/jboss-threads/3.5.0.Final/jboss-threads-3.5.0.Final",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "9b260c0302f637a84a52d3d118214a3c59217615",
"sha256": "0yc0p71y7yjhqjhkvqqi9xqgljavp3aslnik2k7dppbxnkrnlff9"
"sha1": "dd23d4788b3eafe9597ef3fe028e46ceb293ba8d",
"sha256": "1cchp54dw1578my27siim3h5jbf240aq8q6xd3z2b1ajgxxbcl71"
}
},
{
"path": "org/jboss/xnio/xnio-api/3.8.0.Final/xnio-api-3.8.0.Final",
"path": "org/jboss/xnio/xnio-api/3.8.8.Final/xnio-api-3.8.8.Final",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "e2c29acf42ac6f42c34f0b74ba089e3f3d1b2394",
"sha256": "041qnvb74bkgmfxyd23vdl26il55cmfbhi6a4bm3fcmyrpapjfjl"
"sha1": "1ba9c8b9a8dea1c6cd656155943e6d4c2c631fa7",
"sha256": "0wvqdcbardi55l77aw5404qgw70384hw155xvc66shn7l6z8h6bh"
}
},
{
"path": "org/jboss/xnio/xnio-nio/3.8.0.Final/xnio-nio-3.8.0.Final",
"path": "org/jboss/xnio/xnio-nio/3.8.8.Final/xnio-nio-3.8.8.Final",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "90c57dcf7f8c846b4da331d0e6e048c39842c92a",
"sha256": "1zndnb5648wqw23gj80zjqk3yd8gq6grqhz9n4zrcqixx1z586jf"
"sha1": "a5d2faf8d02e0a0bb9e9eabca8e38173cb640331",
"sha256": "0pxw2iv1q1yzk39knc650rg4vflsyjzhf07mwm2s5aqn5h82sk3i"
}
},
@@ -909,11 +918,20 @@
},
{
"path": "org/slf4j/slf4j-api/1.7.36/slf4j-api-1.7.36",
"path": "org/slf4j/slf4j-api/2.0.9/slf4j-api-2.0.9",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "6c62681a2f655b49963a5983b8b0950a6120ae14",
"sha256": "1h512ry8g0nriazg3dqzs6s96502a77drw8vq26nfya97rg5gvyk"
"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"
}
},
@@ -927,11 +945,11 @@
},
{
"path": "org/wildfly/common/wildfly-common/1.5.2.Final/wildfly-common-1.5.2.Final",
"path": "org/wildfly/common/wildfly-common/1.5.4.Final/wildfly-common-1.5.4.Final",
"host": "https://repo1.maven.org/maven2",
"jar": {
"sha1": "8eba40cfe86bcfcc223551e75201e6e7574c7c36",
"sha256": "17rkkm9dqbxdzpamwl9jr8z285awsj6hzpavzmc87wcz9469hp5b"
"sha1": "735ceee5616d5143bac1bc740e444697073c002f",
"sha256": "0sp48y3q7bmp3bjb7a6fpz8gb7ssizvxlw5wdv2xwa6mifpkrnlz"
}
},
@@ -944,15 +962,6 @@
}
},
{
"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",
@@ -962,15 +971,6 @@
}
},
{
"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,6 +998,24 @@
}
},
{
"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",
@@ -1035,11 +1053,11 @@
},
{
"path": "thheller/shadow-cljs/2.25.0/shadow-cljs-2.25.0-aot",
"path": "thheller/shadow-cljs/2.26.2/shadow-cljs-2.26.2-aot",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "013921db91ce4a3616aec9c72c1832a014a0fece",
"sha256": "0ks380z7h8i2ylirvjgmlicq9jjpz9w71gjv521h4xs5fb273cl0"
"sha1": "ab6b31649cb03e352369698781207db4f6da6d5f",
"sha256": "0mh28nykpillkym7hvplrr7vy5hn6a2ymafyf4yfl5y2kfx4yq42"
}
},
@@ -1053,11 +1071,11 @@
},
{
"path": "thheller/shadow-undertow/0.3.1/shadow-undertow-0.3.1",
"path": "thheller/shadow-undertow/0.3.3/shadow-undertow-0.3.3",
"host": "https://repo.clojars.org",
"jar": {
"sha1": "9be444bea4037bb80b451cc52a8e80359c4c45be",
"sha256": "174s2rdxvp7d4jg9kvzjadps42bdsbi05rs2pjy5i0ssq9n23zwa"
"sha1": "ba377c3b70fd942b3ca7e38f055412a441626711",
"sha256": "10w2slj4znm93j0qq3ldj9hj0i7a50vbnmn6kv8i77fakikdjc48"
}
},
+27 -25
View File
@@ -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.25.3/cider-nrepl-0.25.3.jar
cider/piggieback/0.4.1/piggieback-0.4.1.jar
cider/cider-nrepl/0.31.0/cider-nrepl-0.31.0.jar
cider/piggieback/0.5.2/piggieback-0.5.2.jar
clj-kondo/clj-kondo/2023.09.07/clj-kondo-2023.09.07.jar
cljs-bean/cljs-bean/1.9.0/cljs-bean-1.9.0.jar
clout/clout/2.1.2/clout-2.1.2.jar
@@ -26,35 +26,36 @@ 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/v20230411/closure-compiler-unshaded-v20230411.jar
com/google/javascript/closure-compiler-unshaded/v20230802/closure-compiler-unshaded-v20230802.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
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/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
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.2.4.Final/undertow-core-2.2.4.Final.jar
io/undertow/undertow-core/2.3.10.Final/undertow-core-2.3.10.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
@@ -64,12 +65,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/1.0.0/nrepl-1.0.0.jar
nrepl/nrepl/0.9.0/nrepl-0.9.0.jar
nubank/matcher-combinators/3.8.8/matcher-combinators-3.8.8.jar
org/apache/ant/ant/1.10.11/ant-1.10.11.jar
org/apache/ant/ant-launcher/1.10.11/ant-launcher-1.10.11.jar
org/babashka/sci/0.7.38/sci-0.7.38.jar
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/babashka/sci/0.7.38/sci-0.7.38.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
@@ -80,41 +81,42 @@ 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/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/google-closure-library/0.0-20230227-c7c0a541/google-closure-library-0.0-20230227-c7c0a541.jar
org/clojure/math.combinatorics/0.2.0/math.combinatorics-0.2.0.jar
org/clojure/spec.alpha/0.3.218/spec.alpha-0.3.218.jar
org/clojure/test.check/1.1.1/test.check-1.1.1.jar
org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0.jar
org/clojure/tools.analyzer.jvm/1.2.2/tools.analyzer.jvm-1.2.2.jar
org/clojure/tools.analyzer/1.1.0/tools.analyzer-1.1.0.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.6/tools.reader-1.3.6.jar
org/clojure/tools.reader/1.3.7/tools.reader-1.3.7.jar
org/javassist/javassist/3.18.1-GA/javassist-3.18.1-GA.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/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/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/1.7.36/slf4j-api-1.7.36.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/wildfly/client/wildfly-client-config/1.0.1.Final/wildfly-client-config-1.0.1.Final.jar
org/wildfly/common/wildfly-common/1.5.2.Final/wildfly-common-1.5.2.Final.jar
org/wildfly/common/wildfly-common/1.5.4.Final/wildfly-common-1.5.4.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.25.0/shadow-cljs-2.25.0-aot.jar
thheller/shadow-cljs/2.26.2/shadow-cljs-2.26.2-aot.jar
thheller/shadow-cljsjs/0.0.22/shadow-cljsjs-0.0.22.jar
thheller/shadow-undertow/0.3.1/shadow-undertow-0.3.1.jar
thheller/shadow-undertow/0.3.3/shadow-undertow-0.3.3.jar
thheller/shadow-util/0.7.0/shadow-util-0.7.0.jar
tigris/tigris/0.1.2/tigris-0.1.2.jar
+1
View File
@@ -10,6 +10,7 @@
[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"]
@@ -20,7 +20,8 @@
current-fleet
webview-debug
test-networks-enabled?
is-goerli-enabled?]}]
is-goerli-enabled?
peer-syncing-enabled?]}]
(keep
identity
[{:size :small
@@ -28,7 +29,7 @@
:accessibility-label :network-button
:container-margin-top 8
:on-press
#(re-frame/dispatch [:navigate-to :network-settings])
#(re-frame/dispatch [:open-modal :network-settings])
:accessory :text
:accessory-text network-name
:chevron true}
@@ -37,13 +38,13 @@
:accessibility-label :network-button
:container-margin-top 8
:on-press
#(re-frame/dispatch [:navigate-to :network-info])
#(re-frame/dispatch [:open-modal :network-info])
:chevron true}
{:size :small
:title (i18n/label :t/log-level)
:accessibility-label :log-level-settings-button
:on-press
#(re-frame/dispatch [:navigate-to :log-level-settings])
#(re-frame/dispatch [:open-modal :log-level-settings])
:accessory :text
:accessory-text current-log-level
:chevron true}
@@ -51,7 +52,7 @@
:title (i18n/label :t/fleet)
:accessibility-label :fleet-settings-button
:on-press
#(re-frame/dispatch [:navigate-to :fleet-settings])
#(re-frame/dispatch [:open-modal :fleet-settings])
:accessory :text
:accessory-text current-fleet
:chevron true}
@@ -66,14 +67,14 @@
:accessibility-label :rpc-usage-info
:container-margin-top 8
:on-press
#(re-frame/dispatch [:navigate-to :rpc-usage-info])
#(re-frame/dispatch [:open-modal :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 [:navigate-to :peers-stats])
#(re-frame/dispatch [:open-modal :peers-stats])
:chevron true}
{:size :small
:title (i18n/label :t/light-client-enabled)
@@ -119,11 +120,19 @@
#(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
[:navigate-to :currency-settings])
[:open-modal :currency-settings])
:chevron true}]))
(defn- flat-list-data
@@ -145,7 +154,8 @@
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]]
current-fleet [:fleets/current-fleet]
peer-syncing-enabled? [:profile/peer-syncing-enabled?]]
[list/flat-list
{:data (flat-list-data
{:network-name network-name
@@ -156,6 +166,7 @@
:dev-mode? false
:webview-debug webview-debug
:test-networks-enabled? test-networks-enabled?
:is-goerli-enabled? is-goerli-enabled?})
:is-goerli-enabled? is-goerli-enabled?
:peer-syncing-enabled? peer-syncing-enabled?})
:key-fn (fn [_ i] (str i))
:render-fn render-item}]))
@@ -102,7 +102,7 @@
:chevron true
:icon :main-icons/username}
registrar
(assoc :on-press #(re-frame/dispatch [:navigate-to :ens-main registrar])))]
(assoc :on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :contacts-list])}]
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :privacy-and-security])}]
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :quo-preview])}])
:on-press #(re-frame/dispatch [:open-modal :quo-preview])}])
(when config/quo-preview-enabled?
[list.item/list-item
{:icon :main-icons/appearance
:title "Status IM Components"
:accessibility-label :status-im-common-components
:chevron true
:on-press #(re-frame/dispatch [:navigate-to :status-im-preview])}])
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :appearance])}]
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :notifications])}]
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :sync-settings])}]
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :keycard-settings])}])
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :advanced-settings])}]
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :help-center])}]
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :about-app])}]
:on-press #(re-frame/dispatch [:open-modal :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 [:navigate-to :settings-syncing])}])
:on-press #(re-frame/dispatch [:open-modal :settings-syncing])}])
[react/view {:padding-vertical 24}
[list.item/list-item
{:icon :main-icons/log-out
+26
View File
@@ -106,6 +106,32 @@ 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
@@ -14,28 +14,26 @@
[react-native.reanimated :as reanimated]))
(defn drag-gesture
[x-pos gestures-disabled? set-gestures-disabled disabled? track-width sliding-complete?
[x-pos disabled? track-width sliding-complete?
set-sliding-complete
on-complete reset-fn]
(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?))
(set-gestures-disabled true)
(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))))))))
(-> (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 view
"Options
@@ -55,14 +53,11 @@
[track-width set-track-width] (rn/use-state nil)
[sliding-complete?
set-sliding-complete] (rn/use-state false)
[gestures-disabled?
set-gestures-disabled] (rn/use-state disabled?)
on-track-layout (rn/use-callback
#(set-track-width (oops/oget % "nativeEvent.layout.width")))
reset-fn (rn/use-callback
(fn []
(set-sliding-complete false)
(set-gestures-disabled false)
(animations/reset-track-position x-pos)))
dimensions (rn/use-callback
(partial utils/get-dimensions
@@ -77,15 +72,13 @@
[dimensions])
custom-color (if (= type :danger) :danger customization-color)
gesture (rn/use-memo #(drag-gesture x-pos
gestures-disabled?
set-gestures-disabled
disabled?
(dimensions :usable-track)
sliding-complete?
set-sliding-complete
on-complete
reset-fn)
[gestures-disabled? sliding-complete? disabled?])]
[sliding-complete? disabled?])]
[gesture/gesture-detector
{:gesture gesture}
[reanimated/view
@@ -16,9 +16,9 @@
(reagent/flush))
(defn- reorder-category-internal
[{:keys [label data blur? theme]}]
[{:keys [label data blur? theme container-style]}]
(reagent/with-let [atom-data (reagent/atom data)]
[rn/view {:style style/container}
[rn/view {:style (merge (style/container label) container-style)}
[text/text
{:weight :medium
:size :paragraph-2
@@ -1,5 +1,6 @@
(ns quo.components.wallet.account-permissions.view
(:require [quo.components.avatars.account-avatar.view :as account-avatar]
(:require [clojure.string :as string]
[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]
@@ -28,17 +29,24 @@
(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]}]
^{: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)))]]))
(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)))]]))
(defn- view-internal
[{:keys
@@ -30,7 +30,7 @@
:style {:margin-left 4}}
(case type
:token (str amount " " token)
:collectible collectible-name
:collectible (str amount " " collectible-name)
nil)]
(when divider?
[rn/view
+8 -1
View File
@@ -3,6 +3,7 @@
["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]
@@ -29,7 +30,13 @@
(assoc props :source {:uri source})
props)])
(defn image-get-size [uri callback] (.getSize ^js (.-Image ^js react-native) uri callback))
(defn image-get-size
[uri]
(p/create (fn [res rej]
(.getSize ^js (.-Image ^js react-native)
uri
(fn [width height] (res [width height]))
rej))))
(def text (reagent/adapt-react-class (.-Text ^js react-native)))
(def text-input (reagent/adapt-react-class (.-TextInput ^js react-native)))
+2 -4
View File
@@ -3,7 +3,5 @@
["react-native-image-resizer" :default image-resizer]))
(defn resize
[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)))
[{:keys [path max-width max-height quality]}]
(.createResizedImage image-resizer path max-width max-height "JPEG" quality 0 nil false))
+12 -11
View File
@@ -3,18 +3,18 @@
[quo.foundations.colors :as colors]
[react-native.platform :as platform]))
(def ^:private sheet-border-radius 20)
(defn sheet
[{:keys [top]} window-height selected-item]
[{:keys [max-height]}]
{:position :absolute
:max-height (- window-height top)
:z-index 1
:bottom 0
:left 0
:right 0
:border-top-left-radius 20
:border-top-right-radius 20
:overflow (when-not selected-item :hidden)
:flex 1})
:z-index 1
:max-height max-height
:border-top-left-radius sheet-border-radius
:border-top-right-radius sheet-border-radius})
(def gradient-bg
{:position :absolute
@@ -31,10 +31,11 @@
:bottom 0})
(defn sheet-content
[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))
[{: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
:background-color (if shell?
:transparent
(colors/theme-colors colors/white colors/neutral-95 theme))})
+17 -8
View File
@@ -56,6 +56,10 @@
(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 view
[{:keys [hide? insets]}
{:keys [content selected-item padding-bottom-override border-radius on-close shell?
@@ -64,6 +68,8 @@
(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)
@@ -80,7 +86,10 @@
top (- window-height (:top insets) @sheet-height)
bottom (if selected-item-smaller-than-sheet?
(+ @sheet-height bottom-margin)
(:bottom insets))]
(: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)
@@ -105,7 +114,7 @@
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:transform [{:translateY translate-y}]}
(style/sheet insets window-height selected-item))}
(style/sheet {:max-height sheet-max-height}))}
(when shell?
[blur/ios-view
{:style style/shell-bg
@@ -114,14 +123,14 @@
: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)}
{:on-layout set-item-height
:style (style/selected-item theme top bottom selected-item-smaller-than-sheet? border-radius)}
[selected-item]])
[rn/view
{:style (style/sheet-content theme padding-bottom-override insets shell? bottom-margin)
:on-layout #(reset! sheet-height (.-nativeEvent.layout.height ^js %))}
{: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
@@ -9,7 +9,7 @@
(defn view
[{:keys [track-text customization-color auth-button-label on-auth-success on-auth-fail
auth-button-icon-left size blur? container-style]
auth-button-icon-left size blur? container-style disabled?]
:or {container-style {:flex 1}}}]
(let [theme (quo.theme/use-theme-value)
auth-method (rf/sub [:auth-method])
@@ -31,4 +31,5 @@
:customization-color customization-color
:on-complete on-complete
:track-icon (if biometric-auth? :i/face-id :password)
:track-text track-text}]))
:track-text track-text
:disabled? disabled?}]))
@@ -75,20 +75,26 @@
[{:keys [db]} contacts]
{:db (assoc db :contacts/contacts (into {} (map #(vector (:public-key %) %) contacts)))})
(rf/defn send-contact-request
{:events [:contact.ui/send-contact-request]}
[{:keys [db]} id]
(defn send-contact-request
[{:keys [db]} [id message]]
(when (not= id (get-in db [:profile/profile :public-key]))
{: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 %])}]}))
{: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)
(rf/defn remove-contact
"Remove a contact from current account's contact list"
@@ -0,0 +1,41 @@
(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]))))))
@@ -26,15 +26,13 @@
[message/message message context (atom false)])
(defn empty-pinned-messages-state
[{:keys [theme community?]}]
[{:keys [theme]}]
[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 (if community?
:t/no-pinned-messages-community-desc
:t/no-pinned-messages-desc))}]])
:description (i18n/label :t/no-pinned-messages-desc)}]])
(defn f-pinned-messages
[{:keys [theme chat-id]}]
@@ -77,8 +75,7 @@
:key-fn list-key-fn
:separator [quo/separator {:style {:margin-vertical 8}}]}]
[empty-pinned-messages-state
{:community? (boolean community)
:theme theme}])]))
{:theme theme}])]))
(defn- internal-pinned-messages
[params]
@@ -1,6 +1,7 @@
(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]
@@ -29,27 +30,30 @@
#(rf/dispatch [:on-camera-roll-get-photos (:edges %) (:page_info %) end-cursor])))})))
(defn- resize-photo
[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" %))))))
[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}))
(rf/reg-fx :effects.camera-roll/image-selected
(fn [[image chat-id]]
(resize-photo (:uri image) #(rf/dispatch [:photo-selector/image-selected chat-id image %]))))
(-> (resize-photo (:uri image))
(p/then #(rf/dispatch
[:photo-selector/image-selected chat-id image %]))
(p/catch #(log/error "could not resize image" %)))))
(defn- get-albums
[callback]
@@ -5,81 +5,92 @@
[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])
{: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)}]]]))
(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}]]]))))
@@ -1,3 +0,0 @@
(ns status-im.contexts.communities.actions.addresses-for-permissions.style)
(def container {:flex 1})
@@ -1,11 +1,8 @@
(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]))
@@ -20,8 +17,8 @@
nil))
(defn- balances->components-props
[balances]
(for [{:keys [amount decimals type name] :as balance} balances]
[balances images-by-symbol]
(for [{:keys [amount decimals type name] sym :symbol :as balance} balances]
(cond-> balance
true
(assoc :type
@@ -32,22 +29,24 @@
(= type constants/community-token-type-erc721)
(assoc :collectible-name name
:collectible-img-src (resources/get-mock-image :collectible))
:collectible-img-src (images-by-symbol sym))
(= type constants/community-token-type-erc20)
(assoc :amount (str (money/token->unit amount decimals))
:token (:symbol balance)))))
(assoc :amount (str (money/token->unit amount decimals))
:token (:symbol balance)
:token-img-src (images-by-symbol sym)))))
(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])]
(let [balances (rf/sub [:communities/permissioned-balances-by-address community-id address])
images-by-symbol (rf/sub [:communities/token-images-by-symbol community-id])]
[quo/account-permissions
{:account {:name name
:address address
:emoji emoji
:customization-color color}
:token-details (balances->components-props balances)
:token-details (balances->components-props balances images-by-symbol)
:checked? (contains? selected-addresses address)
:disabled? share-all-addresses?
:on-change #(rf/dispatch [:communities/toggle-selected-permission-address
@@ -56,8 +55,15 @@
:customization-color community-color}]))
(defn view
[{:keys [scroll-enabled? on-scroll]}]
(let [{id :community-id} (rf/sub [:get-screen-params])]
[]
(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]))]
(rf/dispatch [:communities/get-permissioned-balances id])
(fn []
(let [{:keys [name color images]} (rf/sub [:communities/community id])
@@ -67,7 +73,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)
@@ -79,26 +85,24 @@
: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}]
@@ -110,25 +114,18 @@
(empty? selected-addresses)
(not highest-permission-role)
(not unsaved-address-changes?))
:on-press (fn []
(rf/dispatch
[:communities/update-previous-permission-addresses
id])
(rf/dispatch [:navigate-back]))}
:on-press update-previous-addresses}
:button-two-label (i18n/label :t/cancel)
:button-two-props {:type :grey
:on-press (fn []
(rf/dispatch
[:communities/reset-selected-permission-addresses id])
(rf/dispatch [:navigate-back]))}
:on-press reset-selected-addresses}
: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)
(not highest-permission-role) (i18n/label
:t/addresses-dont-contain-tokens-needed)
:else nil)}]]))))
(empty? selected-addresses)
(i18n/label :t/no-addresses-selected)
(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.core :as rn]
[react-native.gesture :as gesture]
[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 [:navigate-back]))
(rf/dispatch [:hide-bottom-sheet]))
: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}]
[rn/flat-list
[gesture/flat-list
{:data selected-accounts
:render-fn render-item
:render-data [airdrop-address id]
@@ -15,3 +15,12 @@
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
:padding-horizontal 20
:margin-top margin-top}))
(def status-tag-wrapper
{:flex-direction :row
:padding-top 12
:padding-right 12})
(def header-top-wrapper
{:flex-direction :row
:justify-content :space-between})
@@ -4,14 +4,16 @@
[quo.theme]
[react-native.core :as rn]
[status-im.common.scalable-avatar.view :as avatar]
[status-im.constants :as constants]
[status-im.contexts.profile.contact.header.style :as style]
[status-im.contexts.profile.utils :as profile.utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[{:keys [scroll-y]}]
(let [{:keys [public-key customization-color
emoji-hash bio]
emoji-hash bio contact-request-state]
:as profile} (rf/sub [:contacts/current-contact])
customization-color (or customization-color :blue)
full-name (profile.utils/displayed-name profile)
@@ -19,14 +21,21 @@
online? (rf/sub [:visibility-status-updates/online? public-key])
theme (quo.theme/use-theme-value)]
[rn/view {:style style/header-container}
[rn/view {:style style/avatar-wrapper}
[avatar/view
{:scroll-y scroll-y
:full-name full-name
:online? online?
:profile-picture profile-picture
:border-color (colors/theme-colors colors/white colors/neutral-95 theme)
:customization-color customization-color}]]
[rn/view {:style style/header-top-wrapper}
[rn/view {:style style/avatar-wrapper}
[avatar/view
{:scroll-y scroll-y
:full-name full-name
:online? online?
:profile-picture profile-picture
:border-color (colors/theme-colors colors/white colors/neutral-95 theme)
:customization-color customization-color}]]
(when (= contact-request-state constants/contact-request-state-sent)
[rn/view {:style style/status-tag-wrapper}
[quo/status-tag
{:label (i18n/label :t/contact-profile-request-pending)
:status {:type :pending}
:size :large}]])]
[quo/page-top
{:title full-name
:description :text
@@ -1,6 +1,7 @@
(ns status-im.contexts.profile.settings.events
(:require [clojure.string :as string]
[legacy.status-im.bottom-sheet.events :as bottom-sheet.events]
[re-frame.core :as re-frame]
[status-im.constants :as constants]
status-im.contexts.profile.settings.effects
[taoensso.timbre :as log]
@@ -91,6 +92,16 @@
(boolean private?)
{})))
(re-frame/reg-event-fx :profile.settings/toggle-peer-syncing
(fn [{:keys [db]}]
(let [value (get-in db [:profile/profile :peer-syncing-enabled?])
new-value (not value)]
{:db (assoc-in db [:profile/profile :peer-syncing-enabled?] new-value)
:fx [[:json-rpc/call
[{:method "wakuext_togglePeerSyncing"
:params [{:enabled new-value}]
:on-error #(log/error "failed to toggle peer syncing" new-value %)}]]]})))
(rf/defn change-profile-pictures-show-to
{:events [:profile.settings/change-profile-pictures-show-to]}
[cofx id]
@@ -7,6 +7,7 @@
status-im.contexts.shell.jump-to.effects
[status-im.contexts.shell.jump-to.utils :as shell.utils]
[status-im.navigation.state :as navigation.state]
[status-im.navigation.utils :as navigation.utils]
[utils.re-frame :as rf]))
;;;; Events
@@ -149,10 +150,12 @@
(not hidden-screen?)
(:current-chat-id db))
(conj [:chat/close]))})
{:db (-> db
(assoc :view-id go-to-view-id)
(dissoc :modal-view-ids))
:navigate-to go-to-view-id}))
(let [modal-view-ids (navigation.utils/remove-current-modal-stack (:modal-view-ids db))]
{:navigate-to go-to-view-id
:db (cond-> db
true (assoc :view-id go-to-view-id)
(seq modal-view-ids) (assoc :modal-view-ids modal-view-ids)
(not (seq modal-view-ids)) (dissoc :modal-view-ids))})))
(rf/defn shell-navigate-back
{:events [:shell/navigate-back]}
@@ -176,8 +179,11 @@
shell.constants/close-screen-with-slide-to-right-animation))}
(when (and current-chat-id community-id)
{:dispatch [:shell/add-switcher-card shell.constants/community-screen community-id]}))
{:navigate-back nil
:db (dissoc db :modal-view-ids)})))
(let [modal-view-ids (navigation.utils/remove-current-modal-stack (:modal-view-ids db))]
{:navigate-back nil
:db (if (seq modal-view-ids)
(assoc db :modal-view-ids modal-view-ids)
(dissoc db :modal-view-ids))}))))
(rf/defn floating-screen-opened
{:events [:shell/floating-screen-opened]}
@@ -15,8 +15,8 @@
(defn navigate-back-handler
[]
(when (and (not @navigation.state/curr-modal)
(seq (utils/open-floating-screens)))
(when (or @navigation.state/curr-modal
(seq (utils/open-floating-screens)))
(rf/dispatch [:navigate-back])
true))
@@ -7,8 +7,8 @@
[reagent.core :as reagent]
[status-im.contexts.shell.share.style :as style]
[status-im.contexts.shell.share.wallet.style :as wallet-style]
[status-im.contexts.wallet.common.sheets.network-preferences.view :as network-preferences]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
[utils.i18n :as i18n]
[utils.image-server :as image-server]
[utils.re-frame :as rf]))
@@ -1,9 +1,12 @@
(ns status-im.contexts.syncing.setup-syncing.style
(:require
[quo.foundations.colors :as colors]))
[quo.foundations.colors :as colors]
[react-native.safe-area :as safe-area]))
(def container-main
(defn container-main
[]
{:background-color colors/neutral-95
:padding-top (safe-area/get-top)
:flex 1})
(def page-container
@@ -57,7 +57,7 @@
(rf/dispatch [:syncing/get-connection-string entered-password
set-code]))]
(fn []
[rn/view {:style style/container-main}
[rn/view {:style (style/container-main)}
[:f> f-use-interval clock cleanup-clock @delay-ms]
[rn/scroll-view {}
[quo/page-nav
@@ -38,7 +38,7 @@
:type :primary
:customization-color profile-color
:icon-only? true
:on-press #(rf/dispatch [:navigate-to :settings-setup-syncing])}
:on-press #(rf/dispatch [:open-modal :settings-setup-syncing])}
:i/add]]
[device/view (merge user-device {:this-device? true})]
(when (seq paired-devices)
@@ -1,8 +1,8 @@
(ns status-im.contexts.wallet.common.account-switcher.view
(:require [quo.core :as quo]
[status-im.contexts.wallet.common.sheets.account-options.view :as account-options]
[status-im.contexts.wallet.common.sheets.network-filter.view :as network-filter]
[status-im.contexts.wallet.common.sheets.select-account.view :as select-account]
[status-im.contexts.wallet.sheets.account-options.view :as account-options]
[status-im.contexts.wallet.sheets.network-filter.view :as network-filter]
[status-im.contexts.wallet.sheets.select-account.view :as select-account]
[status-im.feature-flags :as ff]
[utils.re-frame :as rf]))
@@ -1,4 +0,0 @@
(ns status-im.contexts.wallet.common.sheets.select-account.style)
(def list-container
{:margin-horizontal 8})
@@ -10,10 +10,10 @@
[status-im.common.emoji-picker.utils :as emoji-picker.utils]
[status-im.common.standard-authentication.core :as standard-auth]
[status-im.constants :as constants]
[status-im.contexts.wallet.common.sheets.account-origin.view :as account-origin]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.create-account.style :as style]
[status-im.contexts.wallet.create-account.utils :as create-account.utils]
[status-im.contexts.wallet.sheets.account-origin.view :as account-origin]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.responsiveness :refer [iphone-11-Pro-20-pixel-from-width]]
@@ -148,9 +148,7 @@
:path @derivation-path
:account-name @account-name}])))
:auth-button-label (i18n/label :t/confirm)
;; TODO (@rende11) Add this property when sliding button issue will fixed
;; https://github.com/status-im/status-mobile/pull/18683#issuecomment-1941564785
;; :disabled? (empty? @account-name)
:disabled? (empty? @account-name)
:container-style (style/slide-button-container bottom)}]]))))
(defn- view-internal
@@ -5,10 +5,10 @@
[reagent.core :as reagent]
[status-im.contexts.wallet.common.screen-base.create-or-edit-account.view
:as create-or-edit-account]
[status-im.contexts.wallet.common.sheets.network-preferences.view
:as network-preferences]
[status-im.contexts.wallet.common.sheets.remove-account.view :as remove-account]
[status-im.contexts.wallet.edit-account.style :as style]
[status-im.contexts.wallet.sheets.network-preferences.view
:as network-preferences]
[status-im.contexts.wallet.sheets.remove-account.view :as remove-account]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
+1 -1
View File
@@ -4,9 +4,9 @@
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.common.home.top-nav.view :as common.top-nav]
[status-im.contexts.wallet.common.sheets.network-filter.view :as network-filter]
[status-im.contexts.wallet.home.style :as style]
[status-im.contexts.wallet.home.tabs.view :as tabs]
[status-im.contexts.wallet.sheets.network-filter.view :as network-filter]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -45,20 +45,13 @@
(update-in [:wallet :ui :send] dissoc :route)
(update-in [:wallet :ui :send] dissoc :loading-suggested-routes?))}))
(rf/reg-event-fx :wallet/select-send-account-address
(fn [{:keys [db]} [{:keys [address stack-id]}]]
{:db (-> db
(assoc-in [:wallet :ui :send :send-account-address] address)
(update-in [:wallet :ui :send] dissoc :to-address))
:fx [[:dispatch [:navigate-to-within-stack [:wallet-select-asset stack-id]]]]}))
(rf/reg-event-fx :wallet/clean-send-address
(fn [{:keys [db]}]
{:db (update-in db [:wallet :ui :send] dissoc :recipient :to-address)}))
(rf/reg-event-fx
:wallet/select-send-address
(fn [{:keys [db]} [{:keys [address token recipient stack-id]}]]
(fn [{:keys [db]} [{:keys [address token? recipient stack-id]}]]
(let [[prefix to-address] (utils/split-prefix-and-address address)
test-net? (get-in db [:profile/profile :test-networks-enabled?])
goerli-enabled? (get-in db [:profile/profile :is-goerli-enabled?])
@@ -73,7 +66,7 @@
(assoc-in [:wallet :ui :send :selected-networks] selected-networks))
:fx [[:dispatch
[:navigate-to-within-stack
(if token
(if token?
[:wallet-send-input-amount stack-id]
[:wallet-select-asset stack-id])]]]})))
@@ -14,6 +14,7 @@
{:account-props (assoc account :customization-color color)
:on-press #(rf/dispatch [:wallet/select-send-address
{:address address
:token? false
:recipient account
:stack-id :wallet-select-address}])}])
@@ -23,47 +23,52 @@
(defn- address-input
[input-value input-focused?]
(fn []
(let [current-screen-id (rf/sub [:navigation/current-screen-id])
scanned-address (rf/sub [:wallet/scanned-address])
send-address (rf/sub [:wallet/wallet-send-to-address])
recipient (rf/sub [:wallet/wallet-send-recipient])
recipient-plain-address? (= send-address recipient)
valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])
chain-id (rf/sub [:chain-id])
contacts (rf/sub [:contacts/active])]
[quo/address-input
{:on-focus #(reset! input-focused? true)
:on-blur #(reset! input-focused? false)
:on-scan (fn []
(rn/dismiss-keyboard!)
(rf/dispatch [:wallet/clean-scanned-address])
(rf/dispatch [:open-modal :scan-address]))
:ens-regex constants/regx-ens
:scanned-value (or (when recipient-plain-address? send-address) scanned-address)
:address-regex constants/regx-multichain-address
:on-detect-address #(when (or (= current-screen-id :wallet-select-address)
(= current-screen-id :scan-address))
; ^ this check is to prevent effect being triggered when screen is
; loaded but not being shown to the user (deep in the navigation
; stack) and avoid undesired behaviors
(debounce/debounce-and-dispatch
[:wallet/validate-address %]
300))
:on-detect-ens (fn [text cb]
(when (or (= current-screen-id :wallet-select-address)
(= current-screen-id :scan-address))
; ^ this check is to prevent effect being triggered when screen
; is loaded but not being shown to the user (deep in the
; navigation stack) and avoid undesired behaviors
(debounce/debounce-and-dispatch
[:wallet/find-ens text contacts chain-id cb]
300)))
:on-change-text (fn [text]
(when (empty? text)
(rf/dispatch [:wallet/clean-local-suggestions]))
(reset! input-value text))
:valid-ens-or-address? valid-ens-or-address?}])))
(let [set-value-fn (atom nil)]
(fn []
(let [current-screen-id (rf/sub [:navigation/current-screen-id])
scanned-address (rf/sub [:wallet/scanned-address])
send-address (rf/sub [:wallet/wallet-send-to-address])
recipient (rf/sub [:wallet/wallet-send-recipient])
recipient-plain-address? (= send-address recipient)
valid-ens-or-address? (rf/sub [:wallet/valid-ens-or-address?])
chain-id (rf/sub [:chain-id])
contacts (rf/sub [:contacts/active])]
(when (and @set-value-fn scanned-address)
(@set-value-fn scanned-address)
(reset! set-value-fn nil))
[quo/address-input
{:on-focus #(reset! input-focused? true)
:on-blur #(reset! input-focused? false)
:on-scan (fn [set-value]
(reset! set-value-fn set-value)
(rn/dismiss-keyboard!)
(rf/dispatch [:wallet/clean-scanned-address])
(rf/dispatch [:open-modal :scan-address]))
:ens-regex constants/regx-ens
:default-value (when recipient-plain-address? send-address)
:address-regex constants/regx-multichain-address
:on-detect-address #(when (or (= current-screen-id :wallet-select-address)
(= current-screen-id :scan-address))
; ^ this check is to prevent effect being triggered when screen
; is loaded but not being shown to the user (deep in the
; navigation stack) and avoid undesired behaviors
(debounce/debounce-and-dispatch
[:wallet/validate-address %]
300))
:on-detect-ens (fn [text cb]
(when (or (= current-screen-id :wallet-select-address)
(= current-screen-id :scan-address))
; ^ this check is to prevent effect being triggered when screen
; is loaded but not being shown to the user (deep in the
; navigation stack) and avoid undesired behaviors
(debounce/debounce-and-dispatch
[:wallet/find-ens text contacts chain-id cb]
300)))
:on-change-text (fn [text]
(when (empty? text)
(rf/dispatch [:wallet/clean-local-suggestions]))
(reset! input-value text))
:valid-ens-or-address? valid-ens-or-address?}]))))
(defn- ens-linked-address
[{:keys [address networks theme]}]
@@ -93,6 +98,7 @@
(when-not ens
(rf/dispatch [:wallet/select-send-address
{:address address
:token? false
:recipient local-suggestion
:stack-id :wallet-select-address}]))))
:active-state? false}]
@@ -156,7 +162,7 @@
:disabled? (not valid-ens-or-address?)
:on-press #(rf/dispatch [:wallet/select-send-address
{:address @input-value
:token token
:token? (some? token)
:stack-id
:wallet-select-address}])
:customization-color color}
@@ -6,9 +6,9 @@
[react-native.safe-area :as safe-area]
[react-native.share :as share]
[reagent.core :as reagent]
[status-im.contexts.wallet.common.sheets.network-preferences.view :as network-preferences]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.share-address.style :as style]
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
[utils.i18n :as i18n]
[utils.image-server :as image-server]
[utils.re-frame :as rf]))
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.common.sheets.account-options.style)
(ns status-im.contexts.wallet.sheets.account-options.style)
(def drawer-section-label
{:padding-horizontal 20
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.common.sheets.account-options.view
(ns status-im.contexts.wallet.sheets.account-options.view
(:require [oops.core :as oops]
[quo.core :as quo]
[quo.foundations.colors :as colors]
@@ -9,9 +9,9 @@
[react-native.gesture :as gesture]
[react-native.platform :as platform]
[reagent.core :as reagent]
[status-im.contexts.wallet.common.sheets.account-options.style :as style]
[status-im.contexts.wallet.common.sheets.remove-account.view :as remove-account]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.sheets.account-options.style :as style]
[status-im.contexts.wallet.sheets.remove-account.view :as remove-account]
[status-im.feature-flags :as ff]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.common.sheets.account-origin.style
(ns status-im.contexts.wallet.sheets.account-origin.style
(:require [react-native.platform :as platform]))
(def header-container
@@ -1,10 +1,10 @@
(ns status-im.contexts.wallet.common.sheets.account-origin.view
(ns status-im.contexts.wallet.sheets.account-origin.view
(:require
[quo.core :as quo]
[quo.theme]
[react-native.core :as rn]
[status-im.constants :as const]
[status-im.contexts.wallet.common.sheets.account-origin.style :as style]
[status-im.contexts.wallet.sheets.account-origin.style :as style]
[utils.i18n :as i18n]))
(defn- header
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.common.sheets.network-filter.view
(ns status-im.contexts.wallet.sheets.network-filter.view
(:require
[quo.core :as quo]
[reagent.core :as reagent]
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.common.sheets.network-preferences.style
(ns status-im.contexts.wallet.sheets.network-preferences.style
(:require [quo.foundations.colors :as colors]))
(def blur
@@ -1,11 +1,11 @@
(ns status-im.contexts.wallet.common.sheets.network-preferences.view
(ns status-im.contexts.wallet.sheets.network-preferences.view
(:require [quo.core :as quo]
[quo.foundations.colors :as colors]
[quo.theme :as quo.theme]
[react-native.blur :as blur]
[reagent.core :as reagent]
[status-im.contexts.wallet.common.sheets.network-preferences.style :as style]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.sheets.network-preferences.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -1,4 +1,4 @@
(ns status-im.contexts.wallet.common.sheets.remove-account.style)
(ns status-im.contexts.wallet.sheets.remove-account.style)
(def desc-container
{:padding-horizontal 20
@@ -1,12 +1,12 @@
(ns status-im.contexts.wallet.common.sheets.remove-account.view
(ns status-im.contexts.wallet.sheets.remove-account.view
(:require
[quo.core :as quo]
[quo.theme]
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.wallet.common.sheets.remove-account.style :as style]
[status-im.contexts.wallet.common.utils :as utils]
[status-im.contexts.wallet.sheets.remove-account.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -0,0 +1,4 @@
(ns status-im.contexts.wallet.sheets.select-account.style)
(def list-container
{:margin-horizontal 8})
@@ -1,8 +1,8 @@
(ns status-im.contexts.wallet.common.sheets.select-account.view
(ns status-im.contexts.wallet.sheets.select-account.view
(:require [quo.core :as quo]
quo.theme
[react-native.gesture :as gesture]
[status-im.contexts.wallet.common.sheets.select-account.style :as style]
[status-im.contexts.wallet.sheets.select-account.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
+2 -1
View File
@@ -21,6 +21,7 @@
[status-im.contexts.profile.push-notifications.events :as notifications]
[status-im.contexts.shell.jump-to.state :as shell.state]
[status-im.contexts.shell.jump-to.utils :as shell.utils]
[status-im.navigation.core :as navigation]
status-im.contexts.wallet.signals
status-im.events
status-im.navigation.core
@@ -44,7 +45,7 @@
(defn init
[]
(navigation/init)
(native-module/init #(re-frame/dispatch [:signals/signal-received %]))
(when platform/android?
(native-module/set-soft-input-mode adjust-resize))
+76 -74
View File
@@ -11,86 +11,88 @@
[status-im.navigation.view :as views]
[utils.re-frame :as rf]))
(navigation/set-lazy-component-registrator
(fn [screen-key]
(let [screen (views/screen screen-key)]
(navigation/register-component screen-key
(fn [] (gesture/gesture-handler-root-hoc screen))
(fn [] screen)))))
(defn init
[]
(navigation/set-lazy-component-registrator
(fn [screen-key]
(let [screen (views/screen screen-key)]
(navigation/register-component screen-key
(fn [] (gesture/gesture-handler-root-hoc screen))
(fn [] screen)))))
;; APP LAUNCHED
(navigation/reg-app-launched-listener
(fn []
(navigation/set-default-options options/default-options)
(reset! state/curr-modal false)
(reset! state/dissmissing false)
(re-frame/dispatch [:bottom-sheet-hidden])
(if (= @state/root-id :multiaccounts-stack)
(re-frame/dispatch-sync [:set-multiaccount-root])
(when @state/root-id
(reset! theme/device-theme (rn/get-color-scheme))
(re-frame/dispatch [:init-root @state/root-id])
(re-frame/dispatch [:chat/check-last-chat])))
(rn/hide-splash-screen)))
(navigation/reg-component-did-appear-listener
(fn [view-id]
(when (get views/screens view-id)
;;NOTE when back from the background on Android, this event happens for all screens, but we
;;need only for active one
(when (and @state/curr-modal (= @state/curr-modal view-id))
(effects/set-view-id view-id))
(when-not @state/curr-modal
(effects/set-view-id view-id)
(reset! state/pushed-screen-id view-id)))))
;;;; Modal
(navigation/reg-button-pressed-listener
(fn [id]
(if (= "dismiss-modal" id)
(do
(when-let [event (get-in views/screens [(last @state/modals) :on-dissmiss])]
(rf/dispatch event))
(effects/dismiss-modal))
(when-let [handler (get-in views/screens [(keyword id) :right-handler])]
(handler)))))
(navigation/reg-modal-dismissed-listener
(fn []
(if (> (count @state/modals) 1)
(let [new-modals (butlast @state/modals)]
(reset! state/modals (vec new-modals))
(effects/set-view-id (last new-modals)))
(do
(reset! state/modals [])
(reset! state/curr-modal false)
(effects/set-view-id @state/pushed-screen-id)))
(let [component @state/dissmissing]
;; APP LAUNCHED
(navigation/reg-app-launched-listener
(fn []
(navigation/set-default-options options/default-options)
(reset! state/curr-modal false)
(reset! state/dissmissing false)
(when (keyword? component)
(effects/open-modal component)))))
(re-frame/dispatch [:bottom-sheet-hidden])
(if (= @state/root-id :multiaccounts-stack)
(re-frame/dispatch-sync [:set-multiaccount-root])
(when @state/root-id
(reset! theme/device-theme (rn/get-color-scheme))
(re-frame/dispatch [:init-root @state/root-id])
(re-frame/dispatch [:chat/check-last-chat])))
(rn/hide-splash-screen)))
;;;; Toast
(navigation/reg-component-did-appear-listener
(fn [view-id]
(when (get views/screens view-id)
;;NOTE when back from the background on Android, this event happens for all screens, but we
;;need only for active one
(when (and @state/curr-modal (= @state/curr-modal view-id))
(effects/set-view-id view-id))
(when-not @state/curr-modal
(effects/set-view-id view-id)
(reset! state/pushed-screen-id view-id)))))
(navigation/register-component
"toasts"
; `:flex 0` is the same as `flex: 0 0 auto` in CSS.
; We need this to override the HOC default layout which is
; flex 1. If we don't override this property, this HOC
; will catch all touches/gestures while the toast is shown,
; preventing the user doing any action in the app
#(gesture/gesture-handler-root-hoc views/toasts
#js {:flex 0})
(fn [] views/toasts))
;;;; Modal
;;;; Bottom sheet
(navigation/reg-button-pressed-listener
(fn [id]
(if (= "dismiss-modal" id)
(do
(when-let [event (get-in views/screens [(last @state/modals) :on-dissmiss])]
(rf/dispatch event))
(effects/dismiss-modal))
(when-let [handler (get-in views/screens [(keyword id) :right-handler])]
(handler)))))
(navigation/register-component
"bottom-sheet"
(fn [] (gesture/gesture-handler-root-hoc views/bottom-sheet))
(fn [] views/bottom-sheet))
(navigation/reg-modal-dismissed-listener
(fn []
(if (> (count @state/modals) 1)
(let [new-modals (butlast @state/modals)]
(reset! state/modals (vec new-modals))
(effects/set-view-id (last new-modals)))
(do
(reset! state/modals [])
(reset! state/curr-modal false)
(effects/set-view-id @state/pushed-screen-id)))
(let [component @state/dissmissing]
(reset! state/dissmissing false)
(when (keyword? component)
(effects/open-modal component)))))
;;;; Toast
(navigation/register-component
"toasts"
; `:flex 0` is the same as `flex: 0 0 auto` in CSS.
; We need this to override the HOC default layout which is
; flex 1. If we don't override this property, this HOC
; will catch all touches/gestures while the toast is shown,
; preventing the user doing any action in the app
#(gesture/gesture-handler-root-hoc views/toasts
#js {:flex 0})
(fn [] views/toasts))
;;;; Bottom sheet
(navigation/register-component
"bottom-sheet"
(fn [] (gesture/gesture-handler-root-hoc views/bottom-sheet))
(fn [] views/bottom-sheet)))
;; LEGACY (should be removed in status 2.0)
+2 -3
View File
@@ -129,12 +129,11 @@
(defn open-modal
[component]
(let [{:keys [options name]} (get views/screens component)
sheet? (:sheet? options)]
(let [{:keys [options]} (get views/screens component)
sheet? (:sheet? options)]
(if @state/dissmissing
(reset! state/dissmissing component)
(do
(set-view-id name) ; TODO https://github.com/status-im/status-mobile/issues/18811
(reset! state/curr-modal true)
(swap! state/modals conj component)
(navigation/show-modal
+13 -29
View File
@@ -4,6 +4,7 @@
[status-im.contexts.shell.jump-to.events :as shell.events]
[status-im.contexts.shell.jump-to.state :as shell.state]
[status-im.contexts.shell.jump-to.utils :as shell.utils]
[status-im.navigation.utils :as navigation.utils]
[utils.re-frame :as rf]))
(defn- all-screens-params
@@ -24,23 +25,17 @@
:dispatch-n [[:hide-bottom-sheet]]}
(shell.events/shell-navigate-to go-to-view-id screen-params nil nil)))
(defn- add-view-to-modals
[modal-view-ids new-id]
(if (seq modal-view-ids)
(conj modal-view-ids new-id)
modal-view-ids))
(rf/defn navigate-to-within-stack
{:events [:navigate-to-within-stack]}
[{:keys [db]} comp-id]
{:db (update db :modal-view-ids add-view-to-modals (first comp-id))
{:db (update db :modal-view-ids navigation.utils/add-view-to-modal-stack (first comp-id))
:fx [[:navigate-to-within-stack comp-id]]})
(re-frame/reg-event-fx :open-modal
(fn [{:keys [db]} [component screen-params]]
{:db (-> db
(assoc :view-id component)
(assoc :modal-view-ids [component])
(update :modal-view-ids navigation.utils/add-stack-to-modal-stacks component)
(all-screens-params component screen-params))
:fx [[:dispatch [:hide-bottom-sheet]]
[:open-modal-fx component]]}))
@@ -48,7 +43,7 @@
(rf/defn dismiss-modal
{:events [:dismiss-modal]}
[{:keys [db]} comp-id]
{:db (dissoc db :modal-view-ids)
{:db (update db :modal-view-ids navigation.utils/remove-current-modal-stack)
:dismiss-modal comp-id})
(rf/defn navigate-back
@@ -56,30 +51,17 @@
[cofx]
(shell.events/shell-navigate-back cofx nil))
(defn- remove-last-view-to-modals
[modal-view-ids]
(if (seq modal-view-ids)
(pop modal-view-ids)
modal-view-ids))
(rf/defn navigate-back-within-stack
{:events [:navigate-back-within-stack]}
[{:keys [db]} comp-id]
{:db (update db :modal-view-ids remove-last-view-to-modals)
{:db (update db :modal-view-ids navigation.utils/remove-last-view-from-current-modal-stack)
:fx [[:navigate-back-within-stack comp-id]]})
(defn- remove-modal-views-until-comp-id
[modal-view-ids comp-id]
(let [comp-id-index (.indexOf (or modal-view-ids []) comp-id)
modal-view-ids (if (> comp-id-index -1)
(subvec modal-view-ids 0 (inc comp-id-index))
modal-view-ids)]
modal-view-ids))
(rf/defn navigate-back-to
{:events [:navigate-back-to]}
[{:keys [db]} comp-id]
(let [modal-view-ids (remove-modal-views-until-comp-id (:modal-view-ids db) comp-id)]
(let [modal-view-ids (navigation.utils/remove-views-from-modal-stack-until-comp-id (:modal-view-ids db)
comp-id)]
(assoc {:navigate-back-to comp-id}
:db
(if modal-view-ids
@@ -99,13 +81,15 @@
(rf/defn init-root
{:events [:init-root]}
[_ root-id]
{:set-root root-id})
[{:keys [db]} root-id]
{:set-root root-id
:db (dissoc db :modal-view-ids)})
(rf/defn set-stack-root
{:events [:set-stack-root]}
[_ stack root]
{:set-stack-root-fx [stack root]})
[{:keys [db]} stack root]
{:set-stack-root-fx [stack root]
:db (dissoc db :modal-view-ids)})
(rf/defn change-tab
{:events [:navigate-change-tab]}
+1 -12
View File
@@ -13,9 +13,6 @@
[status-im.contexts.chat.messenger.messages.view :as chat]
[status-im.contexts.chat.messenger.photo-selector.view :as photo-selector]
[status-im.contexts.communities.actions.accounts-selection.view :as communities.accounts-selection]
[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.request-to-join.view :as join-menu]
[status-im.contexts.communities.actions.share-community-channel.view :as share-community-channel]
[status-im.contexts.communities.discover.view :as communities.discover]
@@ -126,14 +123,6 @@
:options {:sheet? true}
:component communities.accounts-selection/view}
{:name :addresses-for-permissions
:options {:sheet? true}
:component addresses-for-permissions/view}
{:name :airdrop-addresses
:options {:sheet? true}
:component airdrop-addresses/view}
{:name :lightbox
:options options/lightbox
:component lightbox/lightbox}
@@ -174,7 +163,7 @@
:component settings-syncing/view}
{:name :settings-setup-syncing
:options (merge options/dark-screen {:insets {:top? true}})
:options options/transparent-screen-options
:component settings-setup-syncing/view}
;; Onboarding
+44
View File
@@ -0,0 +1,44 @@
(ns status-im.navigation.utils)
(defn add-view-to-modal-stack
[modal-view-ids new-id]
(if-let [current-stack (and (seq modal-view-ids) (last modal-view-ids))]
(let [updated-stack (conj current-stack new-id)
without-last (vec (butlast modal-view-ids))]
(conj without-last updated-stack))
modal-view-ids))
(defn remove-last-view-from-current-modal-stack
[modal-view-ids]
(if (empty? modal-view-ids)
modal-view-ids
(let [last-stack (last modal-view-ids)
updated-last-stack (vec (butlast last-stack))
without-last-stack (vec (butlast modal-view-ids))]
(if (empty? updated-last-stack)
without-last-stack
(conj without-last-stack updated-last-stack)))))
(defn add-stack-to-modal-stacks
[modal-view-ids first-view-id]
(if (seq modal-view-ids)
(conj modal-view-ids [first-view-id])
[[first-view-id]]))
(defn remove-current-modal-stack
[modal-view-ids]
(if (seq modal-view-ids)
(vec (butlast modal-view-ids))
[]))
(defn remove-views-from-modal-stack-until-comp-id
[modal-view-ids comp-id]
(let [found-index (first (keep-indexed (fn [idx stack]
(when (some #{comp-id} stack) idx))
modal-view-ids))]
(if found-index
(let [target-stack (nth modal-view-ids found-index)
comp-id-index (.lastIndexOf target-stack comp-id)
updated-stack (take (inc comp-id-index) target-stack)]
(assoc modal-view-ids found-index updated-stack))
modal-view-ids)))
+67
View File
@@ -0,0 +1,67 @@
(ns status-im.navigation.utils-test
(:require [cljs.test :refer [deftest is testing]]
[status-im.navigation.utils :as utils]))
(deftest test-add-view-to-modal-stack
(testing "Add view ID to an empty modal stack"
(is (= (utils/add-view-to-modal-stack [] 1)
[])))
(testing "Add view ID to a non-empty modal stack"
(is (= (utils/add-view-to-modal-stack [[1 2]] 3)
[[1 2 3]])))
(testing "Add view ID when multiple modal stacks exist"
(is (= (utils/add-view-to-modal-stack [[1 2] [3 4]] 5)
[[1 2] [3 4 5]]))))
(deftest test-remove-last-view-from-current-modal-stack
(testing "Remove last view ID from a single-element stack"
(is (= (utils/remove-last-view-from-current-modal-stack [[1]])
[])))
(testing "Remove last view ID from the current modal stack"
(is (= (utils/remove-last-view-from-current-modal-stack [[1 2 3] [4 5 6]])
[[1 2 3] [4 5]])))
(testing "Handle empty modal stacks"
(is (= (utils/remove-last-view-from-current-modal-stack [])
[])))
(testing "Ensure unchanged stack when nested stack is a single element"
(is (= (utils/remove-last-view-from-current-modal-stack [[1 2] [3]])
[[1 2]]))))
(deftest test-add-stack-to-modal-stacks
(testing "Add a new stack to an empty list of modal stacks"
(is (= (utils/add-stack-to-modal-stacks [] 1)
[[1]])))
(testing "Add a new stack to existing modal stacks"
(is (= (utils/add-stack-to-modal-stacks [[1 2]] 3)
[[1 2] [3]])))
(testing "Add a new stack when existing stacks are varied"
(is (= (utils/add-stack-to-modal-stacks [[1 2] [3 4]] 5)
[[1 2] [3 4] [5]]))))
(deftest test-remove-current-modal-stack
(testing "Remove the only modal stack"
(is (= (utils/remove-current-modal-stack [[1 2]])
[])))
(testing "Remove the last modal stack from multiple"
(is (= (utils/remove-current-modal-stack [[1 2] [3 4] [5 6]])
[[1 2] [3 4]])))
(testing "Handle removal when modal stacks are empty"
(is (= (utils/remove-current-modal-stack [])
[])))
(testing "Ensure unchanged when nested stacks have varied lengths"
(is (= (utils/remove-current-modal-stack [[1] [2 3] [4 5 6]])
[[1] [2 3]]))))
(deftest test-remove-views-from-modal-stack-until-comp-id
(testing "Remove views until comp-id, including multiple occurrences"
(is (= (utils/remove-views-from-modal-stack-until-comp-id [[1 2 3] [4 5 5 6]] 5)
[[1 2 3] [4 5 5]])))
(testing "comp-id at the beginning of a stack"
(is (= (utils/remove-views-from-modal-stack-until-comp-id [[1 2] [3 4] [5 6 7]] 5)
[[1 2] [3 4] [5]])))
(testing "comp-id not found, no removal"
(is (= (utils/remove-views-from-modal-stack-until-comp-id [[1 2 3] [4 5 6]] 7)
[[1 2 3] [4 5 6]])))
(testing "comp-id is the last element in a stack"
(is (= (utils/remove-views-from-modal-stack-until-comp-id [[1 2 3] [4 5 6] [7 8 9]] 9)
[[1 2 3] [4 5 6] [7 8 9]]))))
+10
View File
@@ -412,3 +412,13 @@
(re-frame/subscribe [:communities/airdrop-address community-id])])
(fn [[accounts airdrop-address]]
(first (filter #(= (:address %) airdrop-address) accounts))))
(re-frame/reg-sub
:communities/token-images-by-symbol
(fn [[_ community-id]]
[(re-frame/subscribe [:communities/community community-id])])
(fn [[{:keys [tokens-metadata]}] _]
(->> tokens-metadata
(map (fn [{sym :symbol image :image}]
{sym image}))
(into {}))))
+21
View File
@@ -505,3 +505,24 @@
:communities
{community-id {:color community-color}})
(is (match? community-color (rf/sub [sub-name community-id]))))))
(h/deftest-sub :communities/token-images-by-symbol
[sub-name]
(testing
"returns a map keyed by the images of tokens/collectibles
And has data-uri as it's values"
(swap! rf-db/app-db assoc-in
[:communities community-id :tokens-metadata]
[{:contract-addresses {:420 "0x1"}
:image "data:image/jpeg;base64,/9j/2wCEAAYEBQYFBAYGBQYH"
:tokenType 2
:symbol "DOGE"
:name "Doge Coin coll"}
{:contract-addresses {:420 "0x1"}
:image "data:image/jpeg;base64,/9j/2wCEAAYEBQYFBAYGBQYH"
:tokenType 2
:symbol "BTC"
:name "Bitcoin coll"}])
(is (match? {"DOGE" "data:image/jpeg;base64,/9j/2wCEAAYEBQYFBAYGBQYH"
"BTC" "data:image/jpeg;base64,/9j/2wCEAAYEBQYFBAYGBQYH"}
(rf/sub [sub-name community-id])))))
+4 -1
View File
@@ -7,4 +7,7 @@
:<- [:view-id]
:<- [:modal-view-ids]
(fn [[view-id modal-view-ids]]
(or (peek modal-view-ids) view-id)))
(or (some-> modal-view-ids
last
last)
view-id)))
+6
View File
@@ -111,6 +111,12 @@
(fn [profile]
(:is-goerli-enabled? profile)))
(re-frame/reg-sub
:profile/peer-syncing-enabled?
:<- [:profile/profile]
(fn [profile]
(:peer-syncing-enabled? profile)))
(re-frame/reg-sub
:multiaccount/contact
:<- [:profile/profile]
+166 -3
View File
@@ -1,16 +1,35 @@
(ns test-helpers.integration
(:require-macros [test-helpers.integration])
(:require
[cljs.test :refer [is]]
[cljs.test :refer [is] :as test]
legacy.status-im.events
[legacy.status-im.multiaccounts.logout.core :as logout]
legacy.status-im.subs.root
[legacy.status-im.utils.test :as legacy-test]
[native-module.core :as native-module]
[promesa.core :as p]
[re-frame.core :as rf]
[re-frame.interop :as rf.interop]
status-im.events
status-im.navigation.core
status-im.subs.root
[taoensso.timbre :as log]
[tests.integration-test.constants :as constants]))
[tests.integration-test.constants :as constants]
[utils.collection :as collection]))
(def default-re-frame-wait-for-timeout-ms
"Controls the maximum time allowed to wait for all events to be processed by
re-frame on every call to `wait-for`.
Take into consideration that some endpoints/signals may take significantly
more time to finish/arrive."
(* 10 1000))
(def default-integration-test-timeout-ms
"Use a high-enough value in milliseconds to timeout integration tests. Not too
small, which would cause sporadic failures, and not too high as to make you
sleepy."
(* 60 1000))
(defn initialize-app!
[]
@@ -59,4 +78,148 @@
(defn log-headline
[test-name]
(log/info (str "========= " (name test-name) " ==================")))
(log/info (str "==== " test-name " ====")))
(defn wait-for
"Returns a promise that resolves when all `event-ids` are processed by re-frame,
otherwise rejects after `timeout-ms`.
If an event ID that is expected in `event-ids` occurs in a different order,
the promise will be rejected."
([event-ids]
(wait-for event-ids default-re-frame-wait-for-timeout-ms))
([event-ids timeout-ms]
(let [waiting-ids (atom event-ids)]
(p/create
(fn [promise-resolve promise-reject]
(let [cb-id (gensym "post-event-callback")
timer-id (js/setTimeout (fn []
(rf/remove-post-event-callback cb-id)
(promise-reject (ex-info
"timed out waiting for all event-ids to run"
{:event-ids event-ids
:waiting-ids @waiting-ids
:timeout-ms timeout-ms}
::timeout)))
timeout-ms)]
(rf/add-post-event-callback
cb-id
(fn [[event-id & _]]
(when-let [idx (collection/first-index #(= % event-id) @waiting-ids)]
;; All `event-ids` should be processed in their original order.
(if (zero? idx)
(do
(swap! waiting-ids rest)
;; When there's nothing else to wait for, clean up resources.
(when (empty? @waiting-ids)
(js/clearTimeout timer-id)
(rf/remove-post-event-callback cb-id)
(promise-resolve)))
(do
(js/clearTimeout timer-id)
(rf/remove-post-event-callback cb-id)
(promise-reject (ex-info "event happened in unexpected order"
{:event-ids event-ids
:waiting-for @waiting-ids}
::out-of-order-event-id)))))))))))))
(defn setup-app
[]
(legacy-test/init!)
(if (app-initialized)
(p/resolved ::app-initialized)
(do
(rf/dispatch [:app-started])
(wait-for [:profile/get-profiles-overview-success]))))
(defn setup-account
[]
(if (messenger-started)
(p/resolved ::messenger-started)
(do
(create-multiaccount!)
(-> (wait-for [:messenger-started])
(.then #(assert-messenger-started))))))
(defn integration-test
"Runs `f` inside `cljs.test/async` macro in a restorable re-frame checkpoint.
`f` will be called with one argument, the `done` function exposed by the
`cljs.test/async` macro. Normally, you don't need to use `done`, but you can
call it if you want to early-terminate the current test, so that the test
runner can execute the next one.
Option `fail-fast?`, when truthy (defaults to true), will force the test
runner to terminate on any test failure. Setting it to false can be useful
during development when you want the rest of the test suite to run due to a
flaky test. Prefer to fail fast in the CI to save on time & resources.
When `fail-fast?` is falsey, re-frame's state is automatically restored after
a test failure, so that the next integration test can run from a pristine
state.
Option `timeout-ms` controls the total time allowed to run `f`. The value
should be high enough to account for some variability, otherwise the test may
fail more often.
"
([test-name f]
(integration-test test-name
{:fail-fast? true
:timeout-ms default-integration-test-timeout-ms}
f))
([test-name {:keys [fail-fast? timeout-ms]} f]
(test/async
done
(let [restore-fn (rf/make-restore-fn)]
(log-headline test-name)
(-> (p/do (f done))
(p/timeout timeout-ms)
(p/catch (fn [error]
(is (nil? error))
(when fail-fast?
(js/process.exit 1))))
(p/finally (fn []
(restore-fn)
(done))))))))
;;;; Fixtures
(defn fixture-session
"Fixture to set up the application and a logged account before the test runs.
Log out after the test is done.
Usage:
(use-fixtures :each (h/fixture-logged))"
[]
{:before (fn []
(test/async done
(p/do (setup-app)
(setup-account)
(done))))
:after (fn []
(test/async done
(p/do (logout)
(wait-for [::logout/logout-method])
(done))))})
(defn fixture-silence-reframe
"Fixture to disable most re-frame messages.
Avoid using this fixture for non-dev purposes because in the CI output it's
desirable to have more data to debug, not less.
Example messages disabled:
- Warning about subscriptions being used in non-reactive contexts.
- Debug message \"Handling re-frame event: XYZ\".
Usage:
(use-fixtures :once (h/fixture-silence-re-frame))
"
[]
{:before (fn []
(set! rf.interop/debug-enabled? false))
:after (fn []
(set! rf.interop/debug-enabled? true))})
+58 -75
View File
@@ -1,10 +1,9 @@
(ns tests.integration-test.chat-test
(:require
[cljs.test :refer [deftest is]]
[day8.re-frame.test :as rf-test]
[cljs.test :refer [deftest is use-fixtures]]
legacy.status-im.events
[legacy.status-im.multiaccounts.logout.core :as logout]
legacy.status-im.subs.root
[promesa.core :as p]
[re-frame.core :as rf]
[status-im.constants :as constants]
status-im.events
@@ -12,85 +11,69 @@
status-im.subs.root
[test-helpers.integration :as h]))
(use-fixtures :each (h/fixture-session))
(def chat-id
"0x0402905bed83f0bbf993cee8239012ccb1a8bc86907ead834c1e38476a0eda71414eed0e25f525f270592a2eebb01c9119a4ed6429ba114e51f5cb0a28dae1adfd")
(deftest one-to-one-chat-test
(h/log-headline :one-to-one-chat-test)
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
(rf/dispatch-sync [:chat.ui/start-chat chat-id]) ;; start a new chat
(rf-test/wait-for
[:chat/one-to-one-chat-created]
(rf/dispatch-sync [:chat/navigate-to-chat chat-id])
(is (= chat-id @(rf/subscribe [:chats/current-chat-id])))
(h/logout)
(rf-test/wait-for [::logout/logout-method]))))))
(h/integration-test ::one-to-one-chat
(fn []
(p/do
(rf/dispatch-sync [:chat.ui/start-chat chat-id])
(h/wait-for [:chat/one-to-one-chat-created])
(rf/dispatch-sync [:chat/navigate-to-chat chat-id])
(is (= chat-id @(rf/subscribe [:chats/current-chat-id])))))))
(deftest delete-chat-test
(h/log-headline :delete-chat-test)
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
(rf/dispatch-sync [:chat.ui/start-chat chat-id]) ;; start a new chat
(rf-test/wait-for
[:chat/one-to-one-chat-created]
(rf/dispatch-sync [:chat/navigate-to-chat chat-id])
(is (= chat-id @(rf/subscribe [:chats/current-chat-id])))
(is @(rf/subscribe [:chats/chat chat-id]))
(rf/dispatch-sync [:chat.ui/show-remove-confirmation chat-id])
(rf/dispatch-sync [:chat.ui/remove-chat chat-id])
(h/logout)
(rf-test/wait-for [::logout/logout-method]))))))
(h/integration-test ::delete-chat
(fn []
(p/do
(rf/dispatch-sync [:chat.ui/start-chat chat-id])
(h/wait-for [:chat/one-to-one-chat-created])
(rf/dispatch-sync [:chat/navigate-to-chat chat-id])
(is (= chat-id @(rf/subscribe [:chats/current-chat-id])))
(is @(rf/subscribe [:chats/chat chat-id]))
(rf/dispatch-sync [:chat.ui/show-remove-confirmation chat-id])
(rf/dispatch-sync [:chat.ui/remove-chat chat-id])))))
(deftest mute-chat-test
(h/log-headline :mute-chat-test)
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
(rf/dispatch-sync [:chat.ui/start-chat chat-id]) ;; start a new chat
(rf-test/wait-for
[:chat/one-to-one-chat-created]
(rf/dispatch-sync [:chat/navigate-to-chat chat-id])
(is (= chat-id @(rf/subscribe [:chats/current-chat-id])))
(is @(rf/subscribe [:chats/chat chat-id]))
(rf/dispatch-sync [:chat.ui/mute chat-id true constants/mute-till-unmuted])
(rf-test/wait-for
[:chat/mute-successfully]
(is @(rf/subscribe [:chats/muted chat-id]))
(rf/dispatch-sync [:chat.ui/mute chat-id false])
(rf-test/wait-for
[:chat/mute-successfully]
(is (not @(rf/subscribe [:chats/muted chat-id])))
(h/logout)
(rf-test/wait-for [::logout/logout-method]))))))))
(h/integration-test ::mute-chat
(fn []
(p/do
(rf/dispatch-sync [:chat.ui/start-chat chat-id])
(h/wait-for [:chat/one-to-one-chat-created])
(rf/dispatch-sync [:chat/navigate-to-chat chat-id])
(is (= chat-id @(rf/subscribe [:chats/current-chat-id])))
(is @(rf/subscribe [:chats/chat chat-id]))
(rf/dispatch-sync [:chat.ui/mute chat-id true constants/mute-till-unmuted])
(h/wait-for [:chat/mute-successfully])
(is @(rf/subscribe [:chats/muted chat-id]))
(rf/dispatch-sync [:chat.ui/mute chat-id false])
(h/wait-for [:chat/mute-successfully])
(is (not @(rf/subscribe [:chats/muted chat-id])))))))
(deftest add-contact-test
(h/log-headline :add-contact-test)
(let
[compressed-key "zQ3shMwgSMKHVznoowceZMxWde9HUnkQEVSGvvex8UFpFNErL"
public-key (str "0x0407e9dc435fe366cb0b4c4f35cbd925438c0f46fe0"
"ed2a86050325bc8856e26898c17e31dee2602b9429c91"
"ecf65a41d62ac1f2f0823c0710dcb536e79af2763c")
primary-name "zQ3...pFNErL"]
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
;; search for contact using compressed key
(rf/dispatch [:contacts/set-new-identity {:input compressed-key}])
(rf-test/wait-for
[:contacts/set-new-identity-success]
(let [new-identity @(rf/subscribe [:contacts/new-identity])]
(is (= public-key (:public-key new-identity)))
(is (= :valid (:state new-identity))))
;; click 'view profile' button
(rf/dispatch [:chat.ui/show-profile public-key])
(rf-test/wait-for
[:contacts/build-contact]
(rf-test/wait-for
[:contacts/build-contact-success]
(let [contact @(rf/subscribe [:contacts/current-contact])]
(is (= primary-name (:primary-name contact))))
(h/logout)
(rf-test/wait-for [::logout/logout-method])))))))))
(h/integration-test ::add-contact
(fn []
(let [compressed-key "zQ3shMwgSMKHVznoowceZMxWde9HUnkQEVSGvvex8UFpFNErL"
public-key (str "0x0407e9dc435fe366cb0b4c4f35cbd925438c0f46fe0"
"ed2a86050325bc8856e26898c17e31dee2602b9429c91"
"ecf65a41d62ac1f2f0823c0710dcb536e79af2763c")
primary-name "zQ3...pFNErL"]
(p/do
;; Search for contact using compressed key
(rf/dispatch [:contacts/set-new-identity {:input compressed-key}])
(h/wait-for [:contacts/set-new-identity-success])
(let [new-identity @(rf/subscribe [:contacts/new-identity])]
(is (= public-key (:public-key new-identity)))
(is (= :valid (:state new-identity))))
;; Click 'view profile' button
(rf/dispatch [:chat.ui/show-profile public-key])
(h/wait-for [:contacts/build-contact :contacts/build-contact-success])
(let [contact @(rf/subscribe [:contacts/current-contact])]
(is (= primary-name (:primary-name contact)))))))))
+18 -18
View File
@@ -1,11 +1,11 @@
(ns tests.integration-test.core-test
(:require
[cljs.test :refer [deftest]]
[day8.re-frame.test :as rf-test]
legacy.status-im.events
[legacy.status-im.multiaccounts.logout.core :as logout]
legacy.status-im.subs.root
[legacy.status-im.utils.test :as utils.test]
[promesa.core :as p]
[re-frame.core :as rf]
status-im.events
status-im.navigation.core
@@ -13,22 +13,22 @@
[test-helpers.integration :as h]))
(deftest initialize-app-test
(h/log-headline :initialize-app-test)
(rf-test/run-test-async
(utils.test/init!)
(rf/dispatch [:app-started])
(rf-test/wait-for
;; use initialize-view because it has the longest avg. time and
;; is dispatched by initialize-multiaccounts (last non-view event)
[:profile/get-profiles-overview-success]
(rf-test/wait-for
[:font/init-font-file-for-initials-avatar]
(h/assert-app-initialized)))))
(h/integration-test ::initialize-app
(fn []
(p/do
(utils.test/init!)
(rf/dispatch [:app-started])
;; Use initialize-view because it has the longest avg. time and is
;; dispatched by initialize-multiaccounts (last non-view event).
(h/wait-for [:profile/get-profiles-overview-success
:font/init-font-file-for-initials-avatar])
(h/assert-app-initialized)))))
(deftest create-account-test
(h/log-headline :create-account-test)
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
(h/logout)
(rf-test/wait-for [::logout/logout-method])))))
(h/integration-test ::create-account
(fn []
(p/do
(h/setup-app)
(h/setup-account)
(h/logout)
(h/wait-for [::logout/logout-method])))))
+38 -61
View File
@@ -1,75 +1,52 @@
(ns tests.integration-test.profile-test
(:require
[cljs.test :refer [deftest is]]
[day8.re-frame.test :as rf-test]
[legacy.status-im.multiaccounts.logout.core :as logout]
[cljs.test :refer [deftest is use-fixtures]]
[legacy.status-im.utils.test :as utils.test]
[promesa.core :as p]
[status-im.contexts.profile.utils :as profile.utils]
[test-helpers.integration :as h]
[utils.re-frame :as rf]))
(use-fixtures :each (h/fixture-session))
(deftest edit-profile-name-test
(h/log-headline :edit-profile-name-test)
(let [new-name "John Doe"]
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
(rf/dispatch [:profile/edit-name new-name])
(rf-test/wait-for
[:navigate-back]
(rf-test/wait-for
[:toasts/upsert]
(let [profile (rf/sub [:profile/profile])
display-name (profile.utils/displayed-name profile)]
(is (= new-name display-name)))
(h/logout)
(rf-test/wait-for [::logout/logout-method]))))))))
(h/integration-test ::edit-profile-name
(fn []
(let [new-name "John Doe"]
(p/do
(rf/dispatch [:profile/edit-name new-name])
(h/wait-for [:navigate-back :toasts/upsert])
(let [profile (rf/sub [:profile/profile])
display-name (profile.utils/displayed-name profile)]
(is (= new-name display-name))))))))
(deftest edit-profile-picture-test
(h/log-headline :edit-profile-picture-test)
(let [mock-image "resources/images/mock2/monkey.png"
absolute-path (.resolve utils.test/path mock-image)]
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
(rf/dispatch [:profile/edit-picture absolute-path 80 80])
(rf-test/wait-for
[:profile/update-local-picture]
(rf-test/wait-for
[:toasts/upsert]
(let [profile (rf/sub [:profile/profile])]
(is (not (nil? (:images profile)))))
(h/logout)
(rf-test/wait-for [::logout/logout-method]))))))))
(h/integration-test ::edit-profile-picture
(fn []
(let [mock-image "resources/images/mock2/monkey.png"
absolute-path (.resolve utils.test/path mock-image)]
(p/do
(rf/dispatch [:profile/edit-picture absolute-path 80 80])
(h/wait-for [:profile/update-local-picture :toasts/upsert])
(let [profile (rf/sub [:profile/profile])]
(is (not (nil? (:images profile))))))))))
(deftest delete-profile-picture-test
(h/log-headline :delete-profile-picture-test)
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
(rf/dispatch [:profile/delete-picture])
(rf-test/wait-for
[:profile/update-local-picture]
(rf-test/wait-for
[:toasts/upsert]
(let [profile (rf/sub [:profile/profile])]
(is (nil? (:image profile))))
(h/logout)
(rf-test/wait-for [::logout/logout-method])))))))
(h/integration-test ::delete-profile-picture
(fn []
(p/do
(rf/dispatch [:profile/delete-picture])
(h/wait-for [:profile/update-local-picture :toasts/upsert])
(let [profile (rf/sub [:profile/profile])]
(is (nil? (:image profile))))))))
(deftest edit-profile-bio-test
(h/log-headline :edit-profile-bio-test)
(let [new-bio "New bio text"]
(rf-test/run-test-async
(h/with-app-initialized
(h/with-account
(rf/dispatch [:profile/edit-bio new-bio])
(rf-test/wait-for
[:navigate-back]
(rf-test/wait-for
[:toasts/upsert]
(let [profile (rf/sub [:profile/profile])
bio (:bio profile)]
(is (= new-bio bio)))
(h/logout)
(rf-test/wait-for [::logout/logout-method]))))))))
(h/integration-test ::edit-profile-bio
(fn []
(let [new-bio "New bio text"]
(p/do
(rf/dispatch [:profile/edit-bio new-bio])
(h/wait-for [:navigate-back :toasts/upsert])
(let [profile (rf/sub [:profile/profile])
bio (:bio profile)]
(is (= new-bio bio))))))))
+4 -1
View File
@@ -3,6 +3,7 @@
(:require
[re-frame.core :as re-frame]
[re-frame.interceptor :as interceptor]
[re-frame.interop :as rf.interop]
[reagent.core :as reagent]
[taoensso.timbre :as log]
[utils.datetime :as datetime])
@@ -20,7 +21,9 @@
[context]
(when js/goog.DEBUG
(reset! handler-nesting-level 0))
(log/debug "Handling re-frame event: " (first (interceptor/get-coeffect context :event)))
(when rf.interop/debug-enabled?
(log/debug "Handling re-frame event: "
(first (interceptor/get-coeffect context :event))))
context)))
(defn- update-db
+2 -2
View File
@@ -2053,8 +2053,7 @@
"you-must-always-hold": "You must always hold:",
"shell-placeholder-title": "Your open tabs will be here",
"shell-placeholder-subtitle": "Jump between your communities, messages,\nwallet accounts and browser tabs",
"no-pinned-messages-desc": "This chat doesnt have any\npinned messages.",
"no-pinned-messages-community-desc": "Just keep pinning, just keep pinning\nWhat do we do? We pin, pin, pin",
"no-pinned-messages-desc": "Just keep pinning, just keep pinning\nWhat do we do? We pin, pin, pin",
"invite-friends-to-status": "Invite friends to Status",
"share-invite-link": "Share an invite link",
"pending-requests": "Pending requests",
@@ -2117,6 +2116,7 @@
"selected-count-from-max": "{{selected}}/{{max}}",
"online": "Online",
"contact-request-chat-pending": "Your contact request is pending",
"contact-profile-request-pending": "Contact request pending",
"contact-request-chat-add": "Add {{name}} as contact to send a message",
"join-request": "Join request",
"join-one-user": "Join {{user}}",