Compare commits

...
63 Commits
Author SHA1 Message Date
ibrahem 0f0ce0d7bd Fix close button not working 2022-11-25 22:06:02 +02:00
ibrahem bc51a59774 Hardcode height to fix modal going under keyboard 2022-11-25 22:03:48 +02:00
ibrahem 4639660943 clean 2022-11-21 15:19:05 +02:00
ibrahem b58e7d6fff Revert changes to quo 2022-11-21 15:18:28 +02:00
ibrahem 3b593bedac improvements 2022-11-20 20:55:05 +03:00
ibrkhalil 944cb6c822 Cleaning 2022-11-20 15:58:37 +02:00
ibrahem 8700886ae4 lint 2022-11-15 23:33:27 +03:00
ibrahem c5cc18e9e0 Match implementation to design 2022-11-15 23:27:30 +03:00
ibrahem 2b6f354fb6 Improvements 2022-11-15 23:27:29 +03:00
ibrahem 717a225fd4 New chat flow for private chats and group chats 2022-11-15 23:27:27 +03:00
frank 433f9185c8 Use WakuNodes in ClusterConfig for Waku V2 (#14283) 2022-11-16 00:27:19 +08:00
Andrea Maria Piana 04408af45c Fix logout & upgrade status-go 2022-11-15 15:17:59 +00:00
Omar Basem ea7548d54a Confirmation Dialog (#14348)
* feat: confirmation dialog
2022-11-15 17:34:38 +04:00
Andrea Maria Piana c7ac53fdd0 Add icons & mentions/unread counts to community list 2022-11-15 13:03:48 +00:00
Roman Volosovskyi 48f86ff862 [#14311] Fix icons in message actions bottom sheet 2022-11-15 13:29:12 +01:00
Parvesh Monu f408035f5e Improve shell animations (#14341) 2022-11-15 16:45:43 +05:30
Parvesh Monu 1228f4aa26 Add accessibility to components (#14359)
- chat name text component
- quoted message text component
2022-11-15 16:41:56 +05:30
Christoph Pader 2f4d8accae feat: implement selectors with blurred background 2022-11-15 10:44:17 +01:00
andrey b8bfb2df80 new structure fixes 2022-11-15 10:33:32 +01:00
andrey 4654402feb new structure fixes 2022-11-15 06:56:33 +01:00
Parvesh Monu e8c44632ab fix community channel back button (#14358) 2022-11-15 03:29:03 +05:30
flexsurfer c7d5e90882 introduce new project structure (first step) (#14356)
* introduce new project structure
2022-11-14 19:16:55 +01:00
Roman Volosovskyi 4353c4a40c [#14245] Fix read/unread notifications filter 2022-11-14 13:40:20 +01:00
Icaro Motta a77f662948 Document new guidelines (#14309) 2022-11-14 07:15:49 -03:00
Omar Basem 57526a45ad Bottom sheet missing actions (#14332)
* feat: bottom sheets
2022-11-11 17:02:39 +04:00
Omar Basem 8fc853373b Rename :main-icons2 to :i (#14335)
* chore: rename icons
2022-11-11 15:45:54 +04:00
Andrea Maria Piana 5e814b7a03 Add display name 2022-11-10 20:00:49 +00:00
Omar Basem 61fd5fd791 Chat user dp (#14314)
* feat: chat-user-dp
2022-11-10 18:26:57 +04:00
Andrea Maria Piana 466dfe56d7 Fix emoji reactions 2022-11-10 13:48:12 +00:00
Andrea Maria Piana 8aee25509e Restore bottom sheet for chats 2022-11-10 13:46:27 +00:00
flexsurfer 8168d224d3 quo2 core (#14319)
* quo2 core
2022-11-10 12:10:16 +01:00
Andrea Maria Piana aca296030c Show bottom sheet when recovering account 2022-11-10 09:11:58 +00:00
yqrashawn f5a61d9a8b chore: fix can't remove node 0 error breaking react-devtools (#14316) 2022-11-10 16:42:41 +08:00
flexsurfer 3c1c8a120d cleanup quo2 2, remove status-im usage (#14308) 2022-11-10 09:10:43 +01:00
yqrashawn 3925de58b1 chore: lint against re-frame dispatch/subscribe in quo components (#14282) 2022-11-10 10:22:42 +08:00
Richard Ramos 0f6022a731 chore: set gowaku build tags for status-go
Signed-off-by: Jakub Sokołowski <jakub@status.im>
2022-11-09 18:47:15 +01:00
John Ngei a1c1be8f8a updated communities home and discover screen (#14018) 2022-11-09 15:41:34 +03:00
Andrea Maria Piana 01eae4da9c upgrade react native to 0.63.5 2022-11-08 19:50:36 +00:00
Roman Volosovskyi 77d0084467 Attempt to fix too long prefix for notification types 2022-11-08 19:13:56 +01:00
flexsurfer 5907edccc8 cleanup quo2 (#14301)
* cleanup quo2
2022-11-08 18:30:17 +01:00
Churikova Tetiana add00a5609 e2e: configurable datacenter 2022-11-08 10:35:05 +01:00
Omar Basem f17f57cc5e Messages home items (#14256)
* feat: messages home items
2022-11-08 13:01:02 +04:00
frank 187d147dc7 fix #14236 Sometimes profile pictures don't load (#14257) 2022-11-07 16:58:29 +01:00
pavloburykh b378d88aaf e2e: deep_link tests 2022-11-04 16:54:13 +02:00
Ibrahem Khalil 3b69e5873e Add members key to the chat-preview flow to show count of members on chat preview (#14274) 2022-11-03 12:10:01 +03:00
Andrej Česen 5e5ed0a11e Add code-snippet component (#14275) 2022-11-03 10:55:33 +03:00
Ibrahem Khalil bca2258508 Format numbers helper (#14186)
format number to 100000 -> 100k/ 1000000000 -> 1b/ 1000000 -> 1m
2022-11-03 10:33:34 +03:00
flexsurfer 7b739dff45 New icons (icons2) not working in token-tag component #14277 (#14280) 2022-11-01 14:58:33 +01:00
du64 ab1dd7e794 Fix typo (replace backtick with apostrophe) (#14255) 2022-10-29 17:24:29 +02:00
Churikova Tetiana 0967582639 e2e: non-latin 2022-10-28 15:54:08 +02:00
Icaro Motta 91b237d3d3 Fix unbounded number of calls to fetch notifications (#14250) 2022-10-27 16:21:41 -03:00
Icaro Motta 69303cd7d1 Implement positive button state (#14252) 2022-10-27 16:03:18 -03:00
Andrea Maria Piana b774ecbcb4 Add chat actions in home screen
This commit adds the following chat actions on the home screen:

- Mute chat
- Delete chat
- View profile (one to ones only)
- Clear history

It adds also integration tests for muting and deleting a chat.

To accommodate multiple dividers in the bottom sheet, the interface has
been changed to accept a sequence of sequences, instead of a map.
2022-10-27 17:53:30 +01:00
Roman Volosovskyi b492ed2969 [#14230] Reset :current-chat-id on pressing back from chat screen 2022-10-27 15:01:10 +02:00
Mohamed Javid 6d557d735a Activity Center UI Fixes (#14244)
* [Fixes] Activity Center UI Issues

* [Chore] Lint Fixes
2022-10-27 20:20:03 +08:00
Roman Volosovskyi f29ed58445 [#14230] Load newly received messages on reopening chat (ISSUE 1) 2022-10-27 11:13:22 +02:00
Churikova Tetiana 1941591110 new ui e2e: reaction and text message in 1-1 2022-10-26 17:14:25 +02:00
Ibrahem Khalil a91e9dfb38 Fix message showing behind message composer (#14238) 2022-10-26 16:40:46 +02:00
Omar Basem c423aa7970 Unpin messages (#14204)
* feat: pinned messages new ui
2022-10-26 17:18:50 +04:00
Icaro Motta 910bafc5f4 Display contact verification requests and allow users to decline them (#14223) 2022-10-26 07:48:07 -03:00
Omar Basem 2ae57f7b21 Messages contact requests (#14221)
* feat: messages contact requests
2022-10-26 10:42:53 +04:00
Jamie Caprani 14a5edb24b fix: adjust selectors to designs (#14214) 2022-10-25 01:50:39 -07:00
Parvesh Monu 0ff6fb25f4 Shell & Bottom Tabs Migration (#14099)
* Shell & Bottom Tabs Migration

* Added accessibility ids for elements in the new UI
2022-10-24 18:35:06 +05:30
385 changed files with 11473 additions and 5414 deletions
+2 -1
View File
@@ -272,7 +272,7 @@ run-android: export TARGET := android
run-android: ##@run Build Android APK and start it on the device
npx react-native run-android --appIdSuffix debug
SIMULATOR=
SIMULATOR=iPhone 13
run-ios: export TARGET := ios
run-ios: ##@run Build iOS app and start it in a simulator/device
ifneq ("$(SIMULATOR)", "")
@@ -287,6 +287,7 @@ endif
lint: export TARGET := clojure
lint: ##@test Run code style checks
sh scripts/lint-re-frame-in-quo-components.sh && \
clj-kondo --config .clj-kondo/config.edn --cache false --lint src && \
TARGETS=$$(git diff --diff-filter=d --cached --name-only src && echo src) && \
clojure -Scp "$$CLASS_PATH" -m cljfmt.main check --indents indentation.edn $$TARGETS
+20 -12
View File
@@ -10,11 +10,11 @@ Join us in creating a browser, messenger, and gateway to a decentralized world.
## Why?
We believe in a medium of pure free trade, economies with fair, permission-less access and a world without intermediaries. We want to create policies that can exist between friends or scale globally, we want to communicate securely and be uninhibited by legacy systems.
We believe in a medium of pure free trade, economies with fair, permission-less access and a world without intermediaries. We want to create policies that can exist between friends or scale globally, we want to communicate securely and be uninhibited by legacy systems.
We want to take responsibility for our data, the way we conduct ourselves privately and promote this way of life to a mass audience.
We want deep insights into our own economies so we can make informed, data-driven decisions on how to make our lives better. The Ethereum blockchain, Smart Contracts, Swarm and Whisper provides us a path forward.
We want deep insights into our own economies so we can make informed, data-driven decisions on how to make our lives better. The Ethereum blockchain, Smart Contracts, Swarm and Whisper provides us a path forward.
If this interests you, **help us make Status a reality** - anyone can contribute and we need everyone at any skill level to participate.
@@ -22,29 +22,37 @@ If this interests you, **help us make Status a reality** - anyone can contribute
Go straight to the [docs](https://status.im/docs) or [join our chat](https://join.status.im/chat/public/status) and choose what interests you:
- **Developer**
Developers are the heart of software and to keep Status beating we need all the help we can get! If you're looking to code in ClojureScript or Golang then Status is the project for you! We use React Native and there is even some Java/Objective-C too!
Want to learn more about it? Start by reading our [Developer Introduction](https://status.im/developer_tools/) which guides you through the technology stack and start browsing [beginner issues](https://github.com/status-im/status-mobile/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good%20first%20issue%22%20). Then you can read how to [Build Status](https://status.im/technical/build_status/), which talks about managing project dependencies, coding guidelines and testing procedures.
- **Developer** Developers are the heart of software and to keep Status beating
we need all the help we can get! If you're looking to code in ClojureScript or
Golang then Status is the project for you! We use React Native and there is even
some Java/Objective-C too! Want to learn more about it? Start by reading our
[Developer Introduction](https://status.im/developer_tools/) which guides you
through the technology stack and start browsing [beginner
issues](https://github.com/status-im/status-mobile/issues?utf8=%E2%9C%93&q=is%3Aopen%20is%3Aissue%20label%3A%22good%20first%20issue%22%20).
Then you can read how to [Build
Status](https://status.im/technical/build_status/), which talks about managing
project dependencies, coding guidelines and testing procedures. The [doc/](doc/)
directory also has valuable information for contributors.
- **Community Management**
- **Community Management**
Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and long lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.im/about)
- **Specification / Documentation**
- **Specification / Documentation**
John Dewey once said "Education is not preparation for life; education is life *itself* ". Developers & Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, head over to our [docs](https://status.im/docs) and see how you can improve what we have.
- **Blog Writing**
- **Blog Writing**
Content is King, keeping our blog up to date and informing the community of news helps keep everyone on the same page. [Jump into our chat](https://join.status.im/chat/public/status) and discuss with the team how you can contribute!
- **Testers**
- **Testers**
It's bug hunting season! Status is currently under active development and there is sure to be a bunch of learning, [build status from scratch](https://status.im/technical/build_status/) or if an android user check out our [nightly builds](https://status.im/nightly). You can shake your phone to submit bug reports, or start browsing our [Github Issues](https://github.com/status-im/status-mobile/issues). Every bug you find brings Status closer to stable, usable software for everyone to enjoy!
- **Security**
- **Security**
Status is a visual interface to make permanent changes on the Blockchain, it handles crypto-tokens that have real value and allows 3rd party code execution. Security is paramount to its success. You are given permission to break Status as hard as you can, as long as you share your findings with the community!
- **Evangelism**
- **Evangelism**
Help us spread the word! Tell a friend *right now*, in fact tell **everyone** - yell from a mountain if you have to, every person counts! If you've got a great story to tell or have some interesting way you've spread the word about Status let us know about it in our [chat](https://join.status.im/chat/public/status)
## Status API
## Status API
View our [API Docs](https://status.im/developer_tools/status_web_api.html) and learn how to integrate your DApp into Status. You can read more about how to add your DApp to Status [here](https://status.im/developer_tools/add_your_dapp.html).
## Give me Binaries!
+1 -1
View File
@@ -62,7 +62,7 @@ pipeline {
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
-m \"not upgrade\" \
-m \"new_ui_critical\" \
-k \"${params.KEYWORD_EXPRESSION}\" \
--apk=${params.APK_NAME}
"""
+1 -1
View File
@@ -14,7 +14,7 @@ pipeline {
string(
name: 'TEST_MARKERS',
description: 'Marker expression for matching tests to run.',
defaultValue: 'critical',
defaultValue: 'new_ui_critical',
) */
string(
name: 'APK_NAME',
+5 -1
View File
@@ -1,5 +1,9 @@
# Codebase Structure and Guidelines
As of Nov/2022, we're starting to document and migrate the codebase to [new
guidelines](new-guidelines.md), which will supersede some of the guidelines in
this document.
## Starting the app
The app is bundled and run in a Nix environment. Information regarding how to run it locally can be found [here](https://status.im/technical/build_status/).
@@ -85,7 +89,7 @@ These guidelines make db.cljs namespaces the place to go when making changes to
- If issues - label 'TESTED-ISSUES' and comment from QA with bugs.
- After fix and/or discussion the process is repeated.
- If manual QA is not needed but all tests don't pass, you can ping @churik or @Serhy to confirm that failed E2E tests are not unrelated.
- If manual QA is not needed but all tests don't pass, you can ping @churik or @Serhy to confirm that failed E2E tests are not unrelated.
## Enabling debug logs
Calls to `log/debug` will not be printed to the console by default. It can be enabled under "Advanced settings" in the app:
+440
View File
@@ -0,0 +1,440 @@
# Guidelines
>The goal of this document is to help all contributors (core and external) to
>write code in _unison_ and help establish good practices that serve the Status
>Mobile contributors well.
We don't want to turn this document into an exhaustive list of rules to be
followed that nobody will read. As much as possible, we'll try to document only
what we consider important for Status Mobile. In other words, we don't want to
maintain a general Clojure convention/style guide, nor do we want to turn this
document into a long tutorial.
This is a **work in progress**, and not all conventions are properly implemented
in the codebase yet. The project structure is also going over major changes (as
of Nov/2022), and it'll take a considerable amount of time until we migrate the
existing code to the new structure.
If you find out anything is outdated or missing, please, share with us or even
better, create a pull-request! 🤸
## Style guide
We mostly follow the [Clojure Style
Guide](https://github.com/bbatsov/clojure-style-guide), so it's recommended to
get familiar with it.
As of Nov/2022, running `make lint` should fix the most basic formatting issues,
and we are in the process of integrating a tool to format non-trivial code
according to the Clojure Style Guide. This should greatly reduce noise in
pull-request reviews and it'll simplify the life of all contributors.
Pay special attention to:
- Align let bindings https://github.com/bbatsov/clojure-style-guide#bindings-alignment
- Align map keys https://github.com/bbatsov/clojure-style-guide#map-keys-alignment
## Dos and don'ts
### Component styles
Prefer to define styles in separate files named `style.cljs`, usually colocated
with the source file using it. For a real example, see
[src/status_im/ui2/screens/chat/messages/style.cljs](../src/status_im/ui2/screens/chat/messages/style.cljs).
```clojure
;; bad
(defn animated-checkbox-view [{:keys [size]}]
[animated/view
{:style {:width size
:height size
:border-radius 4
:justify-content :center
:align-items :center}}
[animated/view
(do-something)]])
;; good
(defn animated-checkbox-view [{:keys [size]}]
[animated/view
{:style (style/animated-checkbox-style size)}
[animated/view
(do-something)]])
```
### Using TODOs comments
_TODO_ comments are used extensively in the codebase, but prefer to use them
only when strictly necessary and when an issue is not enough to track the work
left to be done.
These are all good examples:
```clojure
;; TODO(@username): <message>
;; TODO(@username): <message>, <issue URL>
;; TODO(YYYY-MM-DD): <message>
;; TODO(@username,YYYY-MM-DD): <message>
```
### Subscription names and event names
Always register events and subscriptions using a meaningful namespace, but don't
namespace them with `::`. We understand it's a controversial decision because
there are both pros and cons to such practice.
Whenever appropriate, it's also recommended to use _fake_ namespaces to convey
more knowledge in the keyword about which bounded context (domain) it refers to.
You may also use dots to convey hierarchical structures.
```clojure
;; bad
;; Don't use real namespaced keywords.
(re-frame/reg-sub
::profile-pictures-visibility
:<- [:multiaccount]
(fn [multiaccount]
(:profile-pictures-visibility multiaccount)))
;; good
;; Uses a fake namespaced keyword.
(re-frame/reg-sub
:profile/pictures-visibility
:<- [:multiaccount]
(fn [multiaccount]
(:profile-pictures-visibility multiaccount)))
;; better
;; Uses a fake namespaced keyword with a parent namespace (multiaccount).
(re-frame/reg-sub
:multiaccount.profile/pictures-visibility
:<- [:multiaccount]
(fn [multiaccount]
(:profile-pictures-visibility multiaccount)))
```
### Declaring view components
Use the simple `defn` to declare components. Don't use `utils.views/defview` and
`utils.views/letsubs`.
```clojure
;; bad
(utils.views/defview browser []
(utils.views/letsubs [window-width [:dimensions/window-width]]
(do-something window-width)))
;; good
(defn browser []
(let [window-width (rf/sub [:dimensions/window-width])]
(do-something window-width)))
```
### Using re-frame subscriptions and dispatching events
Use the `utils.re-frame` namespace instead of `re-frame.core` to subscribe and
dispatch.
```clojure
;; bad
(ns my-namespace
(:require [re-frame.core :as rf]))
(let [username @(rf/subscribe [:username])]
[pressable/pressable {:on-press #(rf/dispatch [:do-something])}
[rn/view
(str "Hello " username)]])
;; good
(ns my-namespace
(:require [utils.re-frame :as rf]))
(let [username (rf/sub [:username])]
[pressable/pressable {:on-press #(rf/dispatch [:do-something])}
[rn/view
(str "Hello " username)]])
```
### Registering event handlers
Events must always be declared with the `utils.fx/defn` macro. Also, don't use
`re-frame.core/reg-event-db`.
```clojure
;; bad
(re-frame/reg-event-fx
:wakuv2.ui/save-all-confirmed
(fn [{:keys [db] :as cofx}]
...))
;; good
(fx/defn save-all
{:events [:wakuv2.ui/save-all-confirmed]}
[{:keys [db] :as cofx}]
...)
```
### Registering top-level re-frame subscriptions
Use `subs.root/reg-root-key-sub` to register top-level (root) subscriptions.
Additionally, register root subscriptions in the `subs.root` namespace.
```clojure
;; bad
(re-frame/reg-sub
:view-id
(fn [db]
(:view-id db)))
;; good
(reg-root-key-sub :view-id :view-id)
```
### Registering layer-3 subscriptions
The majority of the subscriptions should be defined as [layer-3
subscriptions](https://day8.github.io/re-frame/subscriptions/#the-four-layer)
due to performance constraints.
```clojure
;; bad
(re-frame/reg-sub
:ens/preferred-name
(fn [db]
(get-in db [:multiaccount :preferred-name])))
;; good
(re-frame/reg-sub
:ens/preferred-name
:<- [:multiaccount]
(fn [multiaccount]
(:preferred-name multiaccount)))
```
### Requiring quo2 components
Consume `quo2` components from `quo2.core`, unless the namespace is also inside
the `quo2/` directory.
```clojure
;; bad
(ns my-namespace
(:require [quo2.components.icon :as icon]))
(icon/icon :i/verified)
;; good
(ns my-namespace
(:require [quo2.core :as quo2]))
(quo2/icon :i/verified)
;; also good because both namespaces are inside quo2/
(ns quo2.components.tabs.account-selector
(:require [quo2.components.markdown.text :as text]))
```
### Require/import
Prefer `:as` instead of `:refer`. There are exceptions to this rule, e.g. the
test macros `deftest` and `is`, which are ubiquitous in the Clojure community.
```clojure
;; bad
(ns status-im.utils.datetime
(:require [cljs-time.coerce :refer [from-long]]))
;; good
(ns status-im.utils.datetime
(:require [cljs-time.coerce :as time.coerce]))
```
### Accessibility labels
Use keywords instead of strings. As a bonus, remember keywords are cached in
memory.
```clojure
;; bad
[text/text {:accessibility-label "profile-nickname"}
"Markov"]
;; good
[text/text {:accessibility-label :profile-nickname}
"Markov"]
```
### Icons
Use the appropriate keyword qualification/namespace and don't directly require
namespaces inside `quo2/components/`.
```clojure
;; bad
(require '[quo2.components.icon :as icons])
(icons/icon :main-icons2/verified)
;; good
(require '[quo2.core :as quo2])
(quo2/icon :i/verified)
```
### Translations
Prefer to use translation placeholders instead of creating multiple translation
keywords and concatenating them into a single string.
```clojure
;; bad
;; Assume the translation key is:
;; "biometric-auth-error": "Unable perform biometric authentication"
(str (i18n/label :t/biometric-auth-error) "(" error-code ")")
;; good
;; Assume the translation key is:
;; "biometric-auth-error": "Unable perform biometric authentication ({{code}})"
(i18n/label :t/biometric-auth-error {:code error-code})
```
## Project Structure
First, the bird's-eye view with some example ClojureScript files:
```
src
├── js/
├── mocks/
├── quo2
│ ├── components/
│ ├── foundations/
│ └── theme.cljs
├── react_native
│ ├── gesture.cljs
│ └── platform.cljs
├── status_im
│ ├── common
│ │ └── components
│ │ └── bottom_sheet.cljs
│ ├── contexts/
│ ├── setup/
│ └── subs/
└── utils.cljs
```
- `src/js`: Raw Javascript files, e.g. React Native Reanimated worklets.
- `src/mocks`: Plumbing configuration to be able to run tests.
- `src/quo2/`: The component library for Status Mobile.
- `src/react_native/`: Contains only low-level constructs to help React Native
work in tandem with Clojure(Script).
- `src/status_im/common/`: Directories named `common` can appear at any level of
the directory tree. Just like directories named `utils`, their directory
nesting level communicates their applicable limits.
- `src/status_im/common/components/`: Contains reusable components that are not
part of the design system (quo2).
- `src/status_im/contexts/`: Contains [bounded contexts](#glossary), like
`browser/`, `messaging/`, etc. As much as possible, _bounded contexts_ should
not directly require each other's namespaces.
- `src/status_im/setup/`: Contains namespaces that are mostly used to initialize
the application, configure test runners, etc. In general, such namespaces
should not be required from the outside.
- `src/status_im/subs/`: All subscriptions should live inside it.
Directories named `utils/` can appear at any level of the directory tree. The
directory nesting level precisely indicates its boundaries. For example, a
`contexts/user_settings/utils/datetime.cljs` file communicates that it should
only be used in the `user_settings` context.
### src/quo2
The `src/quo2/` directory holds all components for the new design system. As
much as possible, its sub-directories and component names should reflect the
same language used by designers.
Even though the directory lives alongside the rest of the codebase, we should
think of it as an external entity that abstracts away particular Status domain
knowledge.
Components inside `src/quo2/` should not rely on re-frame, i.e. they should not
dispatch events or use subscriptions.
Example structure:
```
src
└── quo2
├── components
│ └── dropdown
│ ├── style.cljs
│ ├── test.cljs
│ └── view.cljs
└── screens
└── dropdown
└── view.cljs
```
### Re-frame events
Event handlers should be defined in files named `events.cljs`, and they should
be _close_ to other _things_, like view files, components, etc.
For example:
```
src
└── contexts
└── browser
├── bookmarks/
├── options/
├── permissions/
├── events.cljs
├── events_test.cljs
├── style.cljs
└── view.cljs
```
### Test structure
[Unit tests](#glossary) should be created alongside their respective source
implementation. We prefer them colocated with the source and not like most
Clojure (JVM) codebases which mirror the sources in a top-level test directory.
Component tests should be created in a separate directory `__tests__`. Example:
```
├── models
│ ├── message.cljs
│ └── message_test.cljs
├── __tests__
│ └── input_bla_test.cljs
├── models.cljs
└── models_test.cljs
```
There's no hard rule on how integration test namespaces should be split, but
we're at least striving to define them under appropriate bounded contexts that
mirror the source code.
```
test
├── appium/
└── integration
├── browser/
├── communities/
├── messaging/
├── user_settings/
└── wallet
└── payment_test.cljs
```
## Glossary
**Unit test**: The smallest atomic unit that's meaningful to test. For example,
tests for utility functions and event handlers are considered unit tests in the
mobile codebase. They should be completely deterministic, _fast_, and they
should work flawlessly in the REPL.
**Bounded context**: A logical separation between different domains. It's an
important concept in the [Domain-Driven
Design](https://en.wikipedia.org/wiki/Domain-driven_design) literature. See
[Bounded Context, by Martin
Fowler](https://martinfowler.com/bliki/BoundedContext.html) for an introduction
to the topic.
+178 -178
View File
@@ -4,14 +4,14 @@ PODS:
- React
- CryptoSwift (1.5.1)
- DoubleConversion (1.1.6)
- FBLazyVector (0.63.4)
- FBReactNativeSpec (0.63.4):
- FBLazyVector (0.63.5)
- FBReactNativeSpec (0.63.5):
- Folly (= 2020.01.13.00)
- RCTRequired (= 0.63.4)
- RCTTypeSafety (= 0.63.4)
- React-Core (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- RCTRequired (= 0.63.5)
- RCTTypeSafety (= 0.63.5)
- React-Core (= 0.63.5)
- React-jsi (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- Folly (2020.01.13.00):
- boost-for-react-native
- DoubleConversion
@@ -40,172 +40,172 @@ PODS:
- RNPermissions
- Permission-Microphone (2.1.5):
- RNPermissions
- RCTRequired (0.63.4)
- RCTTypeSafety (0.63.4):
- FBLazyVector (= 0.63.4)
- RCTRequired (0.63.5)
- RCTTypeSafety (0.63.5):
- FBLazyVector (= 0.63.5)
- Folly (= 2020.01.13.00)
- RCTRequired (= 0.63.4)
- React-Core (= 0.63.4)
- React (0.63.4):
- React-Core (= 0.63.4)
- React-Core/DevSupport (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-RCTActionSheet (= 0.63.4)
- React-RCTAnimation (= 0.63.4)
- React-RCTBlob (= 0.63.4)
- React-RCTImage (= 0.63.4)
- React-RCTLinking (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- React-RCTSettings (= 0.63.4)
- React-RCTText (= 0.63.4)
- React-RCTVibration (= 0.63.4)
- React-callinvoker (0.63.4)
- React-Core (0.63.4):
- RCTRequired (= 0.63.5)
- React-Core (= 0.63.5)
- React (0.63.5):
- React-Core (= 0.63.5)
- React-Core/DevSupport (= 0.63.5)
- React-Core/RCTWebSocket (= 0.63.5)
- React-RCTActionSheet (= 0.63.5)
- React-RCTAnimation (= 0.63.5)
- React-RCTBlob (= 0.63.5)
- React-RCTImage (= 0.63.5)
- React-RCTLinking (= 0.63.5)
- React-RCTNetwork (= 0.63.5)
- React-RCTSettings (= 0.63.5)
- React-RCTText (= 0.63.5)
- React-RCTVibration (= 0.63.5)
- React-callinvoker (0.63.5)
- React-Core (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-Core/Default (= 0.63.5)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/CoreModulesHeaders (0.63.4):
- React-Core/CoreModulesHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/Default (0.63.4):
- React-Core/Default (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/DevSupport (0.63.4):
- React-Core/DevSupport (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-jsinspector (= 0.63.4)
- React-Core/Default (= 0.63.5)
- React-Core/RCTWebSocket (= 0.63.5)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- React-jsinspector (= 0.63.5)
- Yoga
- React-Core/RCTActionSheetHeaders (0.63.4):
- React-Core/RCTActionSheetHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTAnimationHeaders (0.63.4):
- React-Core/RCTAnimationHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTBlobHeaders (0.63.4):
- React-Core/RCTBlobHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTImageHeaders (0.63.4):
- React-Core/RCTImageHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTLinkingHeaders (0.63.4):
- React-Core/RCTLinkingHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTNetworkHeaders (0.63.4):
- React-Core/RCTNetworkHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTSettingsHeaders (0.63.4):
- React-Core/RCTSettingsHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTTextHeaders (0.63.4):
- React-Core/RCTTextHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTVibrationHeaders (0.63.4):
- React-Core/RCTVibrationHeaders (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-Core/RCTWebSocket (0.63.4):
- React-Core/RCTWebSocket (0.63.5):
- Folly (= 2020.01.13.00)
- glog
- React-Core/Default (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsiexecutor (= 0.63.4)
- React-Core/Default (= 0.63.5)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsiexecutor (= 0.63.5)
- Yoga
- React-CoreModules (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- React-CoreModules (0.63.5):
- FBReactNativeSpec (= 0.63.5)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/CoreModulesHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTImage (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-cxxreact (0.63.4):
- RCTTypeSafety (= 0.63.5)
- React-Core/CoreModulesHeaders (= 0.63.5)
- React-jsi (= 0.63.5)
- React-RCTImage (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- React-cxxreact (0.63.5):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-callinvoker (= 0.63.4)
- React-jsinspector (= 0.63.4)
- React-jsi (0.63.4):
- React-callinvoker (= 0.63.5)
- React-jsinspector (= 0.63.5)
- React-jsi (0.63.5):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-jsi/Default (= 0.63.4)
- React-jsi/Default (0.63.4):
- React-jsi/Default (= 0.63.5)
- React-jsi/Default (0.63.5):
- boost-for-react-native (= 1.63.0)
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-jsiexecutor (0.63.4):
- React-jsiexecutor (0.63.5):
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-jsinspector (0.63.4)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- React-jsinspector (0.63.5)
- react-native-background-timer (2.2.0):
- React
- react-native-blob-util (0.13.18):
@@ -243,66 +243,66 @@ PODS:
- React
- react-native-webview (11.16.0):
- React-Core
- React-RCTActionSheet (0.63.4):
- React-Core/RCTActionSheetHeaders (= 0.63.4)
- React-RCTAnimation (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- React-RCTActionSheet (0.63.5):
- React-Core/RCTActionSheetHeaders (= 0.63.5)
- React-RCTAnimation (0.63.5):
- FBReactNativeSpec (= 0.63.5)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTAnimationHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTBlob (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- RCTTypeSafety (= 0.63.5)
- React-Core/RCTAnimationHeaders (= 0.63.5)
- React-jsi (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- React-RCTBlob (0.63.5):
- FBReactNativeSpec (= 0.63.5)
- Folly (= 2020.01.13.00)
- React-Core/RCTBlobHeaders (= 0.63.4)
- React-Core/RCTWebSocket (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTImage (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- React-Core/RCTBlobHeaders (= 0.63.5)
- React-Core/RCTWebSocket (= 0.63.5)
- React-jsi (= 0.63.5)
- React-RCTNetwork (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- React-RCTImage (0.63.5):
- FBReactNativeSpec (= 0.63.5)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTImageHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- React-RCTNetwork (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTLinking (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- React-Core/RCTLinkingHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTNetwork (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- RCTTypeSafety (= 0.63.5)
- React-Core/RCTImageHeaders (= 0.63.5)
- React-jsi (= 0.63.5)
- React-RCTNetwork (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- React-RCTLinking (0.63.5):
- FBReactNativeSpec (= 0.63.5)
- React-Core/RCTLinkingHeaders (= 0.63.5)
- React-jsi (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- React-RCTNetwork (0.63.5):
- FBReactNativeSpec (= 0.63.5)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTNetworkHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTSettings (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- RCTTypeSafety (= 0.63.5)
- React-Core/RCTNetworkHeaders (= 0.63.5)
- React-jsi (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- React-RCTSettings (0.63.5):
- FBReactNativeSpec (= 0.63.5)
- Folly (= 2020.01.13.00)
- RCTTypeSafety (= 0.63.4)
- React-Core/RCTSettingsHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- React-RCTText (0.63.4):
- React-Core/RCTTextHeaders (= 0.63.4)
- React-RCTVibration (0.63.4):
- FBReactNativeSpec (= 0.63.4)
- RCTTypeSafety (= 0.63.5)
- React-Core/RCTSettingsHeaders (= 0.63.5)
- React-jsi (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- React-RCTText (0.63.5):
- React-Core/RCTTextHeaders (= 0.63.5)
- React-RCTVibration (0.63.5):
- FBReactNativeSpec (= 0.63.5)
- Folly (= 2020.01.13.00)
- React-Core/RCTVibrationHeaders (= 0.63.4)
- React-jsi (= 0.63.4)
- ReactCommon/turbomodule/core (= 0.63.4)
- ReactCommon/turbomodule/core (0.63.4):
- React-Core/RCTVibrationHeaders (= 0.63.5)
- React-jsi (= 0.63.5)
- ReactCommon/turbomodule/core (= 0.63.5)
- ReactCommon/turbomodule/core (0.63.5):
- DoubleConversion
- Folly (= 2020.01.13.00)
- glog
- React-callinvoker (= 0.63.4)
- React-Core (= 0.63.4)
- React-cxxreact (= 0.63.4)
- React-jsi (= 0.63.4)
- React-callinvoker (= 0.63.5)
- React-Core (= 0.63.5)
- React-cxxreact (= 0.63.5)
- React-jsi (= 0.63.5)
- ReactNativeAudioToolkit (2.0.3):
- React
- ReactNativeNavigation (7.27.1):
@@ -637,8 +637,8 @@ SPEC CHECKSUMS:
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
CryptoSwift: c4f2debceb38bf44c80659afe009f71e23e4a082
DoubleConversion: cde416483dac037923206447da6e1454df403714
FBLazyVector: 3bb422f41b18121b71783a905c10e58606f7dc3e
FBReactNativeSpec: f2c97f2529dd79c083355182cc158c9f98f4bd6e
FBLazyVector: 352a8ca9bbc8e2f097d680747a8c97ecef12d469
FBReactNativeSpec: 7dfb84f624136a45727c813ed21d130cd3e61beb
Folly: b73c3869541e86821df3c387eb0af5f65addfab4
glog: 36ce0530c6d2c3a5a4326885ef4069564887a1db
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
@@ -646,16 +646,16 @@ SPEC CHECKSUMS:
libwebp: 60305b2e989864154bd9be3d772730f08fc6a59c
Permission-Camera: afad27bf90337684d4a86f3825112d648c8c4d3b
Permission-Microphone: 0ffabc3fe1c75cfb260525ee3f529383c9f4368c
RCTRequired: 082f10cd3f905d6c124597fd1c14f6f2655ff65e
RCTTypeSafety: 8c9c544ecbf20337d069e4ae7fd9a377aadf504b
React: b0a957a2c44da4113b0c4c9853d8387f8e64e615
React-callinvoker: c3f44dd3cb195b6aa46621fff95ded79d59043fe
React-Core: d3b2a1ac9a2c13c3bcde712d9281fc1c8a5b315b
React-CoreModules: 0581ff36cb797da0943d424f69e7098e43e9be60
React-cxxreact: c1480d4fda5720086c90df537ee7d285d4c57ac3
React-jsi: a0418934cf48f25b485631deb27c64dc40fb4c31
React-jsiexecutor: 93bd528844ad21dc07aab1c67cb10abae6df6949
React-jsinspector: 58aef7155bc9a9683f5b60b35eccea8722a4f53a
RCTRequired: 5520387431beaa5f32aa8726bf746cd5353119fe
RCTTypeSafety: bc90d6e287fa427c50ed770922bac30faf0bbfa3
React: 83a7f231f462b09260a53c5c51005e7659c66890
React-callinvoker: 1c3fdb5562c792212e149637b8a167516bb4b58e
React-Core: 8baca8644a516e772c77e3923697cfe2b58c1606
React-CoreModules: 200c931e17b332024c2e9d878f67b87c00c2c83b
React-cxxreact: 9096ebaeebf6a1475a14448fa8bfc380c13d7882
React-jsi: 7d908b17758178b076a05a254523f1a4227b53d2
React-jsiexecutor: e06a32e42affb2bd89e4c8369349b5fcf787710c
React-jsinspector: fdbc08866b34ae8e1b788ea1cbd9f9d1ca2aa3d6
react-native-background-timer: 1f7d560647b40e6a60b01c452ba29c54bf581fc4
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
react-native-blur: 4568dd93d1d82748c180df8beb2d929c97b13b47
@@ -673,16 +673,16 @@ SPEC CHECKSUMS:
react-native-status: 21f75d492fd311dc111303da38a7a2b23a8a8466
react-native-status-keycard: f60ca57d789aad6875c64ece81ab06ef0609e0d3
react-native-webview: 28a8636d97ee641f2ee8f20492d7a6c269c1d703
React-RCTActionSheet: 89a0ca9f4a06c1f93c26067af074ccdce0f40336
React-RCTAnimation: 1bde3ecc0c104c55df246eda516e0deb03c4e49b
React-RCTBlob: a97d378b527740cc667e03ebfa183a75231ab0f0
React-RCTImage: c1b1f2d3f43a4a528c8946d6092384b5c880d2f0
React-RCTLinking: 35ae4ab9dc0410d1fcbdce4d7623194a27214fb2
React-RCTNetwork: 29ec2696f8d8cfff7331fac83d3e893c95ef43ae
React-RCTSettings: 60f0691bba2074ef394f95d4c2265ec284e0a46a
React-RCTText: 5c51df3f08cb9dedc6e790161195d12bac06101c
React-RCTVibration: ae4f914cfe8de7d4de95ae1ea6cc8f6315d73d9d
ReactCommon: 73d79c7039f473b76db6ff7c6b159c478acbbb3b
React-RCTActionSheet: e911b99f0d6fa7711ffc2f62d236b12a32771835
React-RCTAnimation: ad8b853170a059faf31d6add34f67d22391bbe01
React-RCTBlob: 134c7270b6672c9c05383b2e0f7f044ba39d7dda
React-RCTImage: c5c74ba8850a193d73aef8efb8fcbb4f9cad7653
React-RCTLinking: 12468e952704555c8cb4e3de94c7b5a266811326
React-RCTNetwork: e9cfaeb9f3657ae91f895e798734141db6e1af5b
React-RCTSettings: 9a09419bd5e8494f6e146e2c9f5c8e2c6e90ed58
React-RCTText: 393f059d7ec02c733da57240694201e734f0dc84
React-RCTVibration: 3e83f53610d63d3c1fc4db303305e934e73047cc
ReactCommon: b9ff54b6dd22ba4a776eda22d7f83ec27544ca35
ReactNativeAudioToolkit: de9610f323e855ac6574be8c99621f3d57c5df06
ReactNativeNavigation: 94979dd1572a3f093fc85d4599360530a1bed8c8
RNCAsyncStorage: b2489b49e38c85e10ed45a888d13a2a4c7b32ea1
@@ -708,7 +708,7 @@ SPEC CHECKSUMS:
SSZipArchive: fe6a26b2a54d5a0890f2567b5cc6de5caa600aef
TOCropViewController: edfd4f25713d56905ad1e0b9f5be3fbe0f59c863
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
Yoga: 4bd86afe9883422a7c4028c00e34790f560923d6
Yoga: 0276e9f20976c8568e107cfc1163a8629051adc0
PODFILE CHECKSUM: a1de9468266e7f0b5273acea713782ab759690f1
+6
View File
@@ -41,6 +41,8 @@
65F6941A25780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
65F6941B25780A4F00A45E76 /* Bridge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65F6941825780A4F00A45E76 /* Bridge.swift */; };
70ADBB5ECF934DCF8A0E4919 /* Inter-Regular.otf in Resources */ = {isa = PBXBuildFile; fileRef = 1426DF592BA248FC81D955CB /* Inter-Regular.otf */; };
715D8132290BE850006F5C88 /* UbuntuMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */; };
715D8133290BE850006F5C88 /* UbuntuMono-Regular.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */; };
74B758FC20D7C00B003343C3 /* launch-image-universal.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */; };
8391E8E0E93C41A98AAA6631 /* Inter-SemiBoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */; };
A0093AB50DA85E1D01818CCA /* libPods-Status-StatusIm-StatusImTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E88D313E5D854BE6BC81FC1 /* libPods-Status-StatusIm-StatusImTests.a */; };
@@ -121,6 +123,7 @@
65F6941725780A4E00A45E76 /* StatusImTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "StatusImTests-Bridging-Header.h"; sourceTree = "<group>"; };
65F6941825780A4F00A45E76 /* Bridge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Bridge.swift; sourceTree = "<group>"; };
693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-SemiBold.otf"; path = "../resources/fonts/Inter-SemiBold.otf"; sourceTree = "<group>"; };
715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; name = "UbuntuMono-Regular.ttf"; path = "../resources/fonts/UbuntuMono-Regular.ttf"; sourceTree = "<group>"; };
74B758FB20D7C00B003343C3 /* launch-image-universal.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = "launch-image-universal.storyboard"; sourceTree = "<group>"; };
7AFBE28450C0239119FBDBA2 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
8B9A886A2CB448B1ABA0EB62 /* libc++.tbd */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; };
@@ -229,6 +232,7 @@
693A62DB37BC4CD5A30E5C96 /* Inter-SemiBold.otf */,
A4F2BBE8D4DD4140A6CCAC39 /* Inter-SemiBoldItalic.otf */,
9C76AF5A418D4D65A4CAD1D9 /* InterStatus-Regular.otf */,
715D8131290BE850006F5C88 /* UbuntuMono-Regular.ttf */,
);
name = Resources;
sourceTree = "<group>";
@@ -475,6 +479,7 @@
buildActionMask = 2147483647;
files = (
74B758FC20D7C00B003343C3 /* launch-image-universal.storyboard in Resources */,
715D8132290BE850006F5C88 /* UbuntuMono-Regular.ttf in Resources */,
B2F2D1BC1D9D531B00B7B453 /* Images.xcassets in Resources */,
D84616FB563A48EBB1678699 /* Inter-Bold.otf in Resources */,
D99C50E5E18942A39C8DDF61 /* Inter-BoldItalic.otf in Resources */,
@@ -493,6 +498,7 @@
buildActionMask = 2147483647;
files = (
3AAD2ACA24A3A60E0075D594 /* launch-image-universal.storyboard in Resources */,
715D8133290BE850006F5C88 /* UbuntuMono-Regular.ttf in Resources */,
3AAD2ACB24A3A60E0075D594 /* Images.xcassets in Resources */,
3AAD2ACC24A3A60E0075D594 /* Inter-Bold.otf in Resources */,
3AAD2ACD24A3A60E0075D594 /* Inter-BoldItalic.otf in Resources */,
+1
View File
@@ -105,6 +105,7 @@
<string>Inter-Thin-BETA.otf</string>
<string>Inter-ThinItalic-BETA.otf</string>
<string>InterStatus-Regular.otf</string>
<string>UbuntuMono-Regular.ttf</string>
</array>
<key>UIBackgroundModes</key>
<array>
+1
View File
@@ -108,6 +108,7 @@
<string>Inter-Thin-BETA.otf</string>
<string>Inter-ThinItalic-BETA.otf</string>
<string>InterStatus-Regular.otf</string>
<string>UbuntuMono-Regular.ttf</string>
</array>
<key>UIBackgroundModes</key>
<array>
+5 -1
View File
@@ -20,7 +20,11 @@ buildGoPackage {
# Build the Go library
buildPhase = ''
runHook preBuild
go build -buildmode=c-archive -o $out/libstatus.a $NIX_BUILD_TOP/main.go
go build \
-buildmode='c-archive' \
-tags='gowaku_skip_migrations' \
-o "$out/libstatus.a" \
$NIX_BUILD_TOP/main.go
runHook postBuild
'';
}
+13 -8
View File
@@ -11,6 +11,9 @@
let
inherit (lib) concatStringsSep optionalString optional;
isIOS = platform == "ios";
isAndroid = platform == "android";
in buildGoPackage {
pname = source.repo;
version = "${source.cleanVersion}-${source.shortRev}-${platform}";
@@ -20,30 +23,32 @@ in buildGoPackage {
# Sandbox causes Xcode issues on MacOS. Requires sandbox=relaxed.
# https://github.com/status-im/status-mobile/pull/13912
__noChroot = (platform == "ios");
__noChroot = isIOS;
extraSrcPaths = [ gomobile ];
nativeBuildInputs = [ gomobile removeReferencesTo ]
++ optional (platform == "android") openjdk
++ optional (platform == "ios") xcodeWrapper;
++ optional isAndroid openjdk
++ optional isIOS xcodeWrapper;
ldflags = concatStringsSep " " goBuildLdFlags;
ANDROID_HOME = optionalString (platform == "android") androidPkgs.sdk;
ANDROID_HOME = optionalString isAndroid androidPkgs.sdk;
# Ensure XCode is present for iOS, instead of failing at the end of the build.
preConfigure = optionalString (platform == "ios") utils.enforceXCodeAvailable;
preConfigure = optionalString isIOS utils.enforceXCodeAvailable;
buildPhase = ''
runHook preBuild
echo -e "\nBuilding $pname for: ${concatStringsSep "," targets}"
set -x
gomobile bind \
${concatStringsSep " " goBuildFlags} \
-ldflags="$ldflags" \
-target=${concatStringsSep "," targets} \
${optionalString (platform == "android") "-androidapi=${platformVersion}"} \
${optionalString (platform == "ios") "-iosversion=${platformVersion}"} \
${optionalString isAndroid "-androidapi=${platformVersion}" } \
${optionalString isIOS "-iosversion=${platformVersion}" } \
-tags='${optionalString isIOS "nowatchdog"} gowaku_skip_migrations' \
-o ${outputFileName} \
${source.goPackagePath}/mobile
@@ -58,7 +63,7 @@ in buildGoPackage {
# Drop govers from disallowedReferences.
dontRenameImports = true;
# Replace hardcoded paths to go package in /nix/store.
preFixup = optionalString (platform == "ios") ''
preFixup = optionalString isIOS ''
find $out -type f -exec \
remove-references-to -t $disallowedReferences '{}' + || true
'';
+5 -1
View File
@@ -12,6 +12,9 @@
"app:packager": "react-native start --host 0.0.0.0 --port 8081",
"app:android": "react-native run-android"
},
"resolutions": {
"react-devtools-core": "^4.26.0"
},
"dependencies": {
"@babel/preset-typescript": "^7.17.12",
"@react-native-async-storage/async-storage": "^1.17.9",
@@ -37,7 +40,7 @@
"qrcode": "^1.4.1",
"react": "16.13.1",
"react-dom": "^16.4.2",
"react-native": "0.63.4",
"react-native": "0.63.5",
"react-native-background-timer": "^2.1.1",
"react-native-blob-util": "^0.13.18",
"react-native-camera-kit": "^8.0.4",
@@ -70,6 +73,7 @@
"react-native-svg": "^9.8.4",
"react-native-touch-id": "^4.4.1",
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#refs/tags/v11.16.0-status",
"react-syntax-highlighter": "^15.5.0",
"rn-emoji-keyboard": "git+https://github.com/status-im/rn-emoji-keyboard.git#refs/tags/v0.4.3",
"tdigest": "^0.1.1"
},
+161 -127
View File
@@ -1,131 +1,165 @@
{
"fleets": {
"eth.prod": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.prod": "enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443",
"boot-01.do-ams3.eth.prod": "enode://436cc6f674928fdc9a9f7990f2944002b685d1c37f025c1be425185b5b1f0900feaf1ccc2a6130268f9901be4a7d252f37302c8335a2c1a62736e9232691cc3a@178.128.138.128:443",
"boot-01.gc-us-central1-a.eth.prod": "enode://32ff6d88760b0947a3dee54ceff4d8d7f0b4c023c6dad34568615fcae89e26cc2753f28f12485a4116c977be937a72665116596265aa0736b53d46b27446296a@34.70.75.208:443",
"boot-02.ac-cn-hongkong-c.eth.prod": "enode://23d0740b11919358625d79d4cac7d50a34d79e9c69e16831c5c70573757a1f5d7d884510bc595d7ee4da3c1508adf87bbc9e9260d804ef03f8c1e37f2fb2fc69@47.52.106.107:443",
"boot-02.do-ams3.eth.prod": "enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@178.128.140.188:443",
"boot-02.gc-us-central1-a.eth.prod": "enode://5405c509df683c962e7c9470b251bb679dd6978f82d5b469f1f6c64d11d50fbd5dd9f7801c6ad51f3b20a5f6c7ffe248cc9ab223f8bcbaeaf14bb1c0ef295fd0@35.223.215.156:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.prod": "enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443",
"mail-01.do-ams3.eth.prod": "enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@178.128.142.54:443",
"mail-01.gc-us-central1-a.eth.prod": "enode://ee2b53b0ace9692167a410514bca3024695dbf0e1a68e1dff9716da620efb195f04a4b9e873fb9b74ac84de801106c465b8e2b6c4f0d93b8749d1578bfcaf03e@104.197.238.144:443",
"mail-02.ac-cn-hongkong-c.eth.prod": "enode://2c8de3cbb27a3d30cbb5b3e003bc722b126f5aef82e2052aaef032ca94e0c7ad219e533ba88c70585ebd802de206693255335b100307645ab5170e88620d2a81@47.244.221.14:443",
"mail-02.do-ams3.eth.prod": "enode://7aa648d6e855950b2e3d3bf220c496e0cae4adfddef3e1e6062e6b177aec93bc6cdcf1282cb40d1656932ebfdd565729da440368d7c4da7dbd4d004b1ac02bf8@178.128.142.26:443",
"mail-02.gc-us-central1-a.eth.prod": "enode://30211cbd81c25f07b03a0196d56e6ce4604bb13db773ff1c0ea2253547fafd6c06eae6ad3533e2ba39d59564cfbdbb5e2ce7c137a5ebb85e99dcfc7a75f99f55@23.236.58.92:443",
"mail-03.ac-cn-hongkong-c.eth.prod": "enode://e85f1d4209f2f99da801af18db8716e584a28ad0bdc47fbdcd8f26af74dbd97fc279144680553ec7cd9092afe683ddea1e0f9fc571ebcb4b1d857c03a088853d@47.244.129.82:443",
"mail-03.do-ams3.eth.prod": "enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@178.128.142.94:443",
"mail-03.gc-us-central1-a.eth.prod": "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.prod": "/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4",
"boot-01.do-ams3.eth.prod": "/ip4/178.128.138.128/tcp/30703/ethv4/16Uiu2HAmRHPzF3rQg55PgYPcQkyvPVH9n2hWsYPhUJBZ6kVjJgdV",
"boot-01.gc-us-central1-a.eth.prod": "/ip4/34.70.75.208/tcp/30703/ethv4/16Uiu2HAm6ZsERLx2BwVD2UM9SVPnnMU6NBycG8XPtu8qKys5awsU",
"boot-02.ac-cn-hongkong-c.eth.prod": "/ip4/47.52.106.107/tcp/30703/ethv4/16Uiu2HAmEHiptiDDd9gqNY8oQqo8hHUWMHJzfwt5aLRdD6W2zcXR",
"boot-02.do-ams3.eth.prod": "/ip4/178.128.140.188/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf",
"boot-02.gc-us-central1-a.eth.prod": "/ip4/35.223.215.156/tcp/30703/ethv4/16Uiu2HAmQEUFE2YaJohavWtHxPTEFv3sEGJtDqvtGEv78DFoEWQF"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.prod": "enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443",
"node-01.do-ams3.eth.prod": "enode://66ba15600cda86009689354c3a77bdf1a97f4f4fb3ab50ffe34dbc904fac561040496828397be18d9744c75881ffc6ac53729ddbd2cdbdadc5f45c400e2622f7@178.128.141.87:443",
"node-01.gc-us-central1-a.eth.prod": "enode://182ed5d658d1a1a4382c9e9f7c9e5d8d9fec9db4c71ae346b9e23e1a589116aeffb3342299bdd00e0ab98dbf804f7b2d8ae564ed18da9f45650b444aed79d509@34.68.132.118:443",
"node-02.ac-cn-hongkong-c.eth.prod": "enode://8bebe73ddf7cf09e77602c7d04c93a73f455b51f24ae0d572917a4792f1dec0bb4c562759b8830cc3615a658d38c1a4a38597a1d7ae3ba35111479fc42d65dec@47.75.85.212:443",
"node-02.do-ams3.eth.prod": "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@134.209.136.79:443",
"node-02.gc-us-central1-a.eth.prod": "enode://fbeddac99d396b91d59f2c63a3cb5fc7e0f8a9f7ce6fe5f2eed5e787a0154161b7173a6a73124a4275ef338b8966dc70a611e9ae2192f0f2340395661fad81c0@34.67.230.193:443",
"node-03.ac-cn-hongkong-c.eth.prod": "enode://ac3948b2c0786ada7d17b80cf869cf59b1909ea3accd45944aae35bf864cc069126da8b82dfef4ddf23f1d6d6b44b1565c4cf81c8b98022253c6aea1a89d3ce2@47.75.88.12:443",
"node-03.do-ams3.eth.prod": "enode://ce559a37a9c344d7109bd4907802dd690008381d51f658c43056ec36ac043338bd92f1ac6043e645b64953b06f27202d679756a9c7cf62fdefa01b2e6ac5098e@134.209.136.123:443",
"node-03.gc-us-central1-a.eth.prod": "enode://c07aa0deea3b7056c5d45a85bca42f0d8d3b1404eeb9577610f386e0a4744a0e7b2845ae328efc4aa4b28075af838b59b5b3985bffddeec0090b3b7669abc1f3@35.226.92.155:443",
"node-04.ac-cn-hongkong-c.eth.prod": "enode://385579fc5b14e04d5b04af7eee835d426d3d40ccf11f99dbd95340405f37cf3bbbf830b3eb8f70924be0c2909790120682c9c3e791646e2d5413e7801545d353@47.244.221.249:443",
"node-04.do-ams3.eth.prod": "enode://4e0a8db9b73403c9339a2077e911851750fc955db1fc1e09f81a4a56725946884dd5e4d11258eac961f9078a393c45bcab78dd0e3bc74e37ce773b3471d2e29c@134.209.136.101:443",
"node-04.gc-us-central1-a.eth.prod": "enode://0624b4a90063923c5cc27d12624b6a49a86dfb3623fcb106801217fdbab95f7617b83fa2468b9ae3de593ff6c1cf556ccf9bc705bfae9cb4625999765127b423@35.222.158.246:443",
"node-05.ac-cn-hongkong-c.eth.prod": "enode://b77bffc29e2592f30180311dd81204ab845e5f78953b5ba0587c6631be9c0862963dea5eb64c90617cf0efd75308e22a42e30bc4eb3cd1bbddbd1da38ff6483e@47.75.10.177:443",
"node-05.do-ams3.eth.prod": "enode://a8bddfa24e1e92a82609b390766faa56cf7a5eef85b22a2b51e79b333c8aaeec84f7b4267e432edd1cf45b63a3ad0fc7d6c3a16f046aa6bc07ebe50e80b63b8c@178.128.141.249:443",
"node-05.gc-us-central1-a.eth.prod": "enode://a5fe9c82ad1ffb16ae60cb5d4ffe746b9de4c5fbf20911992b7dd651b1c08ba17dd2c0b27ee6b03162c52d92f219961cc3eb14286aca8a90b75cf425826c3bd8@104.154.230.58:443",
"node-06.ac-cn-hongkong-c.eth.prod": "enode://cf5f7a7e64e3b306d1bc16073fba45be3344cb6695b0b616ccc2da66ea35b9f35b3b231c6cf335fdfaba523519659a440752fc2e061d1e5bc4ef33864aac2f19@47.75.221.196:443",
"node-06.do-ams3.eth.prod": "enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@178.128.141.0:443",
"node-06.gc-us-central1-a.eth.prod": "enode://282e009967f9f132a5c2dd366a76319f0d22d60d0c51f7e99795a1e40f213c2705a2c10e4cc6f3890319f59da1a535b8835ed9b9c4b57c3aad342bf312fd7379@35.223.240.17:443",
"node-07.ac-cn-hongkong-c.eth.prod": "enode://13d63a1f85ccdcbd2fb6861b9bd9d03f94bdba973608951f7c36e5df5114c91de2b8194d71288f24bfd17908c48468e89dd8f0fb8ccc2b2dedae84acdf65f62a@47.244.210.80:443",
"node-07.do-ams3.eth.prod": "enode://2b01955d7e11e29dce07343b456e4e96c081760022d1652b1c4b641eaf320e3747871870fa682e9e9cfb85b819ce94ed2fee1ac458904d54fd0b97d33ba2c4a4@134.209.136.112:443",
"node-07.gc-us-central1-a.eth.prod": "enode://b706a60572634760f18a27dd407b2b3582f7e065110dae10e3998498f1ae3f29ba04db198460d83ed6d2bfb254bb06b29aab3c91415d75d3b869cd0037f3853c@35.239.5.162:443",
"node-08.ac-cn-hongkong-c.eth.prod": "enode://32915c8841faaef21a6b75ab6ed7c2b6f0790eb177ad0f4ea6d731bacc19b938624d220d937ebd95e0f6596b7232bbb672905ee12601747a12ee71a15bfdf31c@47.75.59.11:443",
"node-08.do-ams3.eth.prod": "enode://0d9d65fcd5592df33ed4507ce862b9c748b6dbd1ea3a1deb94e3750052760b4850aa527265bbaf357021d64d5cc53c02b410458e732fafc5b53f257944247760@178.128.141.42:443",
"node-08.gc-us-central1-a.eth.prod": "enode://e87f1d8093d304c3a9d6f1165b85d6b374f1c0cc907d39c0879eb67f0a39d779be7a85cbd52920b6f53a94da43099c58837034afa6a7be4b099bfcd79ad13999@35.238.106.101:443"
}
},
"eth.staging": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.staging": "enode://630b0342ca4e9552f50714b6c8e28d6955bc0fd14e7950f93bc3b2b8cc8c1f3b6d103df66f51a13d773b5db0f130661fb5c7b8fa21c48890c64c79b41a56a490@47.91.229.44:443",
"boot-01.do-ams3.eth.staging": "enode://f79fb3919f72ca560ad0434dcc387abfe41e0666201ebdada8ede0462454a13deb05cda15f287d2c4bd85da81f0eb25d0a486bbbc8df427b971ac51533bd00fe@174.138.107.239:443",
"boot-01.gc-us-central1-a.eth.staging": "enode://10a78c17929a7019ef4aa2249d7302f76ae8a06f40b2dc88b7b31ebff4a623fbb44b4a627acba296c1ced3775d91fbe18463c15097a6a36fdb2c804ff3fc5b35@35.238.97.234:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.staging": "enode://b74859176c9751d314aeeffc26ec9f866a412752e7ddec91b19018a18e7cca8d637cfe2cedcb972f8eb64d816fbd5b4e89c7e8c7fd7df8a1329fa43db80b0bfe@47.52.90.156:443",
"mail-01.do-ams3.eth.staging": "enode://69f72baa7f1722d111a8c9c68c39a31430e9d567695f6108f31ccb6cd8f0adff4991e7fdca8fa770e75bc8a511a87d24690cbc80e008175f40c157d6f6788d48@206.189.240.16:443",
"mail-01.gc-us-central1-a.eth.staging": "enode://e4fc10c1f65c8aed83ac26bc1bfb21a45cc1a8550a58077c8d2de2a0e0cd18e40fd40f7e6f7d02dc6cd06982b014ce88d6e468725ffe2c138e958788d0002a7f@35.239.193.41:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.staging": "/ip4/47.91.229.44/tcp/30703/ethv4/16Uiu2HAmRnt2Eyoknh3auxh4fJwkRgqkH1gqrWGes8Pk1k3MV4xu",
"boot-01.do-ams3.eth.staging": "/ip4/174.138.107.239/tcp/30703/ethv4/16Uiu2HAm8UZXUHEPZrpJbcQ3yVFH6UtKrwsG6jH4ai72PsbLfVFb",
"boot-01.gc-us-central1-a.eth.staging": "/ip4/35.238.97.234/tcp/30703/ethv4/16Uiu2HAm6G9sDMkrB4Xa5EH3Zx2dysCxFgBTSRzghic3Z9tRFRNE"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.staging": "enode://088cf5a93c576fae52f6f075178467b8ff98bacf72f59e88efb16dfba5b30f80a4db78f8e3cb3d87f2f6521746ef4a8768465ef2896c6af24fd77a425e95b6dd@47.52.226.137:443",
"node-01.do-ams3.eth.staging": "enode://914c0b30f27bab30c1dfd31dad7652a46fda9370542aee1b062498b1345ee0913614b8b9e3e84622e84a7203c5858ae1d9819f63aece13ee668e4f6668063989@167.99.19.148:443",
"node-01.gc-us-central1-a.eth.staging": "enode://d3878441652f010326889f28360e69f2d09d06540f934fada0e17b374ce5319de64279aba3c44a5bf807d9967c6d705b3b4c6b03fa70763240e2ee6af01a539e@35.192.0.86:443"
}
},
"eth.test": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.test": "enode://daae2e72820e86e942fa2a8aa7d6e9954d4043a753483d8bd338e16be82cf962392d5c0e1ae57c3d793c3d3dddd8fd58339262e4234dc966f953cd73b535f5fa@47.52.188.149:443",
"boot-01.do-ams3.eth.test": "enode://9e0988575eb7717c25dea72fd11c7b37767dc09c1a7686f7c2ec577d308d24b377ceb675de4317474a1a870e47882732967f4fa785b02ba95d669b31d464dec0@206.189.243.164:443",
"boot-01.gc-us-central1-a.eth.test": "enode://c1e5018887c863d64e431b69bf617561087825430e4401733f5ba77c70db14236df381fefb0ebe1ac42294b9e261bbe233dbdb83e32c586c66ae26c8de70cb4c@35.188.168.137:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.test": "enode://619dbb5dda12e85bf0eb5db40fb3de625609043242737c0e975f7dfd659d85dc6d9a84f9461a728c5ab68c072fed38ca6a53917ca24b8e93cc27bdef3a1e79ac@47.52.188.196:443",
"mail-01.do-ams3.eth.test": "enode://e4865fe6c2a9c1a563a6447990d8e9ce672644ae3e08277ce38ec1f1b690eef6320c07a5d60c3b629f5d4494f93d6b86a745a0bf64ab295bbf6579017adc6ed8@206.189.243.161:443",
"mail-01.gc-us-central1-a.eth.test": "enode://707e57453acd3e488c44b9d0e17975371e2f8fb67525eae5baca9b9c8e06c86cde7c794a6c2e36203bf9f56cae8b0e50f3b33c4c2b694a7baeea1754464ce4e3@35.192.229.172:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.test": "/ip4/47.52.188.149/tcp/30703/ethv4/16Uiu2HAm9Vatqr4GfVCqnyeaPtCF3q8fz8kDDUgqXVfFG7ZfSA7w",
"boot-01.do-ams3.eth.test": "/ip4/206.189.243.164/tcp/30703/ethv4/16Uiu2HAmBCh5bgYr6V3fDuLqUzvtSAsFTQJCQ3TVHT8ta8bTu2Jm",
"boot-01.gc-us-central1-a.eth.test": "/ip4/35.188.168.137/tcp/30703/ethv4/16Uiu2HAm3MUqtGjmetyZ9L4SN2R8oHDWvACUcec25LjtDD5euiRH"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.test": "enode://ad38f94030a846cc7005b7a1f3b6b01bf4ef59d34e8d3d6f4d12df23d14ba8656702a435d34cf4df3b412c0c1923df5adcce8461321a0d8ffb9435b26e572c2a@47.52.255.194:443",
"node-01.do-ams3.eth.test": "enode://1d193635e015918fb85bbaf774863d12f65d70c6977506187ef04420d74ec06c9e8f0dcb57ea042f85df87433dab17a1260ed8dde1bdf9d6d5d2de4b7bf8e993@206.189.243.163:443",
"node-01.gc-us-central1-a.eth.test": "enode://f593a27731bc0f8eb088e2d39222c2d59dfb9bf0b3950d7a828d51e8ab9e08fffbd9916a82fd993c1a080c57c2bd70ed6c36f489a969de697aff93088dbee1a9@35.194.31.108:443"
}
},
"wakuv2.prod": {
"waku": {
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/ip4/8.210.222.231/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
"node-01.do-ams3.wakuv2.prod": "/ip4/188.166.135.145/tcp/30303/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/ip4/34.121.100.108/tcp/30303/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
}
},
"wakuv2.test": {
"waku": {
"node-01.ac-cn-hongkong-c.wakuv2.test": "/ip4/47.242.210.73/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
"node-01.do-ams3.wakuv2.test": "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/ip4/104.154.239.128/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
}
}
"fleets": {
"eth.prod": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.prod": "enode://6e6554fb3034b211398fcd0f0082cbb6bd13619e1a7e76ba66e1809aaa0c5f1ac53c9ae79cf2fd4a7bacb10d12010899b370c75fed19b991d9c0cdd02891abad@47.75.99.169:443",
"boot-01.do-ams3.eth.prod": "enode://436cc6f674928fdc9a9f7990f2944002b685d1c37f025c1be425185b5b1f0900feaf1ccc2a6130268f9901be4a7d252f37302c8335a2c1a62736e9232691cc3a@178.128.138.128:443",
"boot-01.gc-us-central1-a.eth.prod": "enode://32ff6d88760b0947a3dee54ceff4d8d7f0b4c023c6dad34568615fcae89e26cc2753f28f12485a4116c977be937a72665116596265aa0736b53d46b27446296a@34.70.75.208:443",
"boot-02.ac-cn-hongkong-c.eth.prod": "enode://23d0740b11919358625d79d4cac7d50a34d79e9c69e16831c5c70573757a1f5d7d884510bc595d7ee4da3c1508adf87bbc9e9260d804ef03f8c1e37f2fb2fc69@47.52.106.107:443",
"boot-02.do-ams3.eth.prod": "enode://5395aab7833f1ecb671b59bf0521cf20224fe8162fc3d2675de4ee4d5636a75ec32d13268fc184df8d1ddfa803943906882da62a4df42d4fccf6d17808156a87@178.128.140.188:443",
"boot-02.gc-us-central1-a.eth.prod": "enode://5405c509df683c962e7c9470b251bb679dd6978f82d5b469f1f6c64d11d50fbd5dd9f7801c6ad51f3b20a5f6c7ffe248cc9ab223f8bcbaeaf14bb1c0ef295fd0@35.223.215.156:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.prod": "enode://606ae04a71e5db868a722c77a21c8244ae38f1bd6e81687cc6cfe88a3063fa1c245692232f64f45bd5408fed5133eab8ed78049332b04f9c110eac7f71c1b429@47.75.247.214:443",
"mail-01.do-ams3.eth.prod": "enode://c42f368a23fa98ee546fd247220759062323249ef657d26d357a777443aec04db1b29a3a22ef3e7c548e18493ddaf51a31b0aed6079bd6ebe5ae838fcfaf3a49@178.128.142.54:443",
"mail-01.gc-us-central1-a.eth.prod": "enode://ee2b53b0ace9692167a410514bca3024695dbf0e1a68e1dff9716da620efb195f04a4b9e873fb9b74ac84de801106c465b8e2b6c4f0d93b8749d1578bfcaf03e@104.197.238.144:443",
"mail-02.ac-cn-hongkong-c.eth.prod": "enode://2c8de3cbb27a3d30cbb5b3e003bc722b126f5aef82e2052aaef032ca94e0c7ad219e533ba88c70585ebd802de206693255335b100307645ab5170e88620d2a81@47.244.221.14:443",
"mail-02.do-ams3.eth.prod": "enode://7aa648d6e855950b2e3d3bf220c496e0cae4adfddef3e1e6062e6b177aec93bc6cdcf1282cb40d1656932ebfdd565729da440368d7c4da7dbd4d004b1ac02bf8@178.128.142.26:443",
"mail-02.gc-us-central1-a.eth.prod": "enode://30211cbd81c25f07b03a0196d56e6ce4604bb13db773ff1c0ea2253547fafd6c06eae6ad3533e2ba39d59564cfbdbb5e2ce7c137a5ebb85e99dcfc7a75f99f55@23.236.58.92:443",
"mail-03.ac-cn-hongkong-c.eth.prod": "enode://e85f1d4209f2f99da801af18db8716e584a28ad0bdc47fbdcd8f26af74dbd97fc279144680553ec7cd9092afe683ddea1e0f9fc571ebcb4b1d857c03a088853d@47.244.129.82:443",
"mail-03.do-ams3.eth.prod": "enode://8a64b3c349a2e0ef4a32ea49609ed6eb3364be1110253c20adc17a3cebbc39a219e5d3e13b151c0eee5d8e0f9a8ba2cd026014e67b41a4ab7d1d5dd67ca27427@178.128.142.94:443",
"mail-03.gc-us-central1-a.eth.prod": "enode://44160e22e8b42bd32a06c1532165fa9e096eebedd7fa6d6e5f8bbef0440bc4a4591fe3651be68193a7ec029021cdb496cfe1d7f9f1dc69eb99226e6f39a7a5d4@35.225.221.245:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.prod": "/ip4/47.75.99.169/tcp/30703/ethv4/16Uiu2HAmV8Hq9e3zm9TMVP4zrVHo3BjqW5D6bDVV6VQntQd687e4",
"boot-01.do-ams3.eth.prod": "/ip4/178.128.138.128/tcp/30703/ethv4/16Uiu2HAmRHPzF3rQg55PgYPcQkyvPVH9n2hWsYPhUJBZ6kVjJgdV",
"boot-01.gc-us-central1-a.eth.prod": "/ip4/34.70.75.208/tcp/30703/ethv4/16Uiu2HAm6ZsERLx2BwVD2UM9SVPnnMU6NBycG8XPtu8qKys5awsU",
"boot-02.ac-cn-hongkong-c.eth.prod": "/ip4/47.52.106.107/tcp/30703/ethv4/16Uiu2HAmEHiptiDDd9gqNY8oQqo8hHUWMHJzfwt5aLRdD6W2zcXR",
"boot-02.do-ams3.eth.prod": "/ip4/178.128.140.188/tcp/30703/ethv4/16Uiu2HAmLqTXuY4Sb6G28HNooaFUXUKzpzKXCcgyJxgaEE2i5vnf",
"boot-02.gc-us-central1-a.eth.prod": "/ip4/35.223.215.156/tcp/30703/ethv4/16Uiu2HAmQEUFE2YaJohavWtHxPTEFv3sEGJtDqvtGEv78DFoEWQF"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.prod": "enode://b957e51f41e4abab8382e1ea7229e88c6e18f34672694c6eae389eac22dab8655622bbd4a08192c321416b9becffaab11c8e2b7a5d0813b922aa128b82990dab@47.75.222.178:443",
"node-01.do-ams3.eth.prod": "enode://66ba15600cda86009689354c3a77bdf1a97f4f4fb3ab50ffe34dbc904fac561040496828397be18d9744c75881ffc6ac53729ddbd2cdbdadc5f45c400e2622f7@178.128.141.87:443",
"node-01.gc-us-central1-a.eth.prod": "enode://182ed5d658d1a1a4382c9e9f7c9e5d8d9fec9db4c71ae346b9e23e1a589116aeffb3342299bdd00e0ab98dbf804f7b2d8ae564ed18da9f45650b444aed79d509@34.68.132.118:443",
"node-02.ac-cn-hongkong-c.eth.prod": "enode://8bebe73ddf7cf09e77602c7d04c93a73f455b51f24ae0d572917a4792f1dec0bb4c562759b8830cc3615a658d38c1a4a38597a1d7ae3ba35111479fc42d65dec@47.75.85.212:443",
"node-02.do-ams3.eth.prod": "enode://4ea35352702027984a13274f241a56a47854a7fd4b3ba674a596cff917d3c825506431cf149f9f2312a293bb7c2b1cca55db742027090916d01529fe0729643b@134.209.136.79:443",
"node-02.gc-us-central1-a.eth.prod": "enode://fbeddac99d396b91d59f2c63a3cb5fc7e0f8a9f7ce6fe5f2eed5e787a0154161b7173a6a73124a4275ef338b8966dc70a611e9ae2192f0f2340395661fad81c0@34.67.230.193:443",
"node-03.ac-cn-hongkong-c.eth.prod": "enode://ac3948b2c0786ada7d17b80cf869cf59b1909ea3accd45944aae35bf864cc069126da8b82dfef4ddf23f1d6d6b44b1565c4cf81c8b98022253c6aea1a89d3ce2@47.75.88.12:443",
"node-03.do-ams3.eth.prod": "enode://ce559a37a9c344d7109bd4907802dd690008381d51f658c43056ec36ac043338bd92f1ac6043e645b64953b06f27202d679756a9c7cf62fdefa01b2e6ac5098e@134.209.136.123:443",
"node-03.gc-us-central1-a.eth.prod": "enode://c07aa0deea3b7056c5d45a85bca42f0d8d3b1404eeb9577610f386e0a4744a0e7b2845ae328efc4aa4b28075af838b59b5b3985bffddeec0090b3b7669abc1f3@35.226.92.155:443",
"node-04.ac-cn-hongkong-c.eth.prod": "enode://385579fc5b14e04d5b04af7eee835d426d3d40ccf11f99dbd95340405f37cf3bbbf830b3eb8f70924be0c2909790120682c9c3e791646e2d5413e7801545d353@47.244.221.249:443",
"node-04.do-ams3.eth.prod": "enode://4e0a8db9b73403c9339a2077e911851750fc955db1fc1e09f81a4a56725946884dd5e4d11258eac961f9078a393c45bcab78dd0e3bc74e37ce773b3471d2e29c@134.209.136.101:443",
"node-04.gc-us-central1-a.eth.prod": "enode://0624b4a90063923c5cc27d12624b6a49a86dfb3623fcb106801217fdbab95f7617b83fa2468b9ae3de593ff6c1cf556ccf9bc705bfae9cb4625999765127b423@35.222.158.246:443",
"node-05.ac-cn-hongkong-c.eth.prod": "enode://b77bffc29e2592f30180311dd81204ab845e5f78953b5ba0587c6631be9c0862963dea5eb64c90617cf0efd75308e22a42e30bc4eb3cd1bbddbd1da38ff6483e@47.75.10.177:443",
"node-05.do-ams3.eth.prod": "enode://a8bddfa24e1e92a82609b390766faa56cf7a5eef85b22a2b51e79b333c8aaeec84f7b4267e432edd1cf45b63a3ad0fc7d6c3a16f046aa6bc07ebe50e80b63b8c@178.128.141.249:443",
"node-05.gc-us-central1-a.eth.prod": "enode://a5fe9c82ad1ffb16ae60cb5d4ffe746b9de4c5fbf20911992b7dd651b1c08ba17dd2c0b27ee6b03162c52d92f219961cc3eb14286aca8a90b75cf425826c3bd8@104.154.230.58:443",
"node-06.ac-cn-hongkong-c.eth.prod": "enode://cf5f7a7e64e3b306d1bc16073fba45be3344cb6695b0b616ccc2da66ea35b9f35b3b231c6cf335fdfaba523519659a440752fc2e061d1e5bc4ef33864aac2f19@47.75.221.196:443",
"node-06.do-ams3.eth.prod": "enode://887cbd92d95afc2c5f1e227356314a53d3d18855880ac0509e0c0870362aee03939d4074e6ad31365915af41d34320b5094bfcc12a67c381788cd7298d06c875@178.128.141.0:443",
"node-06.gc-us-central1-a.eth.prod": "enode://282e009967f9f132a5c2dd366a76319f0d22d60d0c51f7e99795a1e40f213c2705a2c10e4cc6f3890319f59da1a535b8835ed9b9c4b57c3aad342bf312fd7379@35.223.240.17:443",
"node-07.ac-cn-hongkong-c.eth.prod": "enode://13d63a1f85ccdcbd2fb6861b9bd9d03f94bdba973608951f7c36e5df5114c91de2b8194d71288f24bfd17908c48468e89dd8f0fb8ccc2b2dedae84acdf65f62a@47.244.210.80:443",
"node-07.do-ams3.eth.prod": "enode://2b01955d7e11e29dce07343b456e4e96c081760022d1652b1c4b641eaf320e3747871870fa682e9e9cfb85b819ce94ed2fee1ac458904d54fd0b97d33ba2c4a4@134.209.136.112:443",
"node-07.gc-us-central1-a.eth.prod": "enode://b706a60572634760f18a27dd407b2b3582f7e065110dae10e3998498f1ae3f29ba04db198460d83ed6d2bfb254bb06b29aab3c91415d75d3b869cd0037f3853c@35.239.5.162:443",
"node-08.ac-cn-hongkong-c.eth.prod": "enode://32915c8841faaef21a6b75ab6ed7c2b6f0790eb177ad0f4ea6d731bacc19b938624d220d937ebd95e0f6596b7232bbb672905ee12601747a12ee71a15bfdf31c@47.75.59.11:443",
"node-08.do-ams3.eth.prod": "enode://0d9d65fcd5592df33ed4507ce862b9c748b6dbd1ea3a1deb94e3750052760b4850aa527265bbaf357021d64d5cc53c02b410458e732fafc5b53f257944247760@178.128.141.42:443",
"node-08.gc-us-central1-a.eth.prod": "enode://e87f1d8093d304c3a9d6f1165b85d6b374f1c0cc907d39c0879eb67f0a39d779be7a85cbd52920b6f53a94da43099c58837034afa6a7be4b099bfcd79ad13999@35.238.106.101:443"
}
},
"meta": {
"hostname": "node-01.do-ams3.proxy.misc",
"timestamp": "2021-06-07T00:00:09.836740"
"eth.staging": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.staging": "enode://630b0342ca4e9552f50714b6c8e28d6955bc0fd14e7950f93bc3b2b8cc8c1f3b6d103df66f51a13d773b5db0f130661fb5c7b8fa21c48890c64c79b41a56a490@47.91.229.44:443",
"boot-01.do-ams3.eth.staging": "enode://f79fb3919f72ca560ad0434dcc387abfe41e0666201ebdada8ede0462454a13deb05cda15f287d2c4bd85da81f0eb25d0a486bbbc8df427b971ac51533bd00fe@174.138.107.239:443",
"boot-01.gc-us-central1-a.eth.staging": "enode://10a78c17929a7019ef4aa2249d7302f76ae8a06f40b2dc88b7b31ebff4a623fbb44b4a627acba296c1ced3775d91fbe18463c15097a6a36fdb2c804ff3fc5b35@35.238.97.234:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.staging": "enode://b74859176c9751d314aeeffc26ec9f866a412752e7ddec91b19018a18e7cca8d637cfe2cedcb972f8eb64d816fbd5b4e89c7e8c7fd7df8a1329fa43db80b0bfe@47.52.90.156:443",
"mail-01.do-ams3.eth.staging": "enode://69f72baa7f1722d111a8c9c68c39a31430e9d567695f6108f31ccb6cd8f0adff4991e7fdca8fa770e75bc8a511a87d24690cbc80e008175f40c157d6f6788d48@206.189.240.16:443",
"mail-01.gc-us-central1-a.eth.staging": "enode://e4fc10c1f65c8aed83ac26bc1bfb21a45cc1a8550a58077c8d2de2a0e0cd18e40fd40f7e6f7d02dc6cd06982b014ce88d6e468725ffe2c138e958788d0002a7f@35.239.193.41:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.staging": "/ip4/47.91.229.44/tcp/30703/ethv4/16Uiu2HAmRnt2Eyoknh3auxh4fJwkRgqkH1gqrWGes8Pk1k3MV4xu",
"boot-01.do-ams3.eth.staging": "/ip4/174.138.107.239/tcp/30703/ethv4/16Uiu2HAm8UZXUHEPZrpJbcQ3yVFH6UtKrwsG6jH4ai72PsbLfVFb",
"boot-01.gc-us-central1-a.eth.staging": "/ip4/35.238.97.234/tcp/30703/ethv4/16Uiu2HAm6G9sDMkrB4Xa5EH3Zx2dysCxFgBTSRzghic3Z9tRFRNE"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.staging": "enode://088cf5a93c576fae52f6f075178467b8ff98bacf72f59e88efb16dfba5b30f80a4db78f8e3cb3d87f2f6521746ef4a8768465ef2896c6af24fd77a425e95b6dd@47.52.226.137:443",
"node-01.do-ams3.eth.staging": "enode://914c0b30f27bab30c1dfd31dad7652a46fda9370542aee1b062498b1345ee0913614b8b9e3e84622e84a7203c5858ae1d9819f63aece13ee668e4f6668063989@167.99.19.148:443",
"node-01.gc-us-central1-a.eth.staging": "enode://d3878441652f010326889f28360e69f2d09d06540f934fada0e17b374ce5319de64279aba3c44a5bf807d9967c6d705b3b4c6b03fa70763240e2ee6af01a539e@35.192.0.86:443"
}
},
"eth.test": {
"boot": {
"boot-01.ac-cn-hongkong-c.eth.test": "enode://daae2e72820e86e942fa2a8aa7d6e9954d4043a753483d8bd338e16be82cf962392d5c0e1ae57c3d793c3d3dddd8fd58339262e4234dc966f953cd73b535f5fa@47.52.188.149:443",
"boot-01.do-ams3.eth.test": "enode://9e0988575eb7717c25dea72fd11c7b37767dc09c1a7686f7c2ec577d308d24b377ceb675de4317474a1a870e47882732967f4fa785b02ba95d669b31d464dec0@206.189.243.164:443",
"boot-01.gc-us-central1-a.eth.test": "enode://c1e5018887c863d64e431b69bf617561087825430e4401733f5ba77c70db14236df381fefb0ebe1ac42294b9e261bbe233dbdb83e32c586c66ae26c8de70cb4c@35.188.168.137:443"
},
"mail": {
"mail-01.ac-cn-hongkong-c.eth.test": "enode://619dbb5dda12e85bf0eb5db40fb3de625609043242737c0e975f7dfd659d85dc6d9a84f9461a728c5ab68c072fed38ca6a53917ca24b8e93cc27bdef3a1e79ac@47.52.188.196:443",
"mail-01.do-ams3.eth.test": "enode://e4865fe6c2a9c1a563a6447990d8e9ce672644ae3e08277ce38ec1f1b690eef6320c07a5d60c3b629f5d4494f93d6b86a745a0bf64ab295bbf6579017adc6ed8@206.189.243.161:443",
"mail-01.gc-us-central1-a.eth.test": "enode://707e57453acd3e488c44b9d0e17975371e2f8fb67525eae5baca9b9c8e06c86cde7c794a6c2e36203bf9f56cae8b0e50f3b33c4c2b694a7baeea1754464ce4e3@35.192.229.172:443"
},
"rendezvous": {
"boot-01.ac-cn-hongkong-c.eth.test": "/ip4/47.52.188.149/tcp/30703/ethv4/16Uiu2HAm9Vatqr4GfVCqnyeaPtCF3q8fz8kDDUgqXVfFG7ZfSA7w",
"boot-01.do-ams3.eth.test": "/ip4/206.189.243.164/tcp/30703/ethv4/16Uiu2HAmBCh5bgYr6V3fDuLqUzvtSAsFTQJCQ3TVHT8ta8bTu2Jm",
"boot-01.gc-us-central1-a.eth.test": "/ip4/35.188.168.137/tcp/30703/ethv4/16Uiu2HAm3MUqtGjmetyZ9L4SN2R8oHDWvACUcec25LjtDD5euiRH"
},
"whisper": {
"node-01.ac-cn-hongkong-c.eth.test": "enode://ad38f94030a846cc7005b7a1f3b6b01bf4ef59d34e8d3d6f4d12df23d14ba8656702a435d34cf4df3b412c0c1923df5adcce8461321a0d8ffb9435b26e572c2a@47.52.255.194:443",
"node-01.do-ams3.eth.test": "enode://1d193635e015918fb85bbaf774863d12f65d70c6977506187ef04420d74ec06c9e8f0dcb57ea042f85df87433dab17a1260ed8dde1bdf9d6d5d2de4b7bf8e993@206.189.243.163:443",
"node-01.gc-us-central1-a.eth.test": "enode://f593a27731bc0f8eb088e2d39222c2d59dfb9bf0b3950d7a828d51e8ab9e08fffbd9916a82fd993c1a080c57c2bd70ed6c36f489a969de697aff93088dbee1a9@35.194.31.108:443"
}
},
"status.prod": {
"waku": {
"node-01.ac-cn-hongkong-c.status.prod": "/dns4/node-01.ac-cn-hongkong-c.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkvEZgh3KLwhLwXg95e5ojM8XykJ4Kxi2T7hk22rnA7pJC",
"node-01.do-ams3.status.prod": "/dns4/node-01.do-ams3.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAm6HZZr7aToTvEBPpiys4UxajCTU97zj5v7RNR2gbniy1D",
"node-01.gc-us-central1-a.status.prod": "/dns4/node-01.gc-us-central1-a.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAkwBp8T6G77kQXSNMnxgaMky1JeyML5yqoTHRM8dbeCBNb",
"node-02.ac-cn-hongkong-c.status.prod": "/dns4/node-02.ac-cn-hongkong-c.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmFy8BrJhCEmCYrUfBdSNkrPw6VHExtv4rRp1DSBnCPgx8",
"node-02.do-ams3.status.prod": "/dns4/node-02.do-ams3.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmSve7tR5YZugpskMv2dmJAsMUKmfWYEKRXNUxRaTCnsXV",
"node-02.gc-us-central1-a.status.prod": "/dns4/node-02.gc-us-central1-a.status.prod.statusim.net/tcp/30303/p2p/16Uiu2HAmDQugwDHM3YeUp86iGjrUvbdw3JPRgikC7YoGBsT2ymMg"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.status.prod": "/dns4/node-01.ac-cn-hongkong-c.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvEZgh3KLwhLwXg95e5ojM8XykJ4Kxi2T7hk22rnA7pJC",
"node-01.do-ams3.status.prod": "/dns4/node-01.do-ams3.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm6HZZr7aToTvEBPpiys4UxajCTU97zj5v7RNR2gbniy1D",
"node-01.gc-us-central1-a.status.prod": "/dns4/node-01.gc-us-central1-a.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAkwBp8T6G77kQXSNMnxgaMky1JeyML5yqoTHRM8dbeCBNb",
"node-02.ac-cn-hongkong-c.status.prod": "/dns4/node-02.ac-cn-hongkong-c.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmFy8BrJhCEmCYrUfBdSNkrPw6VHExtv4rRp1DSBnCPgx8",
"node-02.do-ams3.status.prod": "/dns4/node-02.do-ams3.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmSve7tR5YZugpskMv2dmJAsMUKmfWYEKRXNUxRaTCnsXV",
"node-02.gc-us-central1-a.status.prod": "/dns4/node-02.gc-us-central1-a.status.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmDQugwDHM3YeUp86iGjrUvbdw3JPRgikC7YoGBsT2ymMg"
},
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.nodes.status.im"]
},
"status.test": {
"waku": {
"node-01.ac-cn-hongkong-c.status.test": "/dns4/node-01.ac-cn-hongkong-c.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAm2BjXxCp1sYFJQKpLLbPbwd5juxbsYofu3TsS3auvT9Yi",
"node-01.do-ams3.status.test": "/dns4/node-01.do-ams3.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAkukebeXjTQ9QDBeNDWuGfbaSg79wkkhK4vPocLgR6QFDf",
"node-01.gc-us-central1-a.status.test": "/dns4/node-01.gc-us-central1-a.status.test.statusim.net/tcp/30303/p2p/16Uiu2HAmGDX3iAFox93PupVYaHa88kULGqMpJ7AEHGwj3jbMtt76"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.status.test": "/dns4/node-01.ac-cn-hongkong-c.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAm2BjXxCp1sYFJQKpLLbPbwd5juxbsYofu3TsS3auvT9Yi",
"node-01.do-ams3.status.test": "/dns4/node-01.do-ams3.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkukebeXjTQ9QDBeNDWuGfbaSg79wkkhK4vPocLgR6QFDf",
"node-01.gc-us-central1-a.status.test": "/dns4/node-01.gc-us-central1-a.status.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmGDX3iAFox93PupVYaHa88kULGqMpJ7AEHGwj3jbMtt76"
},
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.nodes.status.im"]
},
"wakuv2.prod": {
"waku": {
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/ip4/8.210.222.231/tcp/30303/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
"node-01.do-ams3.wakuv2.prod": "/ip4/188.166.135.145/tcp/30303/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/ip4/34.121.100.108/tcp/30303/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.wakuv2.prod": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAm4v86W3bmT1BiH6oSPzcsSr24iDQpSN5Qa992BCjjwgrD",
"node-01.do-ams3.wakuv2.prod": "/dns4/node-01.do-ams3.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmL5okWopX7NqZWBUKVqW8iUxCEmd5GMHLVPwCgzYzQv3e",
"node-01.gc-us-central1-a.wakuv2.prod": "/dns4/node-01.gc-us-central1-a.wakuv2.prod.statusim.net/tcp/443/wss/p2p/16Uiu2HAmVkKntsECaYfefR1V2yCR79CegLATuTPE6B9TxgxBiiiA"
},
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@prod.waku.nodes.status.im"]
},
"wakuv2.test": {
"waku": {
"node-01.ac-cn-hongkong-c.wakuv2.test": "/ip4/47.242.210.73/tcp/30303/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
"node-01.do-ams3.wakuv2.test": "/ip4/134.209.139.210/tcp/30303/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/ip4/104.154.239.128/tcp/30303/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
},
"waku-websocket": {
"node-01.ac-cn-hongkong-c.wakuv2.test": "/dns4/node-01.ac-cn-hongkong-c.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAkvWiyFsgRhuJEb9JfjYxEkoHLgnUQmr1N5mKWnYjxYRVm",
"node-01.do-ams3.wakuv2.test": "/dns4/node-01.do-ams3.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmPLe7Mzm8TsYUubgCAW1aJoeFScxrLj8ppHFivPo97bUZ",
"node-01.gc-us-central1-a.wakuv2.test": "/dns4/node-01.gc-us-central1-a.wakuv2.test.statusim.net/tcp/443/wss/p2p/16Uiu2HAmJb2e28qLXxT5kZxVUUoJt72EMzNGXB47Rxx5hw3q4YjS"
},
"waku-nodes": ["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.waku.nodes.status.im"]
}
},
"meta": {
"hostname": "node-01.do-ams3.proxy.misc",
"timestamp": "2021-06-07T00:00:09.836740"
}
}
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 706 B

After

Width:  |  Height:  |  Size: 246 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 972 B

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 286 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env sh
CHANGES=$(git diff --no-ext-diff --diff-filter=d --cached --unified=0 --no-prefix --minimal --exit-code src/quo src/quo2 | grep '^+' || echo '')
INVALID_CHANGES=$(echo "$CHANGES" | grep -E '(re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt)')
if test -n "$INVALID_CHANGES"; then
echo "re-frame dispatch/subscribe is not allowed in quo/quo2 components"
echo ''
echo "$INVALID_CHANGES"
exit 1
fi
+3 -3
View File
@@ -38,13 +38,13 @@
:builds {:mobile
{:target :react-native
:output-dir "app"
:init-fn status-im.core/init
:init-fn status-im2.setup.core/init
;; When false, the Shadow-CLJS watcher won't automatically refresh
;; the target files (a.k.a hot reload). When false, you can manually
;; reload by calling `shadow.cljs.devtools.api/watch-compile-all!`.
:devtools {:autobuild #shadow/env ["SHADOW_AUTOBUILD_ENABLED" :default true :as :bool]}
:dev {:devtools {:after-load status-im.reloader/reload
:build-notify status-im.reloader/build-notify
:dev {:devtools {:after-load status-im2.setup.hot-reload/reload
:build-notify status-im2.setup.hot-reload/build-notify
:preloads [re-frisk-remote.preload]}
:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
+66
View File
@@ -0,0 +1,66 @@
(ns i18n.i18n
(:require
["i18n-js" :as i18n]
[clojure.string :as string]
[status-im.goog.i18n :as goog.i18n]))
(defn init [default-device-language translations-by-locale]
(set! (.-fallbacks i18n) true)
(set! (.-defaultSeparator i18n) "/")
(set! (.-locale i18n) default-device-language)
(set! (.-translations i18n) translations-by-locale))
(defn get-translations []
(.-translations i18n))
(defn set-language [lang]
(set! (.-locale i18n) lang))
;;:zh, :zh-hans-xx, :zh-hant-xx have been added until this bug will be fixed https://github.com/fnando/i18n-js/issues/460
(def delimeters
"This function is a hack: mobile Safari doesn't support toLocaleString(), so we need to pass
this map to WKWebView to make number formatting work."
(let [n (.toLocaleString ^js (js/Number 1000.1))
delimiter? (= (count n) 7)]
(if delimiter?
{:delimiter (subs n 1 2)
:separator (subs n 5 6)}
{:delimiter ""
:separator (subs n 4 5)})))
(defn label-number [number]
(when number
(let [{:keys [delimiter separator]} delimeters]
(.toNumber i18n
(string/replace number #"," ".")
(clj->js {:precision 10
:strip_insignificant_zeros true
:delimiter delimiter
:separator separator})))))
(def default-option-value "<no value>")
(defn label-options [options]
;; i18n ignores nil value, leading to misleading messages
(into {} (for [[k v] options] [k (or v default-option-value)])))
(defn label-fn
([path] (label-fn path {}))
([path options]
(if (exists? (.t i18n))
(let [options (update options :amount label-number)]
(.t i18n (name path) (clj->js (label-options options))))
(name path))))
(def label (memoize label-fn))
(defn label-pluralize [count path & options]
(if (exists? (.t i18n))
(.p i18n count (name path) (clj->js options))
(name path)))
(def locale
(.-locale i18n))
(def format-currency goog.i18n/format-currency)
+74 -9
View File
@@ -1,4 +1,4 @@
import { useDerivedValue } from 'react-native-reanimated';
import { useDerivedValue, withTiming, withSequence, withDelay, Easing } from 'react-native-reanimated';
// Generic Worklets
@@ -32,38 +32,103 @@ export function applyAnimationsToStyle(animations, style) {
// Switcher Worklets
export function switcherCloseButtonOpacity (switcherButtonOpacity) {
export function stackOpacity (stackId, selectedStackId) {
return useDerivedValue(
function () {
'worklet'
return 1 - switcherButtonOpacity.value;
return selectedStackId.value == stackId ? 1 : 0;
}
);
}
export function switcherScreenRadius (switcherScreenSize) {
export function stackPointer (stackId, selectedStackId) {
return useDerivedValue(
function () {
'worklet'
return switcherScreenSize.value/2;
return selectedStackId.value == stackId ? "auto" : "none";
}
);
}
export function switcherScreenBottomPosition (switcherScreenRadius, switcherPressedRadius, initalPosition) {
export function bottomTabIconColor (stackId, selectedStackId, homeStackOpen,
passThrough, selectedTabColor, defaultColor,
passThroughColor) {
return useDerivedValue(
function () {
'worklet'
return initalPosition + switcherPressedRadius - switcherScreenRadius.value;
if (selectedStackId.value == stackId && homeStackOpen.value){
return selectedTabColor;
}
else if (passThrough.value){
return passThroughColor;
}
else {
return defaultColor;
}
}
);
}
export function switcherContainerBottomPosition (switcherScreenBottom, heightOffset) {
// Home Stack
const shellAnimationTime = 200;
const defaultDurationAndEasing = {
duration: shellAnimationTime,
easing: Easing.bezier(0, 0, 1, 1),
}
export function homeStackOpacity (homeStackOpen) {
return useDerivedValue(
function () {
'worklet'
return - (switcherScreenBottom.value + heightOffset);
return withTiming(homeStackOpen.value ? 1 : 0, defaultDurationAndEasing);
}
);
}
export function homeStackTop (homeStackOpen, top) {
return useDerivedValue(
function () {
'worklet'
return withTiming(homeStackOpen.value ? 0 : top, defaultDurationAndEasing);
}
);
}
export function homeStackLeft (selectedStackId, animateHomeStackLeft, homeStackOpen, left) {
return useDerivedValue(
function () {
'worklet'
if (animateHomeStackLeft.value) {
var leftValue = left[selectedStackId.value];
if (homeStackOpen.value) {
return withSequence(withTiming(leftValue, {duration: 0}), withTiming(0, defaultDurationAndEasing))
} else {
return withTiming(leftValue, defaultDurationAndEasing);
}
} else {
return 0;
}
}
);
}
export function homeStackPointer (homeStackOpen) {
return useDerivedValue(
function () {
'worklet'
return homeStackOpen.value ? "auto" : "none";
}
);
}
export function homeStackScale (homeStackOpen, minimizeScale) {
return useDerivedValue(
function () {
'worklet'
return withTiming(homeStackOpen.value ? 1 : minimizeScale, defaultDurationAndEasing);
}
);
}
+12 -14
View File
@@ -44,7 +44,7 @@
(+ 50 keyboard-height-android-delta) ;; TODO : remove 50 when react-native-navigation v8 will be implemented https://github.com/wix/react-native-navigation/issues/7225
0))
min-height (+ (* styles/vertical-padding 2) (:bottom safe-area))
max-height (- window-height (:top safe-area) styles/margin-top)
max-height (- window-height (:top safe-area))
visible (react/state false)
master-translation-y (animated/use-value 0)
@@ -202,17 +202,15 @@
:wait-for master-ref
:enabled (and (not disable-drag?)
(not= sheet-height max-height))})
[animated/view {:height sheet-height}
[animated/scroll-view {:bounces false
:flex 1
:scroll-enabled (= sheet-height max-height)}
[animated/view {:style {:padding-top styles/vertical-padding
:padding-bottom (+ styles/vertical-padding
(if (and platform/ios? keyboard-shown)
keyboard-height
(:bottom safe-area)))}
:on-layout #(reset! height (.-nativeEvent.layout.height ^js %))}
(into [:<>]
(react/get-children children))]]]]]])))
[animated/view {:height sheet-height
:flex 1}
[animated/view {:style {:padding-top styles/vertical-padding
:padding-bottom (+ styles/vertical-padding
(if (and platform/ios? keyboard-shown)
keyboard-height
(:bottom safe-area)))}
:on-layout #(reset! height (.-nativeEvent.layout.height ^js %))}
(into [:<>]
(react/get-children children))]]]]])))
(def bottom-sheet (reagent/adapt-react-class (react/memo bottom-sheet-hooks)))
(def bottom-sheet (reagent/adapt-react-class (react/memo bottom-sheet-hooks)))
+2
View File
@@ -56,6 +56,8 @@
{:keyboardVerticalOffset (+ 44 (:status-bar-height @navigation-const))})]
(reagent/children this))))
(def status-bar (.-StatusBar ^js rn))
(def keyboard (.-Keyboard ^js rn))
(def dismiss-keyboard! #(.dismiss ^js keyboard))
+10 -11
View File
@@ -1,11 +1,11 @@
(ns quo2.components.avatars.account-avatar
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[status-im.ui.components.icons.icons :as icons]
[quo.theme :as theme]))
[quo2.components.icon :as icons]
[quo2.theme :as theme]))
(def icon-color-value
{:dark (get-in colors/customization [:dark :purple])
{:dark (get-in colors/customization [:dark :purple])
:light (get-in colors/customization [:light :purple])})
(defn get-border-radius [size]
@@ -28,11 +28,11 @@
[{:keys [size icon]
:or {size 80
icon :main-icons/placeholder}}]
(let [icon-color (if (theme/dark?)
(:dark icon-color-value)
(:light icon-color-value))
(let [icon-color (if (theme/dark?)
(:dark icon-color-value)
(:light icon-color-value))
avatar-border-radius (get-border-radius size)
inner-icon-size (get-inner-icon-sizes size)]
inner-icon-size (get-inner-icon-sizes size)]
[rn/view {:style {:width size
:background-color icon-color
:height size
@@ -40,6 +40,5 @@
:justify-content :center
:align-items :center}}
[icons/icon icon
{:no-color true
:container-style {:width inner-icon-size
:height inner-icon-size}}]]))
{:no-color true
:size inner-icon-size}]]))
@@ -1,9 +1,9 @@
(ns quo2.components.avatars.channel-avatar
(:require [quo2.foundations.colors :as colors]
[quo.react-native :as rn]
[react-native.core :as rn]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo.theme :as theme]))
[quo2.theme :as theme]))
(defn channel-avatar [{:keys [big? locked? emoji-background-color emoji]}]
(let [lock-exists? (some? locked?)
+19 -15
View File
@@ -1,28 +1,32 @@
(ns quo2.components.avatars.group-avatar
(:require [quo2.foundations.colors :as colors]
[quo2.components.icon :as icon]
[quo.react-native :as rn]))
[react-native.core :as rn]))
(def sizes
{:icon {:small 12
:medium 16
:large 20}
:container {:small 20
{:icon {:small 12
:medium 16
:large 20}
:container {:small 20
:medium 32
:large 48}})
:large 48}})
;; TODO: this implementation does not support group display picture (can only display default group icon).
(defn group-avatar [_]
(fn [{:keys [color size override-theme]}]
(let [theme (or override-theme (if (colors/dark?) :dark :light))
container-size (get-in sizes [:container size])
icon-size (get-in sizes [:icon size])]
(fn [{:keys [color size]}]
(let [container-size (get-in sizes [:container size])
icon-size (get-in sizes [:icon size])
;; theme (or override-theme (if (colors/dark?) :dark :light))
]
[rn/view {:width container-size
:height container-size
:align-items :center
:justify-content :center
:border-radius (/ container-size 2)
:background-color (if (= theme :light)
(colors/custom-color color 50)
(colors/custom-color color 60))}
[icon/icon :total-members {:size icon-size
:color colors/white-opa-70}]])))
:background-color color
;; :background-color (if (= theme :light) TODO: colors/custom-color method here is not working for some reason.
;; (colors/custom-color color 50)
;; (colors/custom-color color 60))
}
[icon/icon :i/group {:size icon-size ; TODO: group icon sizes 12 and 20 (small and large) are missing
:color colors/white-opa-70}]])))
+12 -13
View File
@@ -1,29 +1,28 @@
(ns quo2.components.avatars.icon-avatar
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[status-im.ui.components.icons.icons :as icons]))
[quo2.components.icon :as icons]))
(def sizes
{:big 48
{:big 48
:medium 32
:small 20})
:small 20})
(defn icon-avatar
[{:keys [size icon color opacity]
:or {opacity 20}}]
(let [component-size (size sizes)
circle-color (colors/custom-color color 50 opacity)
icon-color (colors/custom-color-by-theme color 50 60)
icon-size (case size
:big 20
:medium 16
:small 12)]
circle-color (colors/custom-color color 50 opacity)
icon-color (colors/custom-color-by-theme color 50 60)
icon-size (case size
:big 20
:medium 16
:small 12)]
[rn/view {:style {:width component-size
:height component-size
:border-radius component-size
:background-color circle-color
:justify-content :center
:align-items :center}}
[icons/icon icon {:container-style {:width icon-size
:height icon-size}
:color icon-color}]]))
[icons/icon icon {:size icon-size
:color icon-color}]]))
+6 -5
View File
@@ -1,10 +1,11 @@
(ns quo2.components.avatars.user-avatar
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[react-native.fast-image :as fast-image]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icons]
[clojure.string :refer [upper-case split blank?]]
[quo.theme :refer [dark?]]))
[quo2.theme :refer [dark?]]
[clojure.string :refer [upper-case split blank?]]))
(def sizes {:big {:outer 80
:inner 72
@@ -131,8 +132,8 @@
:no-color true}])
(if profile-picture
;; display image
[rn/image {:style (container-styling inner-dimensions outer-dimensions)
:source profile-picture}]
[fast-image/fast-image {:source {:uri profile-picture}
:style (container-styling inner-dimensions outer-dimensions)}]
;; else display initials
[container inner-dimensions outer-dimensions
[text/text {:weight :semi-bold
@@ -1,5 +1,5 @@
(ns quo2.components.avatars.wallet-user-avatar
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]
[clojure.string :as clojure-string]))
+12 -2
View File
@@ -1,8 +1,8 @@
(ns quo2.components.buttons.button
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]
[quo.theme :as theme]
[quo2.theme :as theme]
[reagent.core :as reagent]
[quo2.components.icon :as quo2.icons]))
@@ -44,6 +44,11 @@
:background-color {:default colors/danger-50
:pressed colors/danger-60
:disabled colors/danger-50}}
:positive {:icon-color colors/white
:label {:style {:color colors/white}}
:background-color {:default colors/success-50
:pressed colors/success-60
:disabled colors/success-50-opa-30}}
:photo-bg {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label {:style {:color colors/neutral-100}}
@@ -104,6 +109,11 @@
:background-color {:default colors/danger-60
:pressed colors/danger-50
:disabled colors/danger-60}}
:positive {:icon-color colors/white
:label {:style {:color colors/white}}
:background-color {:default colors/success-60
:pressed colors/success-50
:disabled colors/success-60-opa-30}}
:photo-bg {:icon-color colors/white
:icon-secondary-color colors/neutral-30
:label {:style {:color colors/white}}
+18 -16
View File
@@ -1,7 +1,6 @@
(ns quo2.components.buttons.dynamic-button
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[reagent.core :as reagent]
[status-im.i18n.i18n :as i18n]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]))
@@ -23,13 +22,13 @@
(defn- icon-view [type]
[icon/icon
(case type
:jump-to :main-icons2/jump-to
:mention :main-icons2/mention
:notification-down :main-icons2/arrow-down
:notification-up :main-icons2/arrow-up
:search-with-label :main-icons2/search
:search :main-icons2/search
:bottom :main-icons2/arrow-down)
:jump-to :i/jump-to
:mention :i/mention
:notification-down :i/arrow-down
:notification-up :i/arrow-up
:search-with-label :i/search
:search :i/search
:bottom :i/arrow-down)
{:size 12
:color (get-icon-and-text-color type)
:container-style {:margin-top 6
@@ -60,11 +59,14 @@
:customization-color customize jump-to and mention button color}"
[_]
(let [pressed? (reagent/atom false)]
(fn [{:keys [type on-press count customization-color style]}]
[rn/touchable-without-feedback
{:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)
:on-press on-press}
(fn [{:keys [type label on-press count customization-color style]}]
[rn/touchable-opacity
{:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)
:on-press on-press
:active-opacity 1
:style {:padding 5}
:accessibility-label type}
[rn/view {:style (merge
{:flex-direction :row
:height 24
@@ -92,8 +94,8 @@
:notification-up 0
:search-with-label 8)}}
(case type
:jump-to (i18n/label :t/jump-to)
:search-with-label (i18n/label :t/back)
:jump-to label
:search-with-label label
(:mention :notification-down :notification-up) (str count))])
(when (#{:jump-to :notification-down :notification-up} type)
[icon-view type])]])))
+155
View File
@@ -0,0 +1,155 @@
(ns quo2.components.code.snippet
(:require ["react-native" :as react-native]
[cljs-bean.core :as bean]
[clojure.string :as str]
[oops.core :as oops]
[react-native.core :as rn]
[quo2.theme :as theme]
[quo2.components.buttons.button :as button]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[reagent.core :as reagent]
[react-native.linear-gradient :as linear-gradient]
[react-native.masked-view :as masked-view]
[react-native.syntax-highlighter :as highlighter]))
;; Example themes:
;; https://github.com/react-syntax-highlighter/react-syntax-highlighter/tree/master/src/styles/hljs
(def ^:private themes
{:light {:hljs-comment {:color colors/neutral-40},
:hljs-title {:color (colors/custom-color :blue 50)},
:hljs-keyword {:color (colors/custom-color :green 50)},
:hljs-string {:color (colors/custom-color :turquoise 50)},
:hljs-literal {:color (colors/custom-color :turquoise 50)}
:hljs-number {:color (colors/custom-color :turquoise 50)}
:line-number {:color colors/neutral-40}}
:dark {:hljs-comment {:color colors/neutral-60},
:hljs-title {:color (colors/custom-color :blue 60)},
:hljs-keyword {:color (colors/custom-color :green 60)},
:hljs-string {:color (colors/custom-color :turquoise 60)},
:hljs-literal {:color (colors/custom-color :turquoise 60)}
:hljs-number {:color (colors/custom-color :turquoise 60)}
:line-number {:color colors/neutral-40}}})
(defn- text-style [class-names]
(->> class-names
(map keyword)
(reduce #(merge %1 (get-in themes [(theme/get-theme) %2]))
{:flex-shrink 1
;; Round to a nearest whole number to achieve consistent
;; spacing (also important for calculating `max-text-height`).
;; Line height seems to be inconsistent between text being
;; wrapped and text being rendered on a newline using Flexbox
;; layout.
:line-height 18})))
(defn- render-nodes [nodes]
(map (fn [{:keys [children value] :as node}]
;; Node can have :children or a :value.
(if children
(into [text/text {:weight :code
:size :paragraph-2
:style (text-style (get-in node [:properties :className]))}]
(render-nodes children))
;; Remove newlines as we already render each line separately.
(-> value str/trim-newline)))
nodes))
(defn- code-block [{:keys [rows line-number-width]}]
[into [:<>]
(->> rows
(render-nodes)
;; Line numbers
(map-indexed (fn [idx row]
(conj [rn/view {:style {:flex-direction :row}}
[rn/view {:style {:width line-number-width
;; 8+12 margin
:margin-right 20}}
[text/text {:weight :code
:size :paragraph-2
:style (text-style ["line-number"])}
(inc idx)]]]
row))))])
(defn- native-renderer []
(let [text-height (reagent/atom nil)]
(fn [{:keys [rows max-lines on-copy-press]}]
(let [background-color (colors/theme-colors
colors/white
colors/neutral-80-opa-40)
background-color-left (colors/theme-colors
colors/neutral-5
colors/neutral-80)
border-color (colors/theme-colors
colors/neutral-20
colors/neutral-80)
rows (bean/->clj rows)
font-scale (:font-scale (rn/use-window-dimensions))
max-rows (or max-lines (count rows)) ;; Cut down on rows to process.
max-line-digits (-> rows count (min max-rows) str count)
;; ~ 9 is char width, 18 is width used in Figma.
line-number-width (* font-scale (max 18 (* 9 max-line-digits)))
max-text-height (some-> max-lines (* font-scale 18)) ;; 18 is font's line height.
truncated? (and max-text-height (< max-text-height @text-height))
maybe-mask-wrapper (if truncated?
[masked-view/masked-view
{:mask-element
(reagent/as-element
[linear-gradient/linear-gradient {:colors ["black" "transparent"]
:locations [0.75 1]
:style {:flex 1}}])}]
[:<>])]
[rn/view {:style {:overflow :hidden
:padding 8
:background-color background-color
:border-color border-color
:border-width 1
:border-radius 8
;; Hide on intial render to avoid flicker when mask-wrapper is shown.
:opacity (if @text-height 1 0)}}
;; Line number container
[rn/view {:style {:position :absolute
:bottom 0
:top 0
:left 0
:width (+ line-number-width 8 8)
:background-color background-color-left
:border-right-color border-color
:border-right-width 1}}]
(conj maybe-mask-wrapper [rn/view {:max-height max-text-height}
[rn/view {:on-layout (fn [evt]
(let [height (oops/oget evt "nativeEvent.layout.height")]
(reset! text-height height)))}
[code-block {:rows (take max-rows rows)
:line-number-width line-number-width}]]])
;; Copy button
[rn/view {:style {:position :absolute
:bottom 8
:right 8}}
[button/button {:icon true
:type :grey
:size 24
:on-press on-copy-press}
:main-icons/copy]]]))))
(defn- wrap-renderer-fn [f {:keys [max-lines on-copy-press]}]
(fn [^js props]
(reagent/as-element [:f> f {:rows (.-rows props)
:max-lines max-lines
:on-copy-press on-copy-press}])))
(defn snippet [{:keys [language max-lines on-copy-press]} children]
[highlighter/highlighter {:language language
:renderer (wrap-renderer-fn
native-renderer {:max-lines max-lines
:on-copy-press #(when on-copy-press
(on-copy-press children))})
;; Default props to adapt Highlighter for react-native.
:CodeTag react-native/View
:PreTag react-native/View
:show-line-numbers false
:style #js {}
:custom-style #js {:backgroundColor nil}}
children])
@@ -1,45 +1,44 @@
(ns quo2.components.community.community-card-view
(:require
[quo2.components.community.community-view :as community-view]
[status-im.utils.handlers :refer [<sub]]
[status-im.ui.components.react :as react]
[status-im.ui.screens.communities.styles :as styles]
[status-im.ui.screens.communities.icon :as communities.icon]))
[quo2.components.community.style :as style]
[react-native.core :as rn]))
(defn community-card-view-item
[{:keys [name description locked
status tokens cover tags featured] :as community} on-press]
(let [width (* (<sub [:dimensions/window-width]) 0.90)]
[react/touchable-opacity {:on-press on-press}
[react/view {:style (merge (styles/community-card 20)
{:margin-bottom 16}
(if featured
{:margin-right 12
:width width}
{:flex 1
:margin-horizontal 20}))}
[react/view {:style {:height 230
:border-radius 20}
:on-press on-press}
[react/view
{:flex 1}
[react/view (styles/community-cover-container 40)
[react/image
{:source cover
:style
{:flex 1
:border-radius 20}}]]
[react/view (styles/card-view-content-container 12)
[react/view (styles/card-view-chat-icon 48)
[communities.icon/community-icon-redesign community 48]]
(when (= status :gated)
[react/view (styles/permission-tag-styles)
[community-view/permission-tag-container {:locked locked
:status status
:tokens tokens}]])
[community-view/community-title
{:title name
:description description}]
[community-view/community-stats-column :card-view]
[community-view/community-tags tags]]]]]]))
status tokens cover tags featured]} on-press]
[rn/touchable-opacity {:on-press on-press}
[rn/view {:style (merge (style/community-card 20)
{:margin-bottom 16}
(if featured
{:margin-right 12}
{:flex 1
:margin-horizontal 20}))}
[rn/view {:style {:height 230
:border-radius 20}
:on-press on-press}
[rn/view
{:flex 1}
[rn/view (style/community-cover-container 40)
[rn/image
{:source cover
:style
{:flex 1
:border-radius 20}}]]
[rn/view (style/card-view-content-container 12)
[rn/view (style/card-view-chat-icon 48)]
;;TODO new pure component based on quo2 should be implemented without status-im usage
;[communities.icon/community-icon-redesign community 48]]
(when (= status :gated)
[rn/view (style/permission-tag-styles)
[community-view/permission-tag-container {:locked locked
:status status
:tokens tokens}]])
[community-view/community-title
{:title name
:description description}]
[rn/view {:style (style/card-stats-position)}
[community-view/community-stats-column :card-view]]
[rn/view {:style (style/community-tags-position)}
[community-view/community-tags tags]]]]]]])
@@ -3,74 +3,123 @@
[quo2.components.community.community-view :as community-view]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[status-im.communities.core :as communities]
[status-im.utils.handlers :refer [>evt]]
[status-im.ui.components.react :as react]
[status-im.ui.screens.communities.styles :as styles]
[status-im.ui.screens.communities.community :as community]
[status-im.ui.screens.communities.icon :as communities.icon]))
[quo2.components.counter.counter :as counter]
[quo2.components.icon :as icons]
[quo2.components.community.style :as style]
[react-native.fast-image :as fast-image]
[react-native.core :as rn]))
(defn communities-list-view-item [{:keys [id name locked status tokens background-color] :as community}]
[react/view {:style (merge (styles/community-card 16)
{:margin-bottom 12
:margin-horizontal 20})}
[react/view {:style {:height 56
:border-radius 16}
:on-press (fn []
(>evt [::communities/load-category-states id])
(>evt [:dismiss-keyboard])
(>evt [:navigate-to :community {:community-id id}]))
:on-long-press #(>evt [:bottom-sheet/show-sheet
{:content (fn []
[community/community-actions community])}])}
[react/view {:flex 1}
[react/view {:flex-direction :row
:border-radius 16
:padding-horizontal 12
:align-items :center
:padding-vertical 8
:background-color background-color}
[react/view
[communities.icon/community-icon-redesign community 32]]
[react/view {:flex 1
:margin-horizontal 12}
(defn community-icon-view [community-icon]
[rn/view {:width 32
:height 32}
[fast-image/fast-image {:source {:uri community-icon}
:style {:height 32
:border-radius 16
:width 32}}]])
(defn notification-view [{:keys [muted?
unread-messages?
unread-mentions-count]}]
(cond
muted?
[icons/icon :i/muted {:container-style {:align-items :center
:justify-content :center}
:resize-mode :center
:size 20
:color (colors/theme-colors
colors/neutral-40
colors/neutral-50)}]
(pos? unread-mentions-count)
[counter/counter {:type :default} unread-mentions-count]
unread-messages?
[rn/view {:style {:width 8
:height 8
:border-radius 4
:background-color (colors/theme-colors
colors/neutral-40
colors/neutral-60)}}]))
(defn communities-list-view-item [props {:keys [name
locked?
status
muted?
unread-messages?
unread-mentions-count
community-icon
tokens
background-color]}]
[rn/view {:style (merge (style/community-card 16)
{:margin-bottom 12
:margin-horizontal 20})}
[rn/touchable-highlight (merge {:style {:height 56
:border-radius 16}}
props)
[rn/view {:flex 1}
[rn/view {:flex-direction :row
:border-radius 16
:padding-horizontal 12
:align-items :center
:padding-vertical 8
:background-color background-color}
[rn/view]
(when community-icon
[community-icon-view community-icon])
[rn/view {:flex 1
:margin-horizontal 12}
[text/text {:weight :semi-bold
:size :paragraph-1
:accessibility-label :community-name-text
:number-of-lines 1
:ellipsize-mode :tail}
:ellipsize-mode :tail
:style {:color (when muted?
(colors/theme-colors
colors/neutral-40
colors/neutral-60))}}
name]
[community-view/community-stats-column :list-view]]
(when (= status :gated)
[community-view/permission-tag-container {:locked locked
:status status
:tokens tokens}])]]]])
(if (= status :gated)
[community-view/permission-tag-container {:locked? locked?
:tokens tokens}]
[notification-view {:muted? muted?
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]])
(defn communities-membership-list-item [{:keys [id name status tokens locked] :as community}]
[react/view {:margin-bottom 12
:padding-horizontal 8}
[react/touchable-highlight {:underlay-color colors/primary-50-opa-5
:style {:border-radius 12}
:on-press (fn []
(>evt [::communities/load-category-states id])
(>evt [:dismiss-keyboard])
(>evt [:navigate-to :community {:community-id id}]))
:on-long-press #(>evt [:bottom-sheet/show-sheet
{:content (fn []
[community/community-actions community])}])}
[react/view {:flex 1
:padding-vertical 8
:padding-horizontal 12}
[react/view {:flex-direction :row
:border-radius 16
:align-items :center}
[communities.icon/community-icon-redesign community 48]
[react/view {:margin-left 12
:flex 1}
[community-view/community-title {:title name}]]
(when (= status :gated)
[react/view {:justify-content :center
:margin-right 12}
[community-view/permission-tag-container {:locked locked
:status status
:tokens tokens}]])]]]])
(defn communities-membership-list-item [props {:keys [name
muted?
unread-messages?
unread-mentions-count
status
community-icon
tokens
locked?]}]
[rn/view {:margin-bottom 20}
[rn/touchable-highlight (merge {:underlay-color colors/primary-50-opa-5
:style {:border-radius 12}}
props)
[rn/view {:flex 1}
[rn/view {:flex-direction :row
:border-radius 16
:align-items :center}
(when community-icon
[community-icon-view community-icon])
[rn/view {:flex 1
:margin-left 12
:justify-content :center}
[text/text
{:accessibility-label :chat-name-text
:number-of-lines 1
:ellipsize-mode :tail
:weight :semi-bold
:size :paragraph-1}
name]]
[rn/view {:justify-content :center
:margin-right 16}
(if (= status :gated)
[community-view/permission-tag-container {:locked? locked?
:tokens tokens}]
[notification-view {:muted? muted?
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]]])
@@ -4,83 +4,75 @@
[quo2.components.icon :as icons]
[quo2.foundations.colors :as colors]
[quo2.components.tags.permission-tag :as permission]
[quo2.components.tags.tag :as tag]
[status-im.ui.components.react :as react]
[status-im.utils.money :as money]
[status-im.i18n.i18n :as i18n]
[status-im.ui.screens.communities.styles :as styles]))
[quo2.components.tags.tag :as tag]
[quo2.components.community.style :as style]
[react-native.core :as rn]))
(defn format-members [count]
(if (> count 1000000)
(str (money/with-precision (/ count 1000000) 1) (i18n/label :t/M))
(if (and (> count 999) (< count 1000000))
(str (money/with-precision (/ count 1000) 1) (i18n/label :t/K))
count)))
(defn community-stats [{:keys [icon count icon-color]}]
[react/view (styles/stats-count-container)
[react/view {:margin-right 4}
(defn community-stats [{:keys [icon members-count icon-color]}]
[rn/view (style/stats-count-container)
[rn/view {:margin-right 4}
[icons/icon icon {:container-style {:align-items :center
:justify-content :center}
:resize-mode :center
:size 16
:color icon-color}]]
[text/text {:weight :regular
:size :paragraph-1}
(format-members count)]])
:resize-mode :center
:size 16
:color icon-color}]]
[text/text {:weight :regular
:size :paragraph-1}
members-count]])
(defn community-stats-column [type]
(let [icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40)]
[react/view (if (= type :card-view)
(styles/card-stats-container)
(styles/list-stats-container))
[community-stats {:icon :main-icons2/group
:count "629.2K"
(let [icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40)]
[rn/view (if (= type :card-view)
(style/card-stats-container)
(style/list-stats-container))
[community-stats {:icon :i/group
:members-count "629.2K" ;;TODO here should be formatted value, use money/format-members from outside this component
:icon-color icon-color}]
[community-stats {:icon :main-icons2/lightning
:count "112.1K"
[community-stats {:icon :i/lightning
:members-count "112.1K"
:icon-color icon-color}]
[community-stats {:icon :main-icons2/placeholder
:count 4
:icon-color icon-color}]]))
(when (= type :card-view)
[community-stats {:icon :i/placeholder
:count 4
:icon-color icon-color}])]))
(defn community-tags [tags]
[react/view (styles/community-tags-container)
[rn/view (style/community-tags-container)
(for [{:keys [id tag-label resource]} tags]
^{:key id}
[react/view {:margin-right 8}
[rn/view {:margin-right 8}
[tag/tag
{:id id
:size 24
:label tag-label
:type :emoji
:labelled true
:resource resource}]])])
{:id id
:size 24
:label tag-label
:type :emoji
:labelled true
:resource resource}]])])
(defn community-title [{:keys [title description size] :or {size :small}}]
[react/view (styles/community-title-description-container (if (= size :large) 56 32))
[rn/view (style/community-title-description-container (if (= size :large) 56 32))
(when title
[text/text
{:accessibility-label :chat-name-text
:number-of-lines 1
:ellipsize-mode :tail
:weight :semi-bold
:size (if (= size :large) :heading-1 :heading-2)}
:size (if (= size :large) :heading-1 :heading-2)}
title])
(when description
[text/text
{:accessibility-label :community-description-text
:number-of-lines 2
:ellipsize-mode :tail
:weight :regular
:size :paragraph-1
:style {:margin-top (if (= size :large) 8 2)}}
:weight :regular
:size :paragraph-1
:style {:margin-top (if (= size :large) 8 2)}}
description])])
(defn permission-tag-container [{:keys [locked tokens]}]
(defn permission-tag-container [{:keys [locked? tokens]}]
[permission/tag {:background-color (colors/theme-colors
colors/neutral-10
colors/neutral-80)
:locked locked
:locked? locked?
:tokens tokens
:size 24}])
:size 24}])
@@ -0,0 +1,94 @@
(ns quo2.components.community.discover-card
(:require [quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.community.style :as style]
[react-native.core :as rn]))
;; Discover card placeholders images.
;; TODO replaced when real data is available
(def images
{:images [{:id 1 :column-images [{:id 1 :image ""}]}
{:id 2 :column-images [{}]}]})
(defn card-title-and-description [title description]
[rn/view
{:flex 1
:padding-top 8
:padding-bottom 8
:border-radius 12}
[rn/view {:flex 1
:padding-horizontal 12}
[text/text {:accessibility-label :community-name-text
:ellipsize-mode :tail
:number-of-lines 1
:weight :semi-bold
:size :paragraph-1}
title]
[text/text {:accessibility-label :community-name-text
:ellipsize-mode :tail
:number-of-lines 1
:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)
:weight :regular
:size :paragraph-2}
description]]])
(defn placeholder-list-images [{:keys [images width height border-radius]}]
[rn/view
[rn/view {:justify-content :center}
(for [{:keys [id]} images]
^{:key id}
[rn/view {:border-radius border-radius
:margin-top 4
:margin-right 4
:width width
:height height
:background-color colors/neutral-10}])]])
(defn placeholder-row-images [{:keys [first-image last-image images width height
border-radius]}]
[rn/view
(when first-image
[rn/view {:border-bottom-right-radius 6
:border-bottom-left-radius 6
:margin-right 4
:width width
:height height
:background-color colors/neutral-10}])
(when images
[placeholder-list-images {:images images
:width 32
:height 32
:border-radius 6}])
(when last-image
[rn/view {:border-top-left-radius border-radius
:border-top-right-radius 6
:margin-top 4
:width width
:height height
:background-color colors/neutral-10}])])
(defn discover-card [{:keys [title description on-press accessibility-label]}]
(let [on-joined-images (get images :images)]
[rn/touchable-without-feedback
{:on-press on-press
:accessibility-label accessibility-label}
[rn/view (merge (style/community-card 16)
{:background-color (colors/theme-colors
colors/white
colors/neutral-90)}
{:flex-direction :row
:margin-horizontal 20
:height 56
:padding-right 12})
[card-title-and-description title description]
(for [{:keys [id column-images]} on-joined-images]
^{:key id}
[placeholder-row-images {:images (when (= id 1)
column-images)
:width 32
:height (if (= id 1) 8 26)
:border-radius 6
:first-image "" ; TODO replace with real data
:last-image ""}])]])) ; TODO replace with real data
@@ -1,6 +1,5 @@
(ns status-im.ui.screens.communities.styles
(:require
[quo2.foundations.colors :as colors]))
(ns quo2.components.community.style
(:require [quo2.foundations.colors :as colors]))
(def category-item
{:flex 1
@@ -28,16 +27,26 @@
:margin-right 16})
(defn card-stats-container []
{:flex-direction :row
:margin-top 12})
{:flex-direction :row})
(defn list-stats-container []
{:flex-direction :row
:align-items :center})
(defn community-tags-container []
{:flex-direction :row
:margin-top 16})
{:flex-direction :row})
(defn card-stats-position []
{:position :absolute
:top 116
:right 12
:left 12})
(defn community-tags-position []
{:position :absolute
:top 154
:right 12
:left 12})
(defn card-view-content-container [padding-horizontal]
{:flex 1
+2 -2
View File
@@ -1,6 +1,6 @@
(ns quo2.components.counter.counter
(:require [quo.theme :as theme]
[quo.react-native :as rn]
(:require [quo2.theme :as theme]
[react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))
@@ -1,8 +1,8 @@
(ns quo2.components.dividers.divider-label
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as markdown.text]
[status-im.ui.components.icons.icons :as icons]
[quo2.foundations.colors :as colors]))
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icons]))
(def chevron-icon-container-width 20)
@@ -42,8 +42,7 @@
[icons/icon
:main-icons/chevron-down
{:color text-and-icon-color
:width chevron-icon-container-width
:height chevron-icon-container-height}])
:size chevron-icon-container-width}])
(when (pos? counter-value)
[rn/view {:style {:border-radius 6
:height 16
@@ -1,18 +1,16 @@
(ns quo2.components.dividers.new-messages
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.react :as react]))
[react-native.linear-gradient :as linear-gradient]))
(defn new-messages
"new-messages params - label, color"
[{:keys [label color] :or {label (i18n/label :new-messages-header)
color :primary}}]
[{:keys [label color] :or {color :primary}}]
(let [bg-color (colors/custom-color-by-theme color 50 60 5 5)
text-color (colors/custom-color-by-theme color 50 60)]
[react/linear-gradient {:colors [bg-color "rgba(0,0,0,0)"]
:start {:x 0 :y 0} :end {:x 0 :y 1}}
[linear-gradient/linear-gradient {:colors [bg-color "rgba(0,0,0,0)"]
:start {:x 0 :y 0} :end {:x 0 :y 1}}
[rn/view {:style {:padding-left 60
:padding-vertical 12
:padding-right 24}}
+57 -51
View File
@@ -1,68 +1,74 @@
(ns quo2.components.drawers.action-drawers
(:require [status-im.ui.components.react :as react]
[quo.react-native :as rn]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]))
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]))
(defn- get-icon-color [section]
(if (= section :bottom)
(defn- get-icon-color [danger?]
(if danger?
(colors/theme-colors colors/danger-50 colors/danger-60)
(colors/theme-colors colors/neutral-50 colors/neutral-40)))
(defn action [section]
(fn [{:keys [icon label sub-label right-icon on-press]}]
(defn action [{:keys [icon
label
sub-label
right-icon
danger?
on-press] :as action-props}]
(when action-props
[rn/touchable-opacity {:on-press on-press}
[react/view {:style
{:flex 1
:height (if sub-label 56 47)
:margin-horizontal 20
:flex-direction :row}}
[react/view {:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:margin-right 12
:width 20}}
[rn/view {:style
{:height (if sub-label 56 47)
:margin-horizontal 20
:flex-direction :row}}
[rn/view {:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:margin-right 12
:width 20}}
[icon/icon icon
{:color (get-icon-color section)
:size 20}]]
[react/view
{:color (get-icon-color danger?)
:size 20}]]
[rn/view
{:style
{:flex 1
{:flex 1
:justify-content :center}}
[text/text
{:size :paragraph-1
{:size :paragraph-1
:weight :medium
:style
{:color (when (= section :bottom)
(colors/theme-colors colors/danger-50 colors/danger-60))}}
:style {:color
(when danger?
(colors/theme-colors colors/danger-50 colors/danger-60))}}
label]
(when sub-label [text/text
{:size :paragraph-2
:style
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
sub-label])]
(when sub-label
[text/text
{:size :paragraph-2
:style {:color
(colors/theme-colors colors/neutral-50 colors/neutral-40)}}
sub-label])]
(when right-icon
[react/view {:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:width 20}}
[rn/view {:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:width 20}}
[icon/icon right-icon
{:color (get-icon-color section)
:size 20}]])]]))
{:color (get-icon-color danger?)
:size 20}]])]]))
(defn action-drawer [{:keys [actions actions-with-consequence]}]
(defn divider []
[rn/view {:style {:border-top-width 1
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-80)
:margin-top 8
:margin-bottom 7
:align-items :center
:flex-direction :row}}])
(defn action-drawer [sections]
[:<> {:style
{:flex 1}}
(map (action :top) actions)
(when actions-with-consequence
[:<>
[rn/view {:style {:border-top-width 1
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-80)
:margin-top 8
:margin-bottom 7
:align-items :center
:flex-direction :row}}]
(map (action :bottom) actions-with-consequence)])])
(interpose
[divider]
(for [actions sections]
(map action actions)))])
+2 -2
View File
@@ -1,9 +1,9 @@
(ns quo2.components.dropdowns.dropdown
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.reanimated :as reanimated]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]))
(defn apply-anim [dd-height val]
+13 -14
View File
@@ -1,11 +1,10 @@
(ns quo2.components.header
(:require [oops.core :refer [oget]]
[quo.animated :as animated]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.button :as button]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.react-native :as rn]
[react-native.core :as rn]
[reagent.core :as reagent]))
(def header-height 56)
@@ -61,15 +60,14 @@
:right (max (:width left) (:width right))})))
(def header-actions-style
(merge
{:flex 1
:flex-direction :row
:align-items :center
:justify-content :center}
(:x-tiny spacing/padding-horizontal)))
{:flex 1
:flex-direction :row
:align-items :center
:justify-content :center
:padding-horizontal 4})
(def header-action-placeholder
{:width (:base spacing/spacing)})
{:width 16})
(def element {:align-items :center
:justify-content :center
@@ -140,14 +138,15 @@
(fn [{:keys [left-accessories left-component border-bottom
right-accessories right-component insets get-layout
title subtitle title-component style title-align
background]
background header-style]
:or {title-align :center
border-bottom false}}]
(let [status-bar-height (get insets :top 0)
height (+ header-height status-bar-height)]
[animated/view {:style (header-wrapper-style {:height height
:background background
:border-bottom border-bottom})}
[reanimated/view {:style (header-wrapper-style {:height height
:background background
:header-style header-style
:border-bottom border-bottom})}
[rn/view {:pointer-events :box-none
:height status-bar-height}]
[rn/view {:style (merge {:height header-height}
+3 -3
View File
@@ -1,8 +1,8 @@
(ns quo2.components.icon
(:require
[quo2.components.icons.icons :as icons]
[status-im.ui.components.react :as react]
[clojure.string :as string]
[react-native.core :as rn]
[quo2.components.icons.icons :as icons]
[quo2.foundations.colors :as colors]))
(defn memo-icon-fn
@@ -12,7 +12,7 @@
:or {accessibility-label :icon}}]
(let [size (or size 20)]
^{:key icon-name}
[react/image
[rn/image
{:style
(merge {:width size
:height size}
+2 -2
View File
@@ -1,6 +1,6 @@
(ns quo2.components.info.info-message
(:require [quo.theme :as theme]
[quo.react-native :as rn]
(:require [quo2.theme :as theme]
[react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as quo2.icons]))
@@ -1,6 +1,6 @@
(ns quo2.components.info.information-box
(:require [quo.theme :as theme]
[quo.react-native :as rn]
(:require [quo2.theme :as theme]
[react-native.core :as rn]
[clojure.string :as string]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as quo2.icons]
@@ -78,10 +78,10 @@
[rn/touchable-opacity
{:on-press on-close
:accessibility-label (str (or id "information-box") "-close-button")}
[quo2.icons/icon :main-icons2/close {:size 12
:color (get-color :close-button)
:container-style {:margin-top 4
:margin-left 8}}]])]
[quo2.icons/icon :i/close {:size 12
:color (get-color :close-button)
:container-style {:margin-top 4
:margin-left 8}}]])]
(when include-button?
[quo2.button/button {:type :primary
:size 24
+13 -15
View File
@@ -1,15 +1,15 @@
(ns quo2.components.list-items.channel
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.counter.counter :as quo2.counter]
[quo2.components.icon :as quo2.icons]
[quo2.components.avatars.channel-avatar :as channel-avatar]
[quo2.components.markdown.text :as quo2.text]
[quo.theme :as theme]))
[quo2.theme :as theme]))
(defn list-item [{:keys [name locked? mentions-count unread-messages?
muted? is-active-channel? emoji channel-color]
:or {channel-color colors/primary-50}}]
:or {channel-color colors/primary-50}}]
[rn/view {:style (merge {:height 48
:display :flex
:border-radius 12
@@ -21,26 +21,24 @@
:padding-right 12}
(when is-active-channel?
{:background-color (colors/theme-alpha channel-color 0.05 0.05)}))}
[rn/view {:display :flex
:flex-direction :row
[rn/view {:display :flex
:flex-direction :row
:justify-content :flex-start
:align-items :center}
:align-items :center}
[channel-avatar/channel-avatar
{:big? true
:locked? locked?
:locked? locked?
:emoji-background-color (colors/theme-alpha channel-color 0.1 0.1)
:emoji emoji}]
[quo2.text/text
{:style (merge {:margin-left 12}
(when
(and (not locked?)
muted?)
{:color (if (theme/dark?) colors/neutral-60 colors/neutral-40)}))
{:style (merge {:margin-left 12}
(when (and (not locked?) muted?)
{:color (if (theme/dark?) colors/neutral-60 colors/neutral-40)}))
:weight :medium :size :paragraph-1} (str "# " name)]]
[rn/view {:style {:height 20}}
(when (and (not locked?)
muted?)
[quo2.icons/icon :main-icons2/muted
[quo2.icons/icon :i/muted
{:size 20
:no-color true}])
(when (and (not locked?)
@@ -53,6 +51,6 @@
(not muted?)
(not (pos? (int mentions-count)))
unread-messages?)
[quo2.icons/icon :main-icons2/channel-notification
[quo2.icons/icon :i/channel-notification
{:size 20
:no-color true}])]])
:no-color true}])]])
+15
View File
@@ -0,0 +1,15 @@
(ns quo2.components.list-items.index
(:require [quo.react-native :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))
(defn index [{:keys [title]}]
[rn/view
[rn/view {:style {:border-top-width 1
:border-color (colors/theme-colors colors/neutral-10 colors/neutral-80)
:padding-vertical 8
:padding-horizontal 16}}
[text/text {:weight :medium
:size :paragraph-2
:secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40)}
title]]])
@@ -0,0 +1,276 @@
(ns quo2.components.list-items.list-item
(:require [quo.react-native :as rn]
[quo.platform :as platform]
[quo.haptic :as haptic]
[quo.gesture-handler :as gh]
[quo.design-system.spacing :as spacing]
[quo.design-system.colors :as quo.colors]
[quo.components.controls.view :as controls]
[quo.components.tooltip :as tooltip]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as quo2.icons]
[quo.components.animated.pressable :as animated]))
(defn themes [theme]
(case theme
:main {:icon-color (:icon-04 @quo.colors/theme)
:icon-bg-color (:interactive-02 @quo.colors/theme)
:active-background (:interactive-02 @quo.colors/theme)
:passive-background (:ui-background @quo.colors/theme)
:text-color (:text-01 @quo.colors/theme)}
:accent {:icon-color (:icon-04 @quo.colors/theme)
:icon-bg-color (:interactive-02 @quo.colors/theme)
:active-background (:interactive-02 @quo.colors/theme)
:passive-background (:ui-background @quo.colors/theme)
:text-color (:text-04 @quo.colors/theme)}
:negative {:icon-color (:negative-01 @quo.colors/theme)
:icon-bg-color (:negative-02 @quo.colors/theme)
:active-background (:negative-02 @quo.colors/theme)
:passive-background (:ui-background @quo.colors/theme)
:text-color (:negative-01 @quo.colors/theme)}
:positive {:icon-color (:positive-01 @quo.colors/theme)
:icon-bg-color (:positive-02 @quo.colors/theme)
:active-background (:positive-02 @quo.colors/theme)
:passive-background (:ui-background @quo.colors/theme)
:text-color (:positive-01 @quo.colors/theme)}
:disabled {:icon-color (:icon-02 @quo.colors/theme)
:icon-bg-color (:ui-01 @quo.colors/theme)
:active-background (:ui-01 @quo.colors/theme)
:passive-background (:ui-background @quo.colors/theme)
:text-color (:text-02 @quo.colors/theme)}))
(defn size->icon-size [size]
(case size
:small 36
40))
(defn size->container-size [size]
(case size
:small 52
64))
(defn size->single-title-size [size]
(case size
:small :paragraph-1
:paragraph-1))
(defn container [{:keys [size container-style container-padding-horizontal container-padding-vertical]} & children]
(into [rn/view {:style (merge (or container-padding-horizontal (:tiny spacing/padding-horizontal))
{:min-height (size->container-size size)
:padding-vertical (or container-padding-vertical 8)
:flex-direction :row
:align-items :center
:justify-content :space-between} container-style)}]
children))
(defn icon-column
[{:keys [icon icon-bg-color icon-color size icon-container-style]}]
(when icon
(let [icon-size (size->icon-size size)]
[rn/view {:style (or icon-container-style (:tiny spacing/padding-horizontal))}
(cond
(vector? icon)
icon
(keyword? icon)
[rn/view {:style {:width icon-size
:height icon-size
:align-items :center
:justify-content :center
:border-radius (/ icon-size 2)
:background-color icon-bg-color}}
(quo2.icons/icon icon {:color icon-color})])])))
(defn title-column
[{:keys [title text-color subtitle subtitle-max-lines subtitle-secondary
title-accessibility-label size text-size title-text-weight
right-side-present? title-column-style]}]
[rn/view {:style (or title-column-style
(merge (:tiny spacing/padding-horizontal)
;; make left-side title grow if nothing is present on right-side
(when-not right-side-present?
{:flex 1
:justify-content :center})))}
(cond
(and title subtitle)
[:<>
;; FIXME(Ferossgp): ReactNative 63 will support view inside text on andrid, remove thess if when migrating
(if (string? title)
[text/text {:weight (or title-text-weight :medium)
:style {:color text-color}
:accessibility-label title-accessibility-label
:ellipsize-mode :tail
:number-of-lines 1
:size text-size}
title]
title)
(if (string? subtitle-secondary)
[rn/view {:flex-direction :row}
[text/text {:style {:max-width "56.5%"}
:weight :regular
:color :secondary
:ellipsize-mode :tail
:secondary-color colors/neutral-50
:number-of-lines subtitle-max-lines
:size text-size}
subtitle]
[text/text {:style {:width "7%" :text-align :center}
:weight :regular
:color :secondary
:ellipsize-mode :middle
:secondary-color colors/neutral-50
:number-of-lines subtitle-max-lines
:size text-size}
"•"]
[text/text {:style {:max-width "36.5%"}
:weight :regular
:color :secondary
:ellipsize-mode :middle
:secondary-color colors/neutral-50
:number-of-lines subtitle-max-lines
:size text-size}
subtitle-secondary]]
(if (string? subtitle)
[text/text {:weight :regular
:color :secondary
:ellipsize-mode :tail
:secondary-color colors/neutral-50
:number-of-lines subtitle-max-lines
:size text-size}
subtitle]
subtitle))]
title
(if (string? title)
[text/text {:weight (or title-text-weight :regular)
:number-of-lines 1
:style {:color text-color}
:title-accessibility-label title-accessibility-label
:ellipsize-mode :tail
:size (or text-size (size->single-title-size size))}
title]
title))])
(defn left-side [props]
[rn/view {:style {:flex-direction :row
;; Occupy only content width, never grow, but shrink if need be
:flex-grow 0
:flex-shrink 1
:padding-right 16
:align-items (or (:left-side-alignment props) :center)}}
[icon-column props]
[title-column props]])
(defn right-side [{:keys [chevron active disabled accessory accessory-text accessory-style animated-accessory?]}]
(when (or chevron accessory)
[rn/view {:style (merge {:align-items :center
:justify-content :flex-end
:flex-direction :row
;; Grow to occupy full space, shrink when need be, but always maitaining 16px left gutter
:flex-grow 1
:flex-shrink 0
:margin-left 16
;; When the left-side leaves no room for right-side, the rendered element is pushed out. A flex-basis ensures that there is some room reserved.
;; The number 80px was determined by trial and error.
:flex-basis 80}
accessory-style)}
[rn/view {:style (:tiny spacing/padding-horizontal)}
(case accessory
:radio [controls/radio {:value active :disabled disabled}]
:checkbox [(if animated-accessory?
controls/animated-checkbox
controls/checkbox)
{:value active :disabled disabled}]
:switch [controls/switch {:value active :disabled disabled}]
:text [text/text {:color :secondary
:ellipsize-mode :middle
:number-of-lines 1}
accessory-text]
accessory)]
(when (and chevron platform/ios?)
[rn/view {:style {:padding-right (:tiny spacing/spacing)}}
(quo2.icons/icon :main-icons/next {:container-style {:opacity 0.4
:align-items :center
:justify-content :center}
:resize-mode :center
:color (:icon-02 @quo.colors/theme)})])]))
(defn list-item
[{:keys [theme accessory disabled subtitle-max-lines icon icon-container-style
left-side-alignment icon-color icon-bg-color title-column-style
title subtitle subtitle-secondary active on-press on-long-press chevron size text-size
accessory-text accessibility-label title-accessibility-label accessory-style
haptic-feedback text-color active-background passive-background haptic-type error animated animated-accessory? title-text-weight container-style
active-background-enabled background-color container-padding-horizontal container-padding-vertical]
:or {subtitle-max-lines 1
theme :main
haptic-feedback true
animated platform/ios?
active-background-enabled true
haptic-type :selection}}]
(let [theme (if disabled :disabled theme)
icon-color (or icon-color (:icon-color (themes theme)))
icon-bg-color (or icon-bg-color (:icon-bg-color (themes theme)))
optional-haptic (fn []
(when haptic-feedback
(haptic/trigger haptic-type)))
component (cond
(and (not on-press)
(not on-long-press))
rn/view
animated animated/pressable
:else gh/touchable-highlight)]
[rn/view {:background-color (cond (not= background-color nil)
background-color
(and (= accessory :radio) active)
active-background
:else
passive-background)}
[component
(merge {:type :list-item
:disabled disabled
:bg-color (when active-background-enabled active-background)
:accessibility-label accessibility-label}
(when on-press
{:on-press (fn []
(optional-haptic)
(on-press))})
(when on-long-press
{:on-long-press (fn []
(optional-haptic)
(on-long-press))}))
[container {:size size :container-style container-style :container-padding-vertical container-padding-vertical :container-padding-horizontal container-padding-horizontal}
[left-side {:icon-color icon-color
:text-color (if on-press
text-color
(:text-color (themes :main)))
:left-side-alignment left-side-alignment
:icon-bg-color icon-bg-color
:title-accessibility-label title-accessibility-label
:icon icon
:icon-container-style icon-container-style
:title title
:title-text-weight title-text-weight
:size size
:text-size text-size
:subtitle subtitle
:subtitle-max-lines subtitle-max-lines
:subtitle-secondary subtitle-secondary
:right-side-present? (or accessory chevron)
:title-column-style title-column-style}]
[right-side {:chevron chevron
:active active
:disabled disabled
:on-press on-press
:accessory-text accessory-text
:animated-accessory? animated-accessory?
:accessory-style accessory-style
:accessory accessory}]]]
(when error
[tooltip/tooltip (merge {:bottom-value 0}
(when accessibility-label
{:accessibility-label (str (name accessibility-label) "-error")}))
[text/text {:color :negative
:size :small}
error]])]))
@@ -1,5 +1,5 @@
(ns quo2.components.list-items.menu-item
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors :refer [theme-colors]]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icons]))
@@ -1,9 +1,9 @@
(ns quo2.components.list-items.preview-list
(:require [quo.react-native :as rn]
[status-im.i18n.i18n :as i18n]
(:require [react-native.core :as rn]
[react-native.hole-view :as hole-view]
[react-native.fast-image :as fast-image]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as quo2.icons]
[status-im.ui.components.fast-image :as fast-image]
[quo2.components.avatars.user-avatar :as user-avatar]
[quo2.components.markdown.text :as quo2.text]))
@@ -42,13 +42,13 @@
(defn list-item [index type size item list-size margin-left
hole-size hole-radius hole-x hole-y border-radius]
(let [last-item? (= index (- list-size 1))]
[rn/hole-view {:style {:margin-left (if (= index 0) 0 margin-left)}
:holes (if last-item? []
[{:x hole-x
:y hole-y
:width hole-size
:height hole-size
:borderRadius hole-radius}])}
[hole-view/hole-view {:style {:margin-left (if (= index 0) 0 margin-left)}
:holes (if last-item? []
[{:x hole-x
:y hole-y
:width hole-size
:height hole-size
:borderRadius hole-radius}])}
[avatar item type size border-radius]]))
(defn get-overflow-color [transparent? transparent-color light-color dark-color override-theme]
@@ -56,7 +56,7 @@
transparent-color
(colors/theme-colors light-color dark-color override-theme)))
(defn overflow-label [label size transparent? border-radius margin-left override-theme]
(defn overflow-label [label size transparent? border-radius margin-left override-theme more-than-99-label]
[rn/view {:style {:width size
:height size
:margin-left margin-left
@@ -70,13 +70,13 @@
colors/neutral-70
override-theme)}}
(if (= size 16)
[quo2.icons/icon :main-icons2/more {:size 12
:color (get-overflow-color
transparent?
colors/white-opa-70
colors/neutral-50
colors/neutral-40
override-theme)}]
[quo2.icons/icon :i/more {:size 12
:color (get-overflow-color
transparent?
colors/white-opa-70
colors/neutral-50
colors/neutral-40
override-theme)}]
[quo2.text/text {:size (if (= size 32) :paragraph-2 :label)
:weight :medium
:style {:color (get-overflow-color
@@ -89,7 +89,7 @@
;; If overflow label is below 100, show label as +label (ex. +30), else just show 99+
(if (< label 100)
(str "+" label)
(i18n/label :counter-99-plus))])])
more-than-99-label)])])
(defn border-type [type]
(case type
@@ -105,7 +105,7 @@
:transparent? overflow-label transparent?}
items preview list items (only 4 items is required for preview)
"
[{:keys [type size list-size transparent? override-theme]} items]
[{:keys [type size list-size transparent? override-theme more-than-99-label]} items]
(let [items-arr (into [] items)
list-size (or list-size (count items))
margin-left (get-in params [size :margin-left])
@@ -120,4 +120,4 @@
[list-item index type size (get items-arr index) list-size
margin-left hole-size hole-radius hole-x hole-y border-radius])
(when (> list-size 4)
[overflow-label (- list-size 3) size transparent? border-radius margin-left override-theme])]))
[overflow-label (- list-size 3) size transparent? border-radius margin-left override-theme more-than-99-label])]))
+5 -4
View File
@@ -1,17 +1,17 @@
(ns quo2.components.markdown.text
(:require [quo.react-native :as rn]
[quo.theme :as theme]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.foundations.typography :as typography]
[reagent.core :as reagent]))
(defn text-style [{:keys [size align weight style]}]
(defn text-style [{:keys [size align weight style secondary-color]}]
(merge (case (or weight :regular)
:regular typography/font-regular
:medium typography/font-medium
:semi-bold typography/font-semi-bold
:bold typography/font-bold
:monospace typography/monospace
:code typography/code
:inherit nil)
(case (or size :paragraph-1)
:label typography/label
@@ -23,7 +23,8 @@
{:text-align (or align :auto)}
(if (:color style)
style
(assoc style :color (if (= (theme/get-theme) :dark) colors/white colors/neutral-100)))))
(assoc style :color (or secondary-color
(colors/theme-colors colors/neutral-100 colors/white))))))
(defn text []
(let [this (reagent/current-component)
@@ -0,0 +1,270 @@
(ns quo2.components.markdown.text-input
(:require [clojure.spec.alpha :as s]
[reagent.core :as reagent]
[oops.core :refer [ocall]]
[quo.react-native :as rn]
;; TODO(Ferossgp): Move icon component to lib
[status-im.ui.components.icons.icons :as icons]
[quo.components.tooltip :as tooltip]
[quo.platform :as platform]
[quo.design-system.typography :as typography]
[quo.design-system.spacing :as spacing]
[quo.design-system.colors :as colors]
[quo.components.text :as text]))
;; NOTE(Ferossgp): Refactor with hooks when available
;; We track all currently mounted text input refs
;; in a ref-to-defaultValue map
;; so that we can clear them (restore their default values)
;; when global react-navigation's onWillBlur event is invoked
(defonce text-input-refs (atom {}))
(s/def ::multiline boolean?)
(s/def ::secure-text-entry boolean?)
(s/def ::show-cancel boolean?)
(s/def ::label (s/nilable (s/or :string string? :component vector?)))
(s/def ::cancel-label (s/nilable string?))
(s/def ::default-value (s/nilable string?))
(s/def ::placeholder (s/nilable string?))
(s/def ::keyboard-type (s/nilable (s/or :string string? :keyword keyword?))) ; TODO: make set
(s/def ::accessibility-label (s/nilable (s/or :string string? :keyword keyword?)))
(s/def ::on-focus fn?)
(s/def ::on-blur fn?)
(s/def ::on-press fn?)
(s/def ::accessory (s/keys :opt-un [::on-press
::icon
::component]))
(s/def ::after (s/nilable ::accessory))
(s/def ::before (s/nilable ::accessory))
(s/def ::style (s/nilable map?))
(s/def ::input-style ::style)
(s/def ::container-style ::style)
(s/def ::text-input (s/keys :opt-un
[::label
::multiline
::error
::style
::input-style
::keyboard-type
::before
::after
::cancel-label
::on-focus
::on-blur
::container-style
::show-cancel
::accessibility-label
::bottom-value
::secure-text-entry]))
(defn check-spec [spec prop]
(if (s/valid? spec prop)
true
(do
(s/explain spec prop)
false)))
(def height 44) ; 22 line-height + 11*2 vertical padding
(def multiline-height 88) ; 3 * 22 three line-height + 11* vertical padding
(defn label-style []
{:margin-bottom (:tiny spacing/spacing)})
(defn text-input-row-style []
{:flex-direction :row
:align-items :center})
(defn text-input-view-style [style]
(merge {:border-radius 8
:flex-direction :row
:flex 1
:align-items :center
:background-color (:ui-01 @colors/theme)}
style))
(defn text-input-style [multiline input-style monospace before after]
(merge (if monospace
typography/monospace
typography/font-regular)
{:padding-top 11
:padding-bottom 11
:font-size 15
:margin 0
:text-align-vertical :center
:flex 1
:color (:text-01 @colors/theme)
:height height}
(when-not before
{:padding-left (:base spacing/spacing)})
(when-not after
{:padding-right (:base spacing/spacing)})
(when multiline
{:text-align-vertical :top
:line-height 22
:height multiline-height})
input-style))
(defn cancel-style []
{:margin-left (:tiny spacing/spacing)
:padding-left (:tiny spacing/spacing)
:justify-content :center
:align-self :stretch})
(defn accessory-style []
(merge (:base spacing/padding-horizontal)
{:flex 1
:justify-content :center}))
(defn accessory-element [{:keys [icon component icon-opts style accessibility-label on-press]}]
(let [el (if on-press
rn/touchable-opacity
rn/view)]
[el (merge {:style {:align-self :stretch}}
(when on-press
{:on-press on-press}))
[rn/view (merge {:style (merge (accessory-style)
style)}
(when accessibility-label
{:accessibility-label accessibility-label}))
(cond
icon
[icons/icon icon (merge {:color (:icon-01 @colors/theme)}
icon-opts)]
component
component
:else
nil)]]))
(defn text-input-raw []
(let [focused (reagent/atom nil)
visible (reagent/atom false)
ref (atom nil)
blur (fn []
(some-> @ref (ocall "blur")))]
(fn [{:keys [label multiline error style input-style keyboard-type before after
cancel-label on-focus on-blur show-cancel accessibility-label
bottom-value secure-text-entry container-style get-ref on-cancel
monospace auto-complete-type auto-correct]
:or {cancel-label "Cancel"}
:as props}]
{:pre [(check-spec ::text-input props)]}
(let [show-cancel (if (nil? show-cancel)
;; Enabled by default on iOs and disabled on Android
platform/ios?
show-cancel)
after (cond
(and secure-text-entry @visible)
{:icon :main-icons/hide
:on-press #(reset! visible false)}
(and secure-text-entry (not @visible))
{:icon :main-icons/show
:on-press #(reset! visible true)}
:else after)
secure (boolean (and secure-text-entry (not @visible))) ; must be a boolean to work on iOS
auto-complete (cond
(= keyboard-type :visible-password)
:off
secure-text-entry
:password
:else
auto-complete-type)
auto-correct (and (not= keyboard-type :visible-password) (not secure-text-entry) auto-correct)
on-cancel (fn []
(when on-cancel
(on-cancel))
(blur))
keyboard-type (cond
(and platform/ios? (= keyboard-type :visible-password))
:default
; the correct approach on Android would be keep secure-text-entry on set keyboard type
; to visible-password. But until https://github.com/facebook/react-native/issues/27946
; is solved that's the second best way.
(and platform/android? secure-text-entry)
:default
:else
keyboard-type)]
[rn/view {:style container-style}
(when label
[text/text {:style (label-style)}
label])
[rn/view {:style (text-input-row-style)}
[rn/view {:style (text-input-view-style style)
:important-for-accessibility (if secure-text-entry
:no-hide-descendants
:auto)}
(when before
[accessory-element before])
[rn/text-input
(merge {:style (text-input-style multiline input-style monospace before after)
:ref (fn [r]
(reset! ref r)
(when get-ref (get-ref r)))
:placeholder-text-color (:text-02 @colors/theme)
:underline-color-android :transparent
:auto-capitalize :none
:secure-text-entry secure
:auto-correct auto-correct
:auto-complete-type auto-complete
:on-focus (fn [evt]
(when on-focus (on-focus evt))
(when show-cancel
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets)))
(reset! focused true))
:on-blur (fn [evt]
(when on-blur (on-blur evt))
(when show-cancel
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets)))
(reset! focused false))
:keyboard-type keyboard-type}
(when (and platform/ios? (not after))
{:clear-button-mode :while-editing})
(dissoc props
:style :keyboard-type :on-focus :on-blur
:secure-text-entry :ref :get-ref :auto-correct :auto-complete-type))]
(when after
[accessory-element after])]
(when (and show-cancel
(not multiline)
@focused)
[rn/touchable-opacity {:style (cancel-style)
:on-press on-cancel}
[text/text {:color :link} cancel-label]])
(when error
[tooltip/tooltip (merge {:bottom-value (if bottom-value bottom-value 0)}
(when accessibility-label
{:accessibility-label (str (name accessibility-label) "-error")}))
[text/text {:color :negative
:align :center
:size :small}
error]])]]))))
;; TODO(Ferossgp): Refactor me when hooks available
(defn text-input [{:keys [preserve-input?]
:as props}]
(if preserve-input?
[text-input-raw props]
(let [id (random-uuid)]
(reagent/create-class
{:component-will-unmount
(fn []
(swap! text-input-refs dissoc id))
:reagent-render
(fn [{:keys [get-ref default-value]
:as props}]
[text-input-raw (merge props
{:get-ref (fn [r]
;; Store input and its defaultValue
;; one we receive a non-nil ref
(when r
(swap! text-input-refs assoc id {:ref r :value default-value}))
(when get-ref (get-ref r)))})])}))))
+12 -17
View File
@@ -1,15 +1,12 @@
(ns quo2.components.messages.gap
(:require
[oops.core :refer [oget]]
[quo.react-native :as rn]
[quo.theme :as theme]
[react-native.core :as rn]
[quo2.theme :as theme]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[reagent.core :as reagent]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.react :refer [pressable-class]]
[status-im.utils.handlers :refer [>evt]]))
[reagent.core :as reagent]))
;;; helpers
(def themes
@@ -84,7 +81,7 @@
:color (get-color :time)}} str])
(defn info-button [on-press]
[pressable-class
[rn/touchable-without-feedback
{:on-press on-press}
[icon/icon "message-gap-info" {:size 12 :no-color true :container-style {:padding 4}}]])
@@ -99,7 +96,7 @@
[rn/image {:style {:flex 1} :source (get-image :circles) :resize-mode :repeat}]
[circle]])
(defn body [timestamp-far timestamp-near chat-id gap-ids on-info-button-pressed]
(defn body [timestamp-far timestamp-near on-info-button-pressed on-press warning-label]
[rn/view {:flex 1}
[rn/view
{:flex-direction :row
@@ -109,12 +106,10 @@
[timestamp timestamp-far]
(when on-info-button-pressed [info-button on-info-button-pressed])]
[pressable-class
[rn/touchable-without-feedback
{:style {:flex 1 :margin-top 16 :margin-bottom 20}
:on-press #(when (and chat-id gap-ids)
(>evt [:chat.ui/fill-gaps chat-id gap-ids]))}
[text/text
(i18n/label :messages-gap-warning)]]
:on-press #(when on-press (on-press))}
[text/text warning-label]]
[timestamp timestamp-near]])
@@ -124,10 +119,10 @@
if `on-info-button-pressed` fn is provided, the info button will show up and is pressable"
[{:keys [timestamp-far
timestamp-near
gap-ids
chat-id
on-info-button-pressed
style]}]
style
on-press
warning-label]}]
(let [body-height (reagent/atom nil)]
(fn []
[rn/view
@@ -145,6 +140,6 @@
style)
[timeline]
[body timestamp-far timestamp-near chat-id gap-ids on-info-button-pressed]]
[body timestamp-far timestamp-near on-info-button-pressed on-press warning-label]]
[vborder :left body-height]
[vborder :right body-height]])))
@@ -1,13 +1,12 @@
(ns quo2.components.messages.system-message
(:require [quo.react-native :as rn]
[quo.theme :as theme]
(:require [react-native.core :as rn]
[react-native.reanimated :as reanimated]
[quo2.theme :as theme]
[quo2.components.avatars.icon-avatar :as icon-avatar]
[quo2.components.avatars.user-avatar :as user-avatar]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.reanimated :as ra]
[status-im.i18n.i18n :as i18n]
[status-im.utils.core :as utils]))
[utils :as utils]))
(def themes-landed {:pinned colors/primary-50-opa-5
:added colors/primary-50-opa-5
@@ -54,7 +53,7 @@
(defmulti sm-render :type)
(defmethod sm-render :deleted [{:keys [label timestamp-str]}]
(defmethod sm-render :deleted [{:keys [label timestamp-str labels]}]
[rn/view {:align-items :center
:justify-content :space-between
:flex 1
@@ -67,10 +66,10 @@
[text/text {:size :paragraph-2
:style {:color (get-color :text)
:margin-right 5}}
(i18n/label (or label :message-deleted))]
(or label (:message-deleted labels))]
[sm-timestamp timestamp-str]]])
(defmethod sm-render :added [{:keys [state mentions timestamp-str]}]
(defmethod sm-render :added [{:keys [state mentions timestamp-str labels]}]
[rn/view {:align-items :center
:flex-direction :row}
[sm-icon {:icon :main-icons/add-user16
@@ -84,14 +83,14 @@
:style {:color (get-color :text)
:margin-left 3
:margin-right 3}}
(i18n/label :added)]
(:added labels)]
[sm-user-avatar (:image (second mentions))]
[text/text {:weight :semi-bold
:size :paragraph-2}
(:name (second mentions))]
[sm-timestamp timestamp-str]])
(defmethod sm-render :pinned [{:keys [state pinned-by content timestamp-str]}]
(defmethod sm-render :pinned [{:keys [state pinned-by content timestamp-str labels]}]
[rn/view {:flex-direction :row
:flex 1
:align-items :center}
@@ -110,7 +109,7 @@
:margin-right 2}
[text/text {:size :paragraph-2
:style {:color (get-color :text)}}
(i18n/label :pinned-a-message)]]
(:pinned-a-message labels)]]
[sm-timestamp timestamp-str]]
[rn/view {:flex-direction :row}
[rn/view {:flex-direction :row
@@ -137,19 +136,19 @@
(utils/truncate-str (:info content) 24)])]]]])
(defn system-message
[{:keys [type style non-pressable? animate-landing?] :as message}]
[{:keys [type style non-pressable? animate-landing? labels] :as message}]
[:f>
(fn []
(let [sv-color (ra/use-shared-value
(let [sv-color (reanimated/use-shared-value
(get-color :bg (if animate-landing? :landed :default) type))]
(when animate-landing?
(ra/animate-shared-value-with-delay
(reanimated/animate-shared-value-with-delay
sv-color (get-color :bg :default type) 0 :linear 1000))
[ra/touchable-opacity
[reanimated/touchable-opacity
{:on-press #(when-not non-pressable?
(ra/set-shared-value
(reanimated/set-shared-value
sv-color (get-color :bg :pressed type)))
:style (ra/apply-animations-to-style
:style (reanimated/apply-animations-to-style
{:background-color sv-color}
(merge
{:flex-direction :row
@@ -159,4 +158,4 @@
:padding-horizontal 11
:background-color sv-color}
style))}
[sm-render message]]))])
[sm-render message labels]]))])
@@ -1,71 +1,78 @@
(ns quo2.components.navigation.bottom-nav-tab
(:require [quo.react-native :as rn]
[reagent.core :as reagent]
(:require [react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.hole-view :as hole-view]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icon]
[quo2.components.icons.icons :as icons]
[quo2.components.counter.counter :as counter]))
(defn toggle-background-color [background-color press-out? pass-through?]
(let [color (cond
press-out? nil
pass-through? colors/white-opa-5
:else colors/neutral-70)]
(reset! background-color color)))
(reanimated/set-shared-value
background-color
(cond
press-out? "transparent"
pass-through? colors/white-opa-5
:else colors/neutral-70)))
(defn bottom-nav-tab
"[bottom-nav-tab opts]
opts
{:icon :main-icons2/communities
:selected? true/false
{:icon :i/communities
:new-notifications? true/false
:notification-indicator :unread-dot/:counter
:counter-label number
:on-press bottom-tab on-press function
:pass-through? true/false
:icon-color-anim reanimated shared value
"
[_]
(let [background-color (reagent/atom nil)]
(fn [{:keys [icon selected? new-notifications? notification-indicator counter-label on-press pass-through?]}]
[rn/touchable-without-feedback
{:on-press on-press
:on-press-in #(toggle-background-color background-color false pass-through?)
:on-press-out #(toggle-background-color background-color true pass-through?)}
[rn/view {:style {:width 90
:height 40
:background-color @background-color
:border-radius 10}}
[rn/hole-view {:style {:padding-left 33
:padding-top 8}
:key new-notifications? ;; Key is required to force removal of holes
:holes (cond
(not new-notifications?) ;; No new notifications, remove holes
[]
[{:keys [icon new-notifications? notification-indicator counter-label
on-press pass-through? icon-color-anim accessibility-label]}]
[:f>
(fn []
(let [icon-animated-style (reanimated/apply-animations-to-style
{:tint-color icon-color-anim}
{:width 24
:height 24})
background-color (reanimated/use-shared-value "transparent")
background-animated-style (reanimated/apply-animations-to-style
{:background-color background-color}
{:width 90
:height 40
:border-radius 10})]
[rn/touchable-without-feedback
{:on-press on-press
:on-press-in #(toggle-background-color background-color false pass-through?)
:on-press-out #(toggle-background-color background-color true pass-through?)
:accessibility-label accessibility-label}
[reanimated/view {:style background-animated-style}
[hole-view/hole-view {:style {:padding-left 33
:padding-top 8}
:key new-notifications? ;; Key is required to force removal of holes
:holes (cond
(not new-notifications?) ;; No new notifications, remove holes
[]
(= notification-indicator :unread-dot)
[{:x 50 :y 5 :width 10 :height 10 :borderRadius 5}]
(= notification-indicator :unread-dot)
[{:x 50 :y 5 :width 10 :height 10 :borderRadius 5}]
:else
[{:x 47 :y 1 :width 18 :height 18 :borderRadius 7}])}
[icon/icon
icon
{:size 24
:color (cond
selected? colors/white
pass-through? colors/white-opa-40
:else colors/neutral-50)}]]
(when new-notifications?
(if (= notification-indicator :counter)
[counter/counter {:outline false
:override-text-color colors/white
:override-bg-color colors/primary-50
:style {:position :absolute
:left 48
:top 2}}
counter-label]
[rn/view {:style {:width 8
:height 8
:border-radius 4
:top 6
:left 51
:position :absolute
:background-color colors/primary-50}}]))]])))
:else
[{:x 47 :y 1 :width 18 :height 18 :borderRadius 7}])}
[reanimated/image
{:style icon-animated-style
:source (icons/icon-source (keyword (str icon 24)))}]]
(when new-notifications?
(if (= notification-indicator :counter)
[counter/counter {:outline false
:override-text-color colors/white
:override-bg-color colors/primary-50
:style {:position :absolute
:left 48
:top 2}}
counter-label]
[rn/view {:style {:width 8
:height 8
:border-radius 4
:top 6
:left 51
:position :absolute
:background-color colors/primary-50}}]))]]))])
@@ -1,11 +1,13 @@
(ns quo2.components.navigation.floating-shell-button
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.dynamic-button :as dynamic-button]))
(defn dynamic-button-view [type dynamic-buttons style]
(when-let [{:keys [count on-press customization-color]} (get dynamic-buttons type)]
(when-let [{:keys [count on-press customization-color label]} (get dynamic-buttons type)]
[dynamic-button/dynamic-button
{:type type
:label label
:on-press on-press
:count count
:style style
@@ -15,21 +17,28 @@
"[floating-shell-button dynamic-buttons style]
dynamic-buttons
{:button-type {:on-press on-press :count count}}"
[dynamic-buttons style]
[rn/view {:style (merge {:flex-direction :row
:margin-horizontal 12} style)}
;; Left Section
[rn/view {:style {:flex 1}}
[dynamic-button-view :search dynamic-buttons {:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[rn/view {:style {:flex 1}}
[rn/view {:style {:position :absolute
:flex-direction :row
:right 0}}
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
[dynamic-button-view :bottom dynamic-buttons {:margin-left 8}]]]])
[dynamic-buttons style opacity-anim pointer-anim]
[:f>
(fn []
(let [original-style (merge {:flex-direction :row
:margin-horizontal 12} style)
animated-style (reanimated/apply-animations-to-style
{:opacity opacity-anim
:pointer-events pointer-anim}
original-style)]
[reanimated/view {:style animated-style}
;; Left Section
[rn/view {:style {:flex 1}}
[dynamic-button-view :search dynamic-buttons {:position :absolute
:right 8}]]
;; Mid Section (jump-to)
[dynamic-button-view :jump-to dynamic-buttons nil]
;; Right Section
[rn/view {:style {:flex 1}}
[rn/view {:style {:position :absolute
:flex-direction :row
:right 0}}
[dynamic-button-view :mention dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-down dynamic-buttons {:margin-left 8}]
[dynamic-button-view :notification-up dynamic-buttons {:margin-left 8}]
[dynamic-button-view :bottom dynamic-buttons {:margin-left 8}]]]]))])
+10 -15
View File
@@ -1,10 +1,9 @@
(ns quo2.components.navigation.page-nav
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icons]
[status-im.utils.dimensions :as dimensions]
[clojure.string :as string]
[quo2.components.markdown.text :as text]))
[quo2.components.markdown.text :as text]
[clojure.string :as string]))
(def ^:private centrify-style
{:display :flex
@@ -185,8 +184,7 @@
mid-section
left-section
right-section-buttons]}]
(let [{:keys [height width]} (dimensions/window)
put-middle-section-on-left? (or align-mid?
(let [put-middle-section-on-left? (or align-mid?
(> (count right-section-buttons) 1))
mid-section-props
{:type (:type mid-section)
@@ -197,15 +195,12 @@
:right-icon (:right-icon mid-section)
:icon (:icon mid-section)
:left-icon (:left-icon mid-section)}]
[rn/view {:style (cond->
{:display :flex
:flex-direction :row
:width width
:height (* 0.0497 height)
;; iPhone 11 Pro's height in Figma divided by Component height 56/1125
:align-items :center
:padding-horizontal 20
:justify-content :space-between}
[rn/view {:style (cond-> {:display :flex
:flex-direction :row
;; iPhone 11 Pro's height in Figma divided by Component height 56/1125
:align-items :center
:padding-horizontal 20
:justify-content :space-between}
page-nav-background-uri (assoc :background-color page-nav-color)
page-nav-color (assoc :background page-nav-background-uri))}
[rn/view {:style {:flex 1
+16 -16
View File
@@ -1,9 +1,10 @@
(ns quo2.components.navigation.top-nav
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.counter.counter :as counter]
[quo2.components.buttons.button :as quo2.button]
[quo2.components.avatars.user-avatar :as user-avatar]))
[quo2.components.avatars.user-avatar :as user-avatar]
[react-native.hole-view :as hole-view]))
(defn- get-button-common-props [type]
(let [default? (= type :default)
@@ -44,8 +45,7 @@
open-scanner show-qr open-activity-center style avatar counter-label]}]
(let [button-common-props (get-button-common-props type)]
[rn/view {:style (merge
{:height 56
:flex 1}
{:height 56}
style)}
;; Left Section
[rn/touchable-without-feedback {:on-press open-profile}
@@ -63,22 +63,22 @@
:right 20
:top 12
:flex-direction :row}}
[base-button :main-icons2/search open-search :open-search-button button-common-props]
[base-button :main-icons2/scan open-scanner :open-scanner-button button-common-props]
[base-button :main-icons2/qr-code show-qr :show-qr-button button-common-props]
[base-button :i/search open-search :open-search-button button-common-props]
[base-button :i/scan open-scanner :open-scanner-button button-common-props]
[base-button :i/qr-code show-qr :show-qr-button button-common-props]
[rn/view ;; Keep view instead of "[:<>" to make sure relative
;; position is calculated from this view instead of its parent
[rn/hole-view {:key new-notifications? ;; Key is required to force removal of holes
:holes (cond
(not new-notifications?) ;; No new notifications, remove holes
[]
[hole-view/hole-view {:key new-notifications? ;; Key is required to force removal of holes
:holes (cond
(not new-notifications?) ;; No new notifications, remove holes
[]
(= notification-indicator :unread-dot)
[{:x 37 :y -3 :width 10 :height 10 :borderRadius 5}]
(= notification-indicator :unread-dot)
[{:x 37 :y -3 :width 10 :height 10 :borderRadius 5}]
:else
[{:x 33 :y -7 :width 18 :height 18 :borderRadius 7}])}
[base-button :main-icons2/activity-center open-activity-center
:else
[{:x 33 :y -7 :width 18 :height 18 :borderRadius 7}])}
[base-button :i/activity-center open-activity-center
:open-activity-center-button button-common-props]]
(when new-notifications?
(if (= notification-indicator :counter)
@@ -1,5 +1,5 @@
(ns quo2.components.notifications.activity-logs
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.components.buttons.button :as button]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
@@ -0,0 +1,15 @@
(ns quo2.components.notifications.info-count
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.foundations.typography :as typography]))
(defn info-count [count style]
(when (> count 0)
[rn/view {:style (merge {:width 16
:height 16
:position :absolute
:right 22
:border-radius 6
:background-color (colors/theme-colors colors/primary-50 colors/primary-60)}
style)}
[rn/text {:style (merge typography/font-medium typography/label {:color colors/white :text-align :center})} count]]))
@@ -0,0 +1,12 @@
(ns quo2.components.notifications.notification-dot
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]))
(defn notification-dot [style]
[rn/view {:style (merge {:background-color (colors/theme-colors colors/primary-50 colors/primary-60)
:width 8
:height 8
:border-radius 4
:position :absolute
:z-index 1}
style)}])
+31 -25
View File
@@ -1,7 +1,7 @@
(ns quo2.components.reactions.reaction
(:require [quo2.components.markdown.text :as quo2.text]
[quo.react-native :as rn]
[quo.theme :as theme]
[react-native.core :as rn]
[quo2.theme :as theme]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icons]))
@@ -16,15 +16,17 @@
(defn open-reactions-menu
[{:keys [on-press]}]
(let [dark? (theme/dark?)]
[rn/touchable-opacity {:on-press on-press
:style (merge reaction-styling
[rn/touchable-opacity
{:on-press on-press
:accessibility-label :emoji-reaction-add
:style (merge reaction-styling
{:padding-horizontal 9
:border-width 1
:margin-top 5
:border-color (if dark?
colors/neutral-70
colors/neutral-30)})}
[icons/icon :main-icons2/add
:border-width 1
:margin-top 5
:border-color (if dark?
colors/neutral-70
colors/neutral-30)})}
[icons/icon :i/add
{:size 20
:color (if dark?
colors/white
@@ -32,26 +34,30 @@
(defn reaction
"Add your emoji as a param here"
[{:keys [emoji clicks neutral? on-press]}]
[{:keys [emoji clicks neutral? on-press accessibility-label]}]
(let [dark? (theme/dark?)
text-color (if dark? colors/white
colors/neutral-100)
numeric-value (int clicks)
clicks-positive? (pos? numeric-value)]
[rn/touchable-opacity {:on-press on-press
:style (merge reaction-styling
(cond-> {:background-color
(if dark?
(if neutral?
colors/neutral-70
:transparent)
(if neutral?
colors/neutral-30
:transparent))}
(and dark? (not neutral?)) (assoc :border-color colors/neutral-70
:border-width 1)
(and (not dark?) (not neutral?)) (assoc :border-color colors/neutral-30
:border-width 1)))}
[rn/touchable-opacity
{:on-press on-press
:accessibility-label accessibility-label
:style (merge reaction-styling
(cond-> {:background-color
(if dark?
(if neutral?
colors/neutral-70
:transparent)
(if neutral?
colors/neutral-30
:transparent))}
(and dark? (not neutral?))
(assoc :border-color colors/neutral-70
:border-width 1)
(and (not dark?) (not neutral?))
(assoc :border-color colors/neutral-30
:border-width 1)))}
[icons/icon emoji {:no-color true
:size 16}]
[quo2.text/text {:size :paragraph-2
@@ -1,5 +1,5 @@
(ns quo2.components.selectors.disclaimer
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]
[quo2.components.selectors.selectors :as selectors]))
+47 -28
View File
@@ -1,14 +1,19 @@
(ns quo2.components.selectors.selectors
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo.theme :as theme]
[reagent.core :as reagent]
[quo2.components.icon :as icons]))
(defn- get-color [checked? disabled?]
(if checked?
(defn- get-color [checked? disabled? blurred-background?]
(cond
checked?
(colors/custom-color-by-theme
:primary 50 60 (when disabled? 30) (when disabled? 30))
blurred-background?
(colors/theme-colors
(colors/alpha colors/neutral-80 (if disabled? 0.05 0.1))
(colors/alpha colors/white (if disabled? 0.05 0.1)))
:else
(colors/theme-colors
(colors/alpha colors/neutral-20 (if disabled? 0.4 1))
(colors/alpha colors/neutral-70 (if disabled? 0.3 1)))))
@@ -21,7 +26,7 @@
(defn checkbox-prefill [{:keys [default-checked?]}]
(let [checked? (reagent/atom (or default-checked? false))]
(fn [{:keys [on-change disabled? container-style]}]
(fn [{:keys [on-change disabled? blurred-background? container-style]}]
[rn/touchable-without-feedback
{:on-press (handle-press disabled? on-change checked?)}
[rn/view
@@ -30,16 +35,20 @@
{:height 21
:width 21
:border-radius 6
:background-color (colors/theme-colors
(colors/alpha colors/neutral-20 (if disabled? 0.3 1))
(colors/alpha colors/neutral-70 (if disabled? 0.3 1)))})
:background-color (if blurred-background?
(colors/theme-colors
(colors/alpha colors/neutral-80 (if disabled? 0.05 0.1))
(colors/alpha colors/white (if disabled? 0.05 0.1)))
(colors/theme-colors
(colors/alpha colors/neutral-20 (if disabled? 0.3 1))
(colors/alpha colors/neutral-70 (if disabled? 0.3 1))))})
:accessibility-label (str "checkbox-" (if @checked? "on" "off"))
:accessibility-role :checkbox}
(when @checked?
[rn/view {:style
{:height 20
:width 20}}
[icons/icon :main-icons2/check
[icons/icon :i/check-small
{:size 20
:color (colors/theme-colors
(colors/alpha colors/neutral-100 (if disabled? 0.3 1))
@@ -47,38 +56,44 @@
(defn checkbox [{:keys [default-checked?]}]
(let [checked? (reagent/atom (or default-checked? false))]
(fn [{:keys [on-change disabled? container-style]}]
(fn [{:keys [on-change disabled? blurred-background? container-style]}]
[rn/touchable-without-feedback
{:on-press (handle-press disabled? on-change checked?)}
[rn/view
{:style (merge
container-style
{:height 21
:width 21})}
{:height 20
:width 20})}
[rn/view
{:style {:flex 1
:border-radius 6
:border-width (if @checked? 0 1)
:background-color (if @checked?
(get-color @checked? disabled?)
:background-color (cond
@checked?
(get-color @checked? disabled? blurred-background?)
blurred-background?
(colors/theme-colors
colors/white-opa-5
colors/white-opa-10)
:else
(colors/theme-colors
colors/white
colors/neutral-80-opa-40))
:border-color (if @checked? :none
(get-color @checked? disabled?))}
(get-color @checked? disabled? blurred-background?))}
:accessibility-label (str "checkbox-" (if @checked? "on" "off"))
:accessibility-role :checkbox}
(when @checked?
[rn/view {:style
{:height 20
:width 20}}
[icons/icon :main-icons2/check
[icons/icon :i/check-small
{:size 20
:color (colors/alpha colors/white (if disabled? 0.3 1))}]])]]])))
:color colors/white}]])]]])))
(defn radio [{:keys [default-checked?]}]
(let [checked? (reagent/atom (or default-checked? false))]
(fn [{:keys [on-change disabled? container-style]}]
(fn [{:keys [on-change disabled? blurred-background? container-style]}]
[rn/touchable-without-feedback
{:on-press (handle-press disabled? on-change checked?)}
[rn/view
@@ -88,9 +103,10 @@
:width 20
:border-radius 20
:border-width 1
:border-color (get-color @checked? disabled?)
:background-color (colors/theme-colors colors/white
(colors/alpha colors/neutral-80 0.4))})
:border-color (get-color @checked? disabled? blurred-background?)
:background-color (when-not blurred-background?
(colors/theme-colors colors/white
(colors/alpha colors/neutral-80 0.4)))})
:accessibility-label (str "radio-" (if @checked? "on" "off"))
:accessibility-role :checkbox}
@@ -98,7 +114,7 @@
{:margin-left :auto
:height 14
:width 14
:background-color (when @checked? (get-color @checked? disabled?))
:background-color (when @checked? (get-color @checked? disabled? blurred-background?))
:border-radius 20
:margin-right :auto
:margin-top :auto
@@ -106,7 +122,7 @@
(defn toggle [{:keys [default-checked?]}]
(let [checked? (reagent/atom (or default-checked? false))]
(fn [{:keys [on-change disabled? container-style]}]
(fn [{:keys [on-change disabled? blurred-background? container-style]}]
[rn/touchable-without-feedback
{:on-press (handle-press disabled? on-change checked?)}
[rn/view
@@ -115,17 +131,20 @@
{:height 20
:width 30
:border-radius 20
:background-color (get-color @checked? disabled?)})
:background-color (get-color @checked? disabled? blurred-background?)})
:accessibility-label (str "toggle-" (if @checked? "on" "off"))
:accessibility-role :checkbox}
[rn/view {:style
{:margin-left (if @checked? 12 2)
:height 16
:width 16
:background-color (colors/alpha colors/white
(if (theme/dark?)
(if disabled? 0.3 1)
1))
:background-color (if blurred-background?
(colors/theme-colors
(colors/alpha colors/white (if disabled? 0.4 1))
(colors/alpha colors/white (if disabled? 0.3 1)))
(colors/theme-colors
(colors/alpha colors/white 1)
(colors/alpha colors/white (if disabled? 0.4 1))))
:border-radius 20
:margin-right :auto
:margin-top :auto
+3 -3
View File
@@ -1,14 +1,14 @@
(ns quo2.components.separator
(:require [quo.react-native :as react]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as quo2.colors]))
(defn separator [{:keys [style]}]
[react/view
[rn/view
{:style
(merge
style
{:background-color (quo2.colors/theme-colors
quo2.colors/neutral-30
quo2.colors/neutral-10
quo2.colors/neutral-80)
:align-self :stretch
:height 1})}])
@@ -1,7 +1,7 @@
(ns quo2.components.tabs.account-selector
(:require
[quo.theme :as theme]
[quo.react-native :as rn]
[quo2.theme :as theme]
[react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as quo2]))
+2 -2
View File
@@ -1,9 +1,9 @@
(ns quo2.components.tabs.segmented-tab
(:require [reagent.core :as reagent]
[quo.react-native :as rn]
[react-native.core :as rn]
[quo2.components.tabs.tab :as tab]
[quo2.foundations.colors :as colors]
[quo.theme :as theme]))
[quo2.theme :as theme]))
(def themes {:light {:background-color colors/neutral-20}
:dark {:background-color colors/neutral-80}})
+4 -4
View File
@@ -1,9 +1,9 @@
(ns quo2.components.tabs.tab
(:require [quo2.foundations.colors :as colors]
[quo.react-native :as rn]
[quo.theme :as theme]
[status-im.ui.components.icons.icons :as icons]
[quo2.components.markdown.text :as text]))
[react-native.core :as rn]
[quo2.theme :as theme]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icons]))
(def themes {:light {:default {:background-color colors/neutral-20
:icon-color colors/neutral-50
+50 -33
View File
@@ -1,11 +1,13 @@
(ns quo2.components.tabs.tabs
(:require [oops.core :refer [oget]]
[quo.react-native :as rn]
[react-native.core :as rn]
[quo2.components.tabs.tab :as tab]
[reagent.core :as reagent]
[status-im.ui.components.react :as react]
[status-im.utils.core :as utils]
[status-im.utils.number :as number-utils]))
[utils :as utils]
[quo2.foundations.colors :as colors]
[quo2.components.notifications.notification-dot :refer [notification-dot]]
[react-native.masked-view :as masked-view]
[react-native.linear-gradient :as linear-gradient]))
(def default-tab-size 32)
@@ -14,17 +16,30 @@
(fn [{:keys [data size] :or {size default-tab-size}}]
[rn/view (merge {:flex-direction :row} style)
(doall
(for [{:keys [label id]} data]
(for [{:keys [label id new-info accessibility-label]} data]
^{:key id}
[rn/view {:style {:margin-right (if (= size default-tab-size) 12 8)}}
(when new-info
[rn/view {:position :absolute
:z-index 1
:right -2
:top -2
:width 10
:height 10
:border-radius 5
:justify-content :center
:align-items :center
:background-color (colors/theme-colors colors/neutral-5 colors/neutral-95)}
[notification-dot]])
[tab/tab
{:id id
:size size
:active (= id @active-tab-id)
:on-press (fn []
(reset! active-tab-id id)
(when on-change
(on-change id)))}
{:id id
:size size
:accessibility-label accessibility-label
:active (= id @active-tab-id)
:on-press (fn []
(reset! active-tab-id id)
(when on-change
(on-change id)))}
label]]))])))
(defn- calculate-fade-end-percentage
@@ -35,7 +50,7 @@
;; Truncate to avoid unnecessary rendering.
(if (> fade-percentage 0.99)
0.99
(number-utils/naive-round fade-percentage 2))))
(utils/naive-round fade-percentage 2))))
(defn scrollable-tabs
"Just like the component `tabs`, displays horizontally scrollable tabs with
@@ -83,15 +98,17 @@
size default-tab-size}
:as props}]
(let [maybe-mask-wrapper (if fade-end?
[react/masked-view
{:mask-element (reagent/as-element
[react/linear-gradient {:colors [:black :transparent]
:locations [(get @fading :fade-end-percentage) 1]
:start {:x 0 :y 0}
:end {:x 1 :y 0}
:pointer-events :none
:style {:width "100%"
:height "100%"}}])}]
[masked-view/masked-view
{:mask-element
(reagent/as-element
[linear-gradient/linear-gradient
{:colors [:black :transparent]
:locations [(get @fading :fade-end-percentage) 1]
:start {:x 0 :y 0}
:end {:x 1 :y 0}
:pointer-events :none
:style {:width "100%"
:height "100%"}}])}]
[:<>])]
(conj maybe-mask-wrapper
[rn/flat-list
@@ -132,15 +149,15 @@
[tab/tab {:id id
:size size
:override-theme override-theme
:blur? blur?
:active (= id @active-tab-id)
:on-press (fn [id]
(reset! active-tab-id id)
(when scroll-on-press?
(.scrollToIndex @flat-list-ref
#js {:animated true
:index index
:viewPosition 0.5}))
(when on-change
(on-change id)))}
:blur? blur?
:active (= id @active-tab-id)
:on-press (fn [id]
(reset! active-tab-id id)
(when scroll-on-press?
(.scrollToIndex @flat-list-ref
#js {:animated true
:index index
:viewPosition 0.5}))
(when on-change
(on-change id)))}
label]])})])))))
+1 -2
View File
@@ -1,6 +1,5 @@
(ns quo2.components.tags.base-tag
(:require
[quo.react-native :as rn]))
(:require [react-native.core :as rn]))
(defn style-container [size disabled border-color border-width background-color label type]
(merge {:height size
+3 -3
View File
@@ -1,9 +1,9 @@
(ns quo2.components.tags.context-tags
(:require [quo2.foundations.colors :as colors]
[quo.theme :as quo.theme]
[quo2.theme :as quo2.theme]
[quo2.components.markdown.text :as text]
[quo2.components.avatars.group-avatar :as group-avatar]
[quo.react-native :as rn]))
[react-native.core :as rn]))
(defn padding-left-for-type [type]
(case type
@@ -15,7 +15,7 @@
(defn base-tag [_ _]
(fn [{:keys [override-theme style]} & children]
(let [theme (or override-theme (quo.theme/get-theme))]
(let [theme (or override-theme (quo2.theme/get-theme))]
(into
[rn/view
(merge
+30 -31
View File
@@ -1,10 +1,9 @@
(ns quo2.components.tags.permission-tag
(:require [status-im.ui.components.react :as react]
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icons]
[quo2.components.tags.base-tag :as base-tag]
[status-im.i18n.i18n :as i18n]))
[quo2.components.tags.base-tag :as base-tag]))
(defn outer-resource-container [size background-color]
{:background-color background-color
@@ -28,8 +27,8 @@
(defn extra-count [total-group-count selected-count size background-color]
(let [extra-group-count (- total-group-count selected-count)]
(when (> extra-group-count 0)
[react/view (outer-resource-container size background-color)
[react/view (extra-count-styles size)
[rn/view (outer-resource-container size background-color)
[rn/view (extra-count-styles size)
(if (< extra-group-count 4)
[text/text {:size :label
:style {:align-items :center
@@ -37,12 +36,12 @@
colors/neutral-50
colors/neutral-40)}}
(str "+" extra-group-count)]
[icons/icon :main-icons2/pending-default {:container-style {:align-items :center
:justify-content :center}
:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)
:size 12}])]])))
[icons/icon :i/pending-default {:container-style {:align-items :center
:justify-content :center}
:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)
:size 12}])]])))
(defn selected-token-count [group]
(cond
@@ -58,20 +57,20 @@
:or {size 24}}]
(let [tokens-count (count group)
selected-tokens (take (selected-token-count group) group)]
[react/view {:flex-direction :row
:align-items :center}
[rn/view {:flex-direction :row
:align-items :center}
(for [{:keys [token-icon]} selected-tokens]
^{:key token-icon}
[react/view {:flex-direction :row}
[react/view (outer-resource-container size background-color)
[react/image {:source token-icon
:style {:height (case size 32 28 24 20)
:width (case size 32 28 24 20)
:border-radius size}}]]])
[rn/view {:flex-direction :row}
[rn/view (outer-resource-container size background-color)
[rn/image {:source token-icon
:style {:height (case size 32 28 24 20)
:width (case size 32 28 24 20)
:border-radius size}}]]])
[extra-count tokens-count (count selected-tokens) size]
(when-not last-group
[react/view {:align-items :center}
[rn/view {:align-items :center}
[text/text {:weight :medium
:size (case size 32 :paragraph-2 24 :label)
:style {:color (colors/theme-colors
@@ -80,7 +79,7 @@
:padding-left 4
:text-transform :lowercase
:padding-right (case size 32 16 24 12)}}
(i18n/label :t/or)]])])))
"or"]])])))
(defn selected-group-count [tokens]
(cond
@@ -94,8 +93,8 @@
:or {size 24}}]
(let [selected-groups (take (selected-group-count tokens) tokens)
last-group-id ((last selected-groups) :id)]
[react/view {:flex-direction :row
:align-items :center}
[rn/view {:flex-direction :row
:align-items :center}
(for [{:keys [id group]} selected-groups]
^{:key id}
[token-group {:group group
@@ -110,13 +109,13 @@
[base-tag/base-tag {:background-color background-color
:size size
:type :permission}
[react/view {:flex-direction :row
:align-items :center
:justify-content :flex-end}
[react/view {:padding-left (case 32 8 24 6)
:padding-right (case size 32 16 24 12)}
[icons/icon (if locked :main-icons2/locked
:main-icons2/unlocked)
[rn/view {:flex-direction :row
:align-items :center
:justify-content :flex-end}
[rn/view {:padding-left (case 32 8 24 6)
:padding-right (case size 32 16 24 12)}
[icons/icon (if locked :i/locked
:i/unlocked)
{:resize-mode :center
:size (case size 32 20 24 16)
:color (colors/theme-colors
@@ -124,4 +123,4 @@
colors/neutral-40)}]]
[tag-tokens {:tokens tokens
:size size
:background-color background-color}]]]))
:background-color background-color}]]]))
+7 -8
View File
@@ -1,10 +1,9 @@
(ns quo2.components.tags.status-tags
(:require [quo.react-native :as rn]
[quo.theme :as quo.theme]
(:require [react-native.core :as rn]
[quo2.theme :as quo2.theme]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[status-im.i18n.i18n :as i18n]))
[quo2.foundations.colors :as colors]))
(def default-container-style
{:border-radius 20
@@ -54,7 +53,7 @@
:background-color colors/success-50-opa-10
:icon :verified
:border-color colors/success-50-opa-20
:label (or label (i18n/label :positive))
:label label
:text-color (if (= theme :light) colors/success-50
colors/success-60)}])
@@ -64,7 +63,7 @@
:icon :untrustworthy
:background-color colors/danger-50-opa-10
:border-color colors/danger-50-opa-20
:label (or label (i18n/label :negative))
:label label
:text-color (if (= theme :light)
colors/danger-50
colors/danger-60)}])
@@ -73,7 +72,7 @@
[size theme label]
[base-tag {:size size
:icon :pending
:label (or label (i18n/label :pending))
:label label
:background-color (if (= theme :light)
colors/neutral-10
colors/neutral-80)
@@ -91,5 +90,5 @@
nil)]
[status-component
size
(or override-theme (quo.theme/get-theme))
(or override-theme (quo2.theme/get-theme))
label])))
+2 -2
View File
@@ -1,7 +1,7 @@
(ns quo2.components.tags.tag
(:require [quo2.foundations.colors :as colors]
[quo.theme :as theme]
[quo.react-native :as rn]
[quo2.theme :as theme]
[react-native.core :as rn]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.tags.base-tag :as base-tag]))
+3 -4
View File
@@ -1,6 +1,6 @@
(ns quo2.components.tags.tags
(:require [reagent.core :as reagent]
[quo.react-native :as rn]
[react-native.core :as rn]
[quo2.components.tags.tag :as tag]))
(defn tags [{:keys [default-active on-change]}]
@@ -22,8 +22,7 @@
:icon-color icon-color
:labelled (if (= type :label) true labelled)
:resource (if (= type :icon)
:main-icons2/placeholder
:i/placeholder
resource)
:on-press #(do (reset! active-tab-id %)
(when on-change (on-change %)))})
tag-label]])]))))
(when on-change (on-change %)))})]])]))))
+12 -16
View File
@@ -1,9 +1,9 @@
(ns quo2.components.tags.token-tag
(:require [quo2.foundations.colors :as colors]
[quo.react-native :as rn]
[quo.theme :as theme]
[react-native.core :as rn]
[quo2.theme :as theme]
[quo2.components.markdown.text :as text]
[status-im.ui.components.icons.icons :as icons]))
[quo2.components.icon :as icons]))
(def themes {:light {:background-color colors/neutral-20}
:dark {:background-color colors/neutral-80}})
@@ -76,23 +76,19 @@
:or
{size :small border-color (colors/custom-color-by-theme :purple 50 60)}}]
[tag {:size size
[tag {:size size
:token-img-src token-img-src
:border-color (when is-required border-color)
:border-color (when is-required border-color)
:overlay
(when (or is-required is-purchasable)
[rn/view
{:style (merge icon-container-styles
{:width 15.5
:height 15.5
:background-color border-color
:border-color (if (= (theme/get-theme) :dark) colors/neutral-100 colors/white)
:border-width 1
:right (get-value-from-size size -3.75 -5.75)
:bottom (get-value-from-size size (- 32 7.75 4) (- 24 7.75 2)) ; (- height (icon-height/2) spacing)
})}
[icons/icon (if is-required :main-icons2/required-checkmark12 :main-icons2/purchasable12)
{:background-color border-color
:border-color (if (= (theme/get-theme) :dark) colors/neutral-100 colors/white)
:border-width 1
:right (get-value-from-size size -3.75 -5.75)
:bottom (get-value-from-size size (- 32 7.75 4) (- 24 7.75 2))})}
[icons/icon (if is-required :i/hold :i/add)
{:no-color true
:width 13.5
:height 13.5}]])}
:size 12}]])}
(str value " " token)]))
+1 -1
View File
@@ -1,5 +1,5 @@
(ns quo2.components.wallet.lowest-price
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[clojure.string :as string]))
(def centrify {:style {:flex-direction :row
@@ -1,19 +1,17 @@
(ns quo2.components.wallet.network-amount
(:require [clojure.string :as string]
[quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[status-im.i18n.i18n :as i18n]))
[quo2.foundations.colors :as colors]))
(defn network-amount
"[network-amount opts]
opts
{:style style ;; extra styles for the container (takes precedence)
:network-name \"Mainnet\" ;; shown network name
:icon :main-icons2/ethereum ;; key of icon belonging to the network
:icon :i/ethereum ;; key of icon belonging to the network
:eth-value 1.2345678 ;; shown ETH value}"
[{:keys [show-right-border? style network-name icon eth-value] :as _opts}]
[{:keys [show-right-border? style network-name icon eth-value labels] :as _opts}]
[rn/view (merge {:accessibility-label :network-amount
:background-color (colors/theme-colors colors/white colors/neutral-95)
:border-radius 16
@@ -35,7 +33,7 @@
[text/text {:weight :medium
:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-100 colors/white)}}
eth-value \space (i18n/label :t/eth)]
eth-value \space (:eth labels)]
[rn/view {:style {:border-right-width (when show-right-border? 1)
:border-right-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
:padding-left 8
@@ -44,4 +42,4 @@
[text/text {:weight :medium
:size :label
:style {:color colors/neutral-50}}
(string/lower-case (i18n/label :t/on)) \space network-name]]]])
(:on labels) \space network-name]]]])
@@ -1,11 +1,11 @@
(ns quo2.components.wallet.network-breakdown
(:require [quo.react-native :as rn]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]
[quo2.components.wallet.network-amount :refer [network-amount]]))
(defn network-breakdown
[{:keys [top-value network-conversions]}]
[{:keys [top-value network-conversions labels]}]
[rn/view {:style {:background-color (colors/theme-colors
colors/white
colors/neutral-95)
@@ -41,5 +41,6 @@
[network-amount {:show-right-border? (not= idx last-item-idx)
:icon icon
:network-name network
:eth-value conversion}]])
:eth-value conversion
:labels labels}]])
network-conversions))]])
+12 -15
View File
@@ -1,12 +1,10 @@
(ns quo2.components.wallet.token-overview
(:require
[quo2.foundations.colors :as colors]
[status-im.i18n.i18n :as i18n]
[quo.react-native :as rn]
[react-native.core :as rn]
[clojure.string :as string]
[status-im.utils.currency :as currencies]
[status-im.ui.components.icons.icons :as icons]
[quo2.components.markdown.text :as text]))
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icons]))
(def container-style {:display :flex :width "100%" :padding-left 20 :padding-right 20 :padding-top 12 :padding-bottom 12})
@@ -42,18 +40,18 @@
}"
[]
(fn
[{:keys [currency price percentage-change] :or {currency :usd price "0.00" percentage-change "0.0"}}]
[{:keys [currency price percentage-change label] :or {price "0.00" percentage-change "0.0"}}]
(let [direction (get-direction percentage-change)]
[rn/view {:style container-style}
[text/text {:number-of-lines 1
:size :paragraph-2} (i18n/label :token-price)]
:size :paragraph-2} label]
[text/text {:style {:margin-top 4}
:weight :semi-bold
:number-of-lines 1
:size :heading-2} (str (get-in currencies/currencies [currency :symbol]) price)]
:size :heading-2} (str currency price)]
[rn/view {:style {:display :flex :flex-direction :row :margin-top 6 :align-items :center}}
(when (not (zero? direction)) [icons/icon (if (>= direction 0) :main-icons2/price-increase12 :main-icons2/price-decrease12)
(when (not (zero? direction)) [icons/icon (if (>= direction 0) :i/price-increase12 :i/price-decrease12)
{:no-color true
:width 14
:height 14
@@ -76,7 +74,7 @@
:percentage-change :string
}"
[]
(fn [{:keys [token token-img-src currency account-balance price percentage-change] :or {currency :usd account-balance "0.00" price "0.00" percentage-change "0.0"}}]
(fn [{:keys [token token-img-src currency account-balance price percentage-change] :or {account-balance "0.00" price "0.00" percentage-change "0.0"}}]
(let [direction (get-direction percentage-change)]
[rn/view {:style container-style}
[text/text {:weight :regular
@@ -85,20 +83,19 @@
[rn/view {:style {:display :flex :flex-direction :row :flex 1 :justify-content :space-between}}
[text/text {:number-of-lines 1
:weight :semi-bold
:size :heading-1} (str (get-in currencies/currencies [currency :symbol]) account-balance)]
:size :heading-1} (str currency account-balance)]
[rn/image {:source token-img-src
:style {:height 32
:width 32}}]]
[rn/view {:style {:display :flex :flex-direction :row :margin-top 6 :align-items :center}}
(when (not (zero? direction)) [icons/icon (if (pos? direction) :main-icons2/price-increase12 :main-icons2/price-decrease12)
(when (not (zero? direction)) [icons/icon (if (pos? direction) :i/price-increase :i/price-decrease)
{:no-color true
:width 12
:height 12
:size 12
:container-style {:margin-right 4}}])
[text/text {:number-of-lines 1
:weight :medium
:size :paragraph-2
:style {:color (price-color direction)}} (str (get-in currencies/currencies [currency :symbol]) price)]
:style {:color (price-color direction)}} (str currency price)]
[divider direction]
[text/text {:number-of-lines 1
:weight :medium
+91
View File
@@ -0,0 +1,91 @@
(ns quo2.core
(:require quo2.components.buttons.button
quo2.components.buttons.dynamic-button
quo2.components.markdown.text
quo2.components.icon
quo2.components.separator
quo2.components.header
quo2.components.avatars.account-avatar
quo2.components.avatars.channel-avatar
quo2.components.avatars.group-avatar
quo2.components.avatars.icon-avatar
quo2.components.avatars.user-avatar
quo2.components.avatars.wallet-user-avatar
quo2.components.community.community-card-view
quo2.components.community.community-list-view
quo2.components.community.community-view
quo2.components.community.discover-card
quo2.components.counter.counter
quo2.components.dividers.divider-label
quo2.components.dividers.new-messages
quo2.components.drawers.action-drawers
quo2.components.dropdowns.dropdown
quo2.components.info.info-message
quo2.components.info.information-box
quo2.components.list-items.channel
quo2.components.list-items.menu-item
quo2.components.list-items.preview-list
quo2.components.messages.gap
quo2.components.messages.system-message
quo2.components.reactions.reaction
quo2.components.notifications.activity-logs
quo2.components.notifications.info-count
quo2.components.notifications.notification-dot
quo2.components.tags.tags
quo2.components.tabs.tabs
quo2.components.tabs.account-selector
quo2.components.list-items.index
quo2.components.list-items.list-item))
(def button quo2.components.buttons.button/button)
(def dynamic-button quo2.components.buttons.dynamic-button/dynamic-button)
(def text quo2.components.markdown.text/text)
(def icon quo2.components.icon/icon)
(def separator quo2.components.separator/separator)
(def counter quo2.components.counter.counter/counter)
(def header quo2.components.header/header)
(def action-drawer quo2.components.drawers.action-drawers/action-drawer)
(def dropdown quo2.components.dropdowns.dropdown/dropdown)
(def info-message quo2.components.info.info-message/info-message)
(def information-box quo2.components.info.information-box/information-box)
(def gap quo2.components.messages.gap/gap)
(def system-message quo2.components.messages.system-message/system-message)
(def reaction quo2.components.reactions.reaction/reaction)
(def tags quo2.components.tags.tags/tags)
(def tabs quo2.components.tabs.tabs/tabs)
(def scrollable-tabs quo2.components.tabs.tabs/scrollable-tabs)
(def account-selector quo2.components.tabs.account-selector/account-selector)
;;;; AVATAR
(def account-avatar quo2.components.avatars.account-avatar/account-avatar)
(def channel-avatar quo2.components.avatars.channel-avatar/channel-avatar)
(def group-avatar quo2.components.avatars.group-avatar/group-avatar)
(def icon-avatar quo2.components.avatars.icon-avatar/icon-avatar)
(def user-avatar quo2.components.avatars.user-avatar/user-avatar)
(def wallet-user-avatar quo2.components.avatars.wallet-user-avatar/wallet-user-avatar)
;;;; COMMUNITY
(def community-card-view-item quo2.components.community.community-card-view/community-card-view-item)
(def communities-list-view-item quo2.components.community.community-list-view/communities-list-view-item)
(def communities-membership-list-item quo2.components.community.community-list-view/communities-membership-list-item)
(def community-stats-column quo2.components.community.community-view/community-stats-column)
(def community-stats quo2.components.community.community-view/community-stats)
(def community-tags quo2.components.community.community-view/community-tags)
(def community-title quo2.components.community.community-view/community-title)
(def discover-card quo2.components.community.discover-card/discover-card)
;;;; DIVIDERS
(def divider-label quo2.components.dividers.divider-label/divider-label)
(def new-messages quo2.components.dividers.new-messages/new-messages)
;;;; LIST ITEMS
(def channel-list-item quo2.components.list-items.channel/list-item)
(def menu-item quo2.components.list-items.menu-item/menu-item)
(def preview-list quo2.components.list-items.preview-list/preview-list)
(def index quo2.components.list-items.index/index)
(def list-item quo2.components.list-items.list-item/list-item)
;;;; NOTIFICATIONS
(def activity-log quo2.components.notifications.activity-logs/activity-log)
(def info-count quo2.components.notifications.info-count/info-count)
(def notification-dot quo2.components.notifications.notification-dot/notification-dot)
+26 -2
View File
@@ -1,6 +1,6 @@
(ns quo2.foundations.colors
(:require [clojure.string :as string]
[quo.theme :as theme]))
[quo2.theme :as theme]))
(defn alpha [value opacity]
(when value
@@ -45,7 +45,6 @@
;;Blur
(def neutral-5-opa-70 (alpha neutral-5 0.7))
(def neutral-90-opa-70 (alpha neutral-90 0.7))
(def neutral-95-opa-70 (alpha neutral-95 0.7))
;;80 with transparency
(def neutral-80-opa-5 (alpha neutral-80 0.05))
@@ -60,6 +59,20 @@
(def neutral-80-opa-90 (alpha neutral-80 0.9))
(def neutral-80-opa-95 (alpha neutral-80 0.95))
;;95 with transparency
(def neutral-95-opa-60 (alpha neutral-95 0.6))
(def neutral-95-opa-70 (alpha neutral-95 0.7))
(def neutral-95-opa-80 (alpha neutral-95 0.8))
(def neutral-95-opa-90 (alpha neutral-95 0.9))
(def neutral-95-opa-95 (alpha neutral-95 0.95))
;;100 with transparency
(def neutral-100-opa-60 (alpha neutral-100 0.6))
(def neutral-100-opa-70 (alpha neutral-100 0.7))
(def neutral-100-opa-80 (alpha neutral-100 0.8))
(def neutral-100-opa-90 (alpha neutral-100 0.9))
(def neutral-100-opa-95 (alpha neutral-100 0.95))
;;;;White
;;Solid
@@ -78,6 +91,11 @@
(def white-opa-90 (alpha white 0.9))
(def white-opa-95 (alpha white 0.95))
;;;;Black
;;Solid
(def black "#000000")
;;;;Primary
;;Solid
@@ -104,6 +122,12 @@
(def success-50-opa-30 (alpha success-50 0.3))
(def success-50-opa-40 (alpha success-50 0.4))
(def success-60-opa-5 (alpha success-60 0.05))
(def success-60-opa-10 (alpha success-60 0.1))
(def success-60-opa-20 (alpha success-60 0.2))
(def success-60-opa-30 (alpha success-60 0.3))
(def success-60-opa-40 (alpha success-60 0.4))
;;;;Danger
;;Solid
+2
View File
@@ -45,3 +45,5 @@
(def font-bold {:font-family "Inter-Bold"}) ; 700
(def monospace {:font-family "InterStatus-Regular"})
(def code {:font-family "UbuntuMono-Regular"})
@@ -1,61 +0,0 @@
(ns quo2.screens.navigation.bottom-nav-tab
(:require [quo.react-native :as rn]
[quo.previews.preview :as preview]
[reagent.core :as reagent]
[quo2.components.navigation.bottom-nav-tab :as quo2]
[quo2.foundations.colors :as colors]))
(def descriptor [{:label "Type"
:key :icon
:type :select
:options [{:key :main-icons2/communities
:value "Communities"}
{:key :main-icons2/messages
:value "Messages"}
{:key :main-icons2/wallet
:value "Wallet"}
{:key :main-icons2/browser
:value "Browser"}]}
{:label "Selected?"
:key :selected?
:type :boolean}
{:label "Pass through?"
:key :pass-through?
:type :boolean}
{:label "New Notifications?"
:key :new-notifications?
:type :boolean}
{:label "Notification Indicator"
:key :notification-indicator
:type :select
:options [{:key :counter
:value :counter}
{:key :unread-dot
:value :unread-dot}]}
{:label "Counter Label"
:key :counter-label
:type :text}])
(defn cool-preview []
(let [state (reagent/atom {:icon :main-icons2/communities
:selected? true
:pass-through? true
:new-notifications? true
:notification-indicator :counter
:counter-label 8
:preview-label-color colors/white})]
(fn []
[rn/touchable-without-feedback {:on-press rn/dismiss-keyboard!}
[rn/view {:padding-bottom 150}
[preview/customizer state descriptor]
[rn/view {:padding-vertical 60
:align-items :center}
[quo2/bottom-nav-tab @state (:value @state)]]]])))
(defn preview-bottom-nav-tab []
[rn/view {:background-color colors/neutral-100
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
-40
View File
@@ -1,40 +0,0 @@
(ns quo2.screens.selectors.selectors
(:require [quo.react-native :as rn]
[quo.previews.preview :as preview]
[reagent.core :as reagent]
[quo2.components.selectors.selectors :as quo2]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))
(def descriptor [{:label "Disabled?"
:key :disabled?
:type :boolean}])
(defn cool-preview []
(let [state (reagent/atom {:disabled false})]
(fn []
[rn/view {:margin-bottom 50
:padding 16}
[preview/customizer state descriptor]
[rn/view {:padding-vertical 60
:align-items :center}
[text/text {:size :heading-2} "Toggle"]
[quo2/toggle {:container-style {:margin-top 0}
:disabled? (:disabled? @state)}]
[text/text {:size :heading-2} "Radio"]
[quo2/radio {:container-style {:margin-top 0}
:disabled? (:disabled? @state)}]
[text/text {:size :heading-2} "Checkbox"]
[quo2/checkbox {:container-style {:margin-top 0}
:disabled? (:disabled? @state)}]
[text/text {:size :heading-2} "Checkbox Prefill"]
[quo2/checkbox-prefill {:container-style {:margin-top 0}
:disabled? (:disabled? @state)}]]])))
(defn preview-selectors []
[rn/view {:background-color (colors/theme-colors colors/white colors/neutral-90)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
+13
View File
@@ -0,0 +1,13 @@
(ns quo2.theme
(:require [reagent.core :as reagent]))
(def theme (reagent/atom :light))
(defn dark? []
(= :dark @theme))
(defn get-theme []
@theme)
(defn set-theme [value]
(reset! theme value))
+14
View File
@@ -0,0 +1,14 @@
(ns react-native.background-timer
(:require ["react-native-background-timer" :default background-timer]))
(defn set-timeout [cb ms]
(.setTimeout background-timer cb ms))
(defn clear-timeout [id]
(.clearTimeout background-timer id))
(defn set-interval [cb ms]
(.setInterval background-timer cb ms))
(defn clear-interval [id]
(.clearInterval background-timer id))
+8
View File
@@ -0,0 +1,8 @@
(ns react-native.config
(:require ["react-native-config" :default react-native-config]))
(def config (js->clj react-native-config :keywordize-keys true))
(defn get-config
([k] (get config k))
([k not-found] (get config k not-found)))
+50
View File
@@ -0,0 +1,50 @@
(ns react-native.core
(:require [reagent.core :as reagent]
["react-native" :as react-native]
[react-native.flat-list :as flat-list]))
(def app-state ^js (.-AppState ^js react-native))
(def view (reagent/adapt-react-class (.-View ^js react-native)))
(def scroll-view (reagent/adapt-react-class (.-ScrollView ^js react-native)))
(def image (reagent/adapt-react-class (.-Image ^js react-native)))
(def text (reagent/adapt-react-class (.-Text ^js react-native)))
(def text-input (reagent/adapt-react-class (.-TextInput ^js react-native)))
(def touchable-opacity (reagent/adapt-react-class (.-TouchableOpacity ^js react-native)))
(def touchable-highlight (reagent/adapt-react-class (.-TouchableHighlight ^js react-native)))
(def touchable-without-feedback (reagent/adapt-react-class (.-TouchableWithoutFeedback ^js react-native)))
(def flat-list flat-list/flat-list)
(def activity-indicator (reagent/adapt-react-class (.-ActivityIndicator ^js react-native)))
(def modal (reagent/adapt-react-class (.-Modal ^js react-native)))
(def keyboard ^js (.-Keyboard ^js react-native))
(def dismiss-keyboard! #(.dismiss keyboard))
(defn use-window-dimensions []
(let [window ^js (react-native/useWindowDimensions)]
{:font-scale (.-fontScale window)
:height (.-height window)
:scale (.-scale window)
:width (.-width window)}))
(defn hide-splash-screen []
(.hide ^js (-> react-native .-NativeModules .-SplashScreen)))
(defn alert [title message buttons options]
(.alert (.-Alert ^js react-native) title message (clj->js buttons) (clj->js options)))
(def appearance ^js (.-Appearance ^js react-native))
(defn get-color-scheme []
(.getColorScheme appearance))
(defn appearance-add-change-listener [handler]
(.addChangeListener appearance handler))
(defn get-window []
(js->clj (.get (.-Dimensions ^js react-native) "window") :keywordize-keys true))
+32
View File
@@ -0,0 +1,32 @@
(ns react-native.fast-image
(:require ["react-native-fast-image" :as FastImage]
[react-native.core :as rn]
[reagent.core :as reagent]))
(def fast-image-class (reagent/adapt-react-class ^js FastImage))
(defn placeholder [style child]
[rn/view {:style (merge style {:flex 1 :justify-content :center :align-items :center})}
child])
(defn fast-image [_]
(let [loaded? (reagent/atom false)
error? (reagent/atom false)]
(fn [props]
[fast-image-class (merge
props
{:on-error (fn [e]
(when-let [on-error (:on-error props)]
(on-error e))
(reset! error? true))
:on-load (fn [e]
(when-let [on-load (:on-load props)]
(on-load e))
(reset! loaded? true)
(reset! error? false))})
(when (or @error? (not @loaded?))
[placeholder (:style props)
(if @error?
[rn/text "X"]
(when-not @loaded?
[rn/activity-indicator {:animating true}]))])])))
+35
View File
@@ -0,0 +1,35 @@
(ns react-native.flat-list
(:require [reagent.core :as reagent]
["react-native" :as react-native]))
(def react-native-flat-list (reagent/adapt-react-class (.-FlatList ^js react-native)))
(defn- wrap-render-fn [f render-data]
(fn [data]
(reagent/as-element [f (.-item ^js data) (.-index ^js data)
(.-separators ^js data) render-data
(.-isActive ^js data) (.-drag ^js data)])))
(defn- wrap-on-drag-end-fn [f]
(fn [data]
(f (.-from ^js data) (.-to ^js data) (.-data ^js data))))
(defn- wrap-key-fn [f]
(fn [data index]
{:post [(some? %)]}
(f data index)))
(defn base-list-props
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn] :as props}]
(merge {:data (to-array data)}
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
(when header {:ListHeaderComponent (reagent/as-element header)})
(when footer {:ListFooterComponent (reagent/as-element footer)})
(when on-drag-end-fn {:onDragEnd (wrap-on-drag-end-fn on-drag-end-fn)})
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn)))
(defn flat-list [props]
[react-native-flat-list (base-list-props props)])
@@ -1,8 +1,9 @@
(ns quo2.gesture
(:require ["react-native-gesture-handler" :refer (GestureDetector Gesture)]
(ns react-native.gesture
(:require ["react-native-gesture-handler" :refer (GestureDetector Gesture gestureHandlerRootHOC)]
[reagent.core :as reagent]))
(def gesture-detector (reagent/adapt-react-class GestureDetector))
(def gesture-handler-root-hoc gestureHandlerRootHOC)
(defn gesture-pan [] (.Pan ^js Gesture))
@@ -10,4 +11,4 @@
(defn on-start [^js pan handler] (.onStart pan handler))
(defn on-end [^js pan handler] (.onEnd pan handler))
(defn on-end [^js pan handler] (.onEnd pan handler))
+5
View File
@@ -0,0 +1,5 @@
(ns react-native.hole-view
(:require [reagent.core :as reagent]
["react-native-hole-view" :refer (RNHoleView)]))
(def hole-view (reagent/adapt-react-class RNHoleView))
+8
View File
@@ -0,0 +1,8 @@
(ns react-native.languages
(:require ["react-native-languages" :default react-native-languages]))
(defn add-change-listener [handler]
(.addEventListener ^js react-native-languages "change" (fn [^js event] (handler (.-language event)))))
(defn get-lang-keyword []
(keyword (.-language ^js react-native-languages)))
+5
View File
@@ -0,0 +1,5 @@
(ns react-native.linear-gradient
(:require ["react-native-linear-gradient" :default LinearGradient]
[reagent.core :as reagent]))
(def linear-gradient (reagent/adapt-react-class LinearGradient))
+5
View File
@@ -0,0 +1,5 @@
(ns react-native.mail
(:require ["react-native-mail" :default react-native-mail]))
(defn mail [opts callback]
(.mail react-native-mail (clj->js opts) callback))

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