Compare commits

..
Author SHA1 Message Date
Omar Basem a35489d1c5 lint spacing 2023-07-21 09:10:06 +04:00
Omar Basem 3d584bcf3f revert podfile 2023-07-21 09:10:06 +04:00
Omar Basem 61417c57d7 review 2023-07-21 09:10:06 +04:00
Omar Basem eab026c89c review 2023-07-21 09:10:05 +04:00
Omar Basem 9a91d994b7 update title 2023-07-21 09:10:05 +04:00
Omar Basem c0079f3cac review 2023-07-21 09:10:05 +04:00
Omar Basem 4fc7a2e0bb style update 2023-07-21 09:10:04 +04:00
Omar Basem 9b00955345 feat: category quo2 2023-07-21 09:10:04 +04:00
Churikova Tetiana 1b2ad33926 e2e: TimeoutException 2023-07-20 20:06:43 +03:00
Mohamed Javid 9731e7039c Refactor Bottom Sheet to use Theme Context (#16710)
This commit updates "Bottom Sheet" to use the theme (for theme provider) provided on the bottom sheet args when dispatching. This will ensure the theme is passed down to its child components where it can consume and render based on the theme.

Changes done:

In Bottom Sheet:
 - Fix Bottom Sheet to use the correct background colour (neutral-95) for dark mode (as per Figma)
 - Fix the Icon colour for danger in light mode
 - Updated Quo2 Preview to provide an option for the bottom sheet theme

In Action Drawer:
 - Refactor the Action Drawer component to consume theme context

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-07-20 19:43:17 +05:30
Mohamed Javid b14757b120 [Fix] Scroll to bottom on editing message (#16630)
This commit fixes (by skipping) the scroll to the bottom of messages when the user edits a message and sends it.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-07-20 16:57:09 +05:30
John Ngei 2317e856bf Mute community
* mute and unmute community

https://github.com/status-im/status-go/compare/dfdaa722...e6187aec

* mute and unmute community and all community chats

https://github.com/status-im/status-go/compare/dfdaa722...3abc86e4

* updated statu-go

https://github.com/status-im/status-go/compare/dfdaa722...919123e1

* refactored mute chat drawer

https://github.com/status-im/status-go/compare/d3e650d5...3af0b17c

* refactored mute chat drawer

https://github.com/status-im/status-go/compare/dfdaa722...3af0b17c

* fixing mute channels

* fixed mute community channels

* update community chats mute status

https://github.com/status-im/status-go/compare/dfdaa722...dc50ac21

* added mute and unmute community toast

https://github.com/status-im/status-go/compare/dfdaa722...c06f7a6c

* unmute community when atleast one community channel is unmuted

https://github.com/status-im/status-go/compare/dfdaa722...e691c475

* updated status-go

https://github.com/status-im/status-go/compare/b2e56f5d...c52718cd

* updated status-go version v0.162.5
2023-07-19 16:30:42 +03:00
flexsurfer 32f18c3d3c [#16703] The display name is not resolved in chats for user sender after relogin (#16704) 2023-07-18 10:04:42 +02:00
Andrea Maria Piana e99f6de434 Update version to 0.162.3 2023-07-17 15:53:14 +01:00
Parvesh Monu bb3b3061c6 fix navigation to community from discover communities screen (#16702) 2023-07-17 13:56:46 +05:30
Ibrahem Khalil 0067468d57 Fix failing mute till test (#16453) 2023-07-16 15:02:32 +03:00
Ibrahem Khalil b2cbed444c [161108] Optimize message styling when there's multiple mentions on top of each other (#16505) 2023-07-16 14:40:09 +03:00
Yevheniia Berdnyk 1d0186a12e fix for airplane mode 2023-07-15 00:17:17 +03:00
Parvesh Monu c0e4653129 hide mutual update's system messages (#16674) 2023-07-14 19:29:19 +05:30
Andrea Maria Piana 60f18fc6fb Update readme 2023-07-14 10:42:17 +01:00
Parvesh Monu b531dadf96 fix navigating to chat via the 'Jump to' button breaks composer (#16604) 2023-07-14 13:45:12 +05:30
Andrea Maria Piana 2b0ea01710 Avoid panic when config missing in community 2023-07-14 08:26:21 +01:00
Mohamed Javid 9f5e7ce3f9 Add flash toggle for the camera in sync screen (#16558)
This commit adds a flash toggle for the camera in the "Sign in" and "Scan sync code" screens.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-07-13 17:33:53 +05:30
Parvesh Monu a340e2a55c fix image long press issue and cropping (#16571) 2023-07-13 14:07:42 +05:30
Icaro Motta 88c4521321 Move status-im.utils.money to utils.money (#16573) 2023-07-12 18:26:04 +00:00
codemaster 645a5b312b fix: banner images/colors in shell (#16239) 2023-07-13 00:56:43 +10:00
Andrés Felipe Ceballos M c55f12ecf8 [#15950] Updated build-image-messages (#16518)
Author: andresceballosm <ceballosmarandres@gmail.com>
2023-07-12 18:34:29 +05:30
Icaro Motta 6c28e9349f Fix & optimize shadows foundation (#16553)
Rewrite the shadows foundation API:

- Fix (implementation & usages): theme changes were not causing shadows to be
  reevaluated.
- Optimization: define all possible shadow values at compile time. Good to
  reduce cycles on garbage collection since recreating the shadow map all the
  time is unnecessary and also to save cycles on computing colors since calls to
  colors/alpha are not memoized.
- API redesign: unify access to Design System shadows in a single function.

None of the actual shadow values changed.

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

API rationale
=============

The quo2.foundations.shadows namespace reflects what's in the Design System >
Foundations > Shadows https://www.figma.com/file/v98g9ZiaSHYUdKWrbFg9eM/Foundations?type=design&node-id=624-965&mode=design&t=CvIotdjbHKHcHjpd-0).
Figma users see these shadows in other components as "Shadow/Normal/Light/03".
Notice the shadow's weight is shown as a number (not the semantic name in Figma,
e.g. "intense", "strong"):

So to make things as easy as possible, I opted for exposing a single public
function named "get", which receives arguments in order of frequency of usage
and which expects shadow weights as numbers so that devs don't need to mentally
translate 1 to "soft", or 3 to "intense".
2023-07-12 11:35:14 +00:00
Icaro Motta 6170686e34 Rewrite Community List component (#16527)
Re-implements the component Community List according to guidelines
and, most importantly, fixes a bunch of issues and tries to achieve 100%
compatibility with Figma.

The new implementation is trying to mirror Figma properties as much as possible.

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

Changelog:

- Refactor to guidelines.
- Fix: original implementation in money/format-amounts had a bug caught by new
  unit tests ("1000000" was formatted incorrectly).
- Fix: Community permission tag correct background when theme is overridden and
  when blur is enabled.
- Fix: Notification dot uses correct colors for dark mode and blur variants.
- Fix: Community stats background when blur is enabled.
- Fix: Community stats icon color when blur is enabled.
- Add: The component's Quo preview screen is smarter and will only show form
  fields (aka descriptors) that are relevant for each component type (engage,
  discover or share).
- Add: replace hardcoded community statistics with an implementation that
  actually accepts real numbers and which are correctly formatted.
- Add: New Quo descriptor type number.
- Add: Component uses correct shadows according to foundations/shadows.
2023-07-12 11:14:24 +00:00
Mohamed Javid 72e56dcf75 [Fix] Login Validation Error (#16562)
This commit fixes the log-in validation issue due to not receiving the "node.login" signal from "status-go".

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-07-12 16:12:50 +05:30
Jamie Caprani 4801342a42 chore: add doc on pixel perfection (#16539) 2023-07-12 03:31:14 -07:00
Tetiana Churikova 7282ba04bc e2e: fixes shell nav (#16545) 2023-07-12 11:21:39 +02:00
Ibrahem Khalil 2e397f0065 [16524] Fix chevron icon showing when chat is muted (#16528) 2023-07-12 11:28:53 +03:00
Parvesh Monu bcb55a1ab3 Enable shell navigation (#16438) 2023-07-12 13:24:50 +05:30
Alexander 224d6c7cad Top bar fixes (#16506)
* Recent fixes

* More fix attempts (more successful now)

* Updates for `on-content-size-change`

* Lint fix

* Update

* View fixes
2023-07-11 20:30:22 +02:00
Mohamed Javid 126a8705cd [Fix] Seen state in Activity Center when it is open (#16541)
This commit fixes the seen state of notifications, if the user is in the Activity Center screen while receiving a new notification.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-07-11 20:59:17 +05:30
Jamie Caprani 3fce4816dc feat: add video and animation to generating keys page (#16415) 2023-07-11 07:26:40 -07:00
Omar Basem 704b160964 feat: album selector animation (#16533)
* feat: album selector animation
2023-07-11 15:16:24 +04:00
Ibrahem Khalil 7350c88920 [16467] Fix delete for me doesn't work on chat reopen (#16529) 2023-07-11 13:42:14 +03:00
Omar Basem 7392b9bf50 Lightbox opacity swipe animation, and margins (#16510)
* feat: lightbox animations
2023-07-11 13:41:34 +04:00
Ibrahem Khalil f5948fa016 [16543] Fix muting channel from inside and outside chat page (#16544) 2023-07-10 22:42:15 +03:00
Mohamed Javid 919fbf2091 [Fix] Profile colour in "Jump to" and "View profile" buttons (#16538)
This commit fixes the profile colour in the following screens:

- "View Profile" button on the "Add a contact" page
- "Jump to" button inside the chat
- "Jump to" button in the "Community Overview" screen

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-07-10 18:44:31 +05:30
Parvesh Monu 728d9d01c5 fix App is not opened on the last viewed chat with biometric login enabled (#16516) 2023-07-10 15:33:31 +05:30
Jamie Caprani 9ac14b6fac chore: update guidelines for figma api to match quo2 component api (#16454) 2023-07-10 02:45:39 -07:00
Brian Sztamfater 4414f8ffd3 fix: onboarding carousel screen overflows affecting navigation (#16514)
Signed-off-by: Brian Sztamfater <brian@status.im>
2023-07-07 12:55:38 -03:00
Andrea Maria Piana 1e8ea3fd16 Enable lightclient
https://github.com/status-im/status-go/compare/67050429...67050429
2023-07-07 15:40:24 +01:00
Icaro Motta 17f5ad79f4 Fixes for the Community Channel avatar component (#16379)
- Community channels may not have an emoji, and in such cases, it should fall
  back to a single letter. The component was recently updated in Figma after
  this concern was brought up to designers.
- The default (fallback) color to be used in the list of community channels
  should be the community color, not a default "primary-50" as was before. It's
  a subtle change because the colors are rendered at 10% transparency.
- Rewrote the channel-avatar component to follow guidelines.

Fixes:

- https://github.com/status-im/status-mobile/issues/16332
- https://github.com/status-im/status-mobile/issues/16327
2023-07-07 14:16:50 +00:00
Siddarth Kumar d76e64b1bb fix: profile redirect on newly created account (#16340)
This commit gets rid of the app-state check which is buggy,
The app-state becomes `active` after the universal link code has executed always resulting in the redirect not happening.
2023-07-07 19:21:00 +05:30
flexsurfer ac675e28eb [#16520] ENS setting is unavailable on PRs when test network is set (#16521) 2023-07-07 15:34:02 +02:00
Omar Basem 5755d2e21a Lightbox text sheet (#16471)
* feat: lightbox text
2023-07-07 17:10:04 +04:00
Rahul Pratap cf2a3bfce7 Fixed issues with styling in pinned messages panel. (#16498) 2023-07-07 17:16:12 +05:30
Siddarth Kumar dcda44fab6 fix: ellipsis on compressed-keys as per designs (#16492)
This commit does the following:

- Moves `get-abbreviated-profile-url` from shell share view into `utils.address` and update its usage.

- Adds `get-shortened-compressed-key` to `utils.address` and update the code using `get-shortened-key` to now use `get-shortened-compressed-key` instead.

- Adds test for newly introduced utils.
2023-07-07 16:31:17 +05:30
Yevheniia Berdnyk 362aa476ae e2e: fix for nightly apk upload (#16517) 2023-07-07 11:08:13 +02:00
Jamie Caprani 25b088833d chore: move button into view and style files (#16442)
* chore: move button into view and style files
2023-07-07 00:20:37 -07:00
flexsurfer 3395baa966 fix smthg test folder (#16519) 2023-07-07 08:46:54 +02:00
flexsurfer 4327653b0b [#16422] Merge profile and profile overview into one map in status-go (#16507)
* [#16422] Merge profile and profile overview into one map in status-go
2023-07-06 19:46:21 +02:00
Yevheniia Berdnyk 26dcc16ea6 e2e: fix for endless apk upload + teardown 2023-07-06 17:47:35 +03:00
Icaro Motta 9ed68ee7d1 Lint & fix some shadowed core Clojure(Script) vars (#16500)
It's well known that shadowing core Clojure vars can lead to unexpected bugs. In
fact, it's a common source of bugs in other languages too. In the status-mobile
repository there are, in total, 562 shadowed vars, ~500 are core vars. Excluding
the "old code" we still have 285 offenders.

In status-mobile I've already seen two bugs caused by shadowed vars, both with
the shadowed var "name". But probably other problems happened in the past, and
others will happen in the future if we don't do something about this. This PR is
also my response to my frustration trying to review PRs and checking for
shadowed vars, humans were not meant for that!

In this commit we are enabling ":shadowed-var" to lint certain (not all) core
vars as errors (not warnings). In future PRs we can gradually unshadow more
vars. For the record, name is shadowed 40 times in the new code and 130 in
total, and type is shadowed 93 times in the new code and 124 in total!

What about non-core vars, should we allow shadowing? There are ~70 non-core
shadowed vars. In my opinion, we should also lint and disallow shadowing
non-core vars, since it may cause the same kind of bugs of shadowing core vars.
But this decision can be left for another moment/issue, after we have fixed the
most prominent problem of shadowing core vars.

Which vars are unshadowed in this PR? I fixed 62 errors and unshadowed
cljs.core/iter, cljs.core/time, cljs.core/count, cljs.core/key,
clojure.core/key.

Resources:

- [clj-kondo linter: shadowed-var](https://github.com/clj-kondo/clj-kondo/blob/master/doc/linters.md#shadowed-var)
2023-07-06 10:28:07 +00:00
Parvesh Monu 4d7cf3e94e Replace placeholders on "Jump to" page (#16501) 2023-07-06 15:27:18 +05:30
flexsurfer 4decba8d00 multiaccounts refactoring S3, refactor keychain and touchid, move and refactor create/recover/login profile (#16448)
* multiaccounts refactoring S3 E1, refactor keychain and touchid,simplify app init flow, refactor biometric flow
* S3 E2 move and refactor create/recover/login methods
2023-07-06 11:25:57 +02:00
Ibrahem Khalil 229a806f12 [16079] Fix dark mode for communities and messages home (#16382) 2023-07-05 22:34:13 +03:00
Ibrahem Khalil abe653c086 [16469] Fix conditional of selection user's name in confirmation drawer (#16489) 2023-07-05 20:06:19 +03:00
AlexanderandOmar Basem f047665f75 Dynamically calculate composer height to adjust the spacing on the bottom of the list (#16235)
* fix: Android auto scrolling to bottom of chat

---------

Co-authored-by: Omar Basem <omarbasem.0101@gmail.com>
2023-07-05 18:30:27 +04:00
Tetiana Churikova ea3b090265 e2e: change numpocesses (#16494) 2023-07-05 14:59:36 +02:00
Tetiana Churikova c52bf965f7 e2e: more groups (#16483) 2023-07-05 11:55:40 +02:00
Ulises Manuel Cárdenas e260187cf5 [#16073] Password info box
* Refactor: Remove use of f-component

* Fix documentation drawer styles

* Refactor: move title styles to style ns

* Fix StaticSafeAreaInsets not being defined on component tests

* Fix bottom sheet height on Android
2023-07-04 17:08:47 -06:00
Ulises Manuel Cárdenas ca0915c940 #16111 - Toast animation & dismiss gesture
* Enable toast animations and refactor

* Add gesture-handler-root-HOC to detect toast's gestures on Android

* Add comment about flex 0 style
2023-07-04 16:25:08 -06:00
Ulises Manuel Cárdenas 2b4b357c32 [#16378] Fix channel unread counter space
* Makes `divider-label` styles more lenient

* Small refactor to `list-items.channel` component

* Fix styles for `channel-list-component`
  - Refactor `channel-list-component`
  - Add some missing `:style` keys in `status-im2.contexts.communities.overview.view`
  - Fix a warning related to using a `deref` in a `lazy-seq`

* Changes icon keyword namespace from `:main-icons` to `:i`
2023-07-04 16:11:56 -06:00
Icaro Motta 19ca8e28a5 Lint and fix missing trailing newlines (#16445)
Apply the Clojure Style Guide recommendation to end files with proper lines
(having a trailing newline character). See
https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap03.html#tag_03_206
2023-07-04 19:40:13 +00:00
Yevheniia Berdnyk 8978e92042 e2e: nightly fixes 2023-07-04 20:26:05 +03:00
Brian Sztamfater c2c79cc1ac feat: implement onboarding modal transition for sign in screen (#16167) 2023-07-04 12:43:08 -03:00
Parvesh Monu affd2a5e76 Implement static loading skeleton (#16474) 2023-07-04 16:55:22 +05:30
Yevheniia Berdnyk ef99bf2ad6 e2e: tests for reactions in community and group chats 2023-07-04 13:17:48 +03:00
Jamie Caprani 1f6f907d57 feat: add markdown list component to quo2 (#16411) 2023-07-03 13:08:19 -07:00
Jamie Caprani 97b254c514 chore: update use of theme in page-nav component (#16424) 2023-07-03 08:37:31 -07:00
Yevheniia Berdnyk ca2ed9d37e e2e: fixes for backup users and unread indicator tests 2023-07-03 15:55:05 +03:00
Jamie Caprani e64ff76e0b update theming for profile-input, empty state and predictive keyboard components (#16423)
* chore: remove override-prop from empty-state component

* chore: remove override-prop from profile-input and title-input components

* chore: remove override-prop from predictive-keyboard component
2023-07-03 04:26:33 -07:00
Mohamed Javid 88884064b1 Update Bottom sheet screen to use theme context (#16429)
This commit updates the `bottom-sheet-screen` component (which used `override-theme` from `screen-params` subs) to use the theme from the context provider.

The bottom sheet screen will pick the theme specified in the screen options (to override) as expected. If it's not specified, then it will fall back to the user's theme.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-07-03 13:00:41 +05:30
393 changed files with 7026 additions and 5792 deletions
+7
View File
@@ -14,6 +14,13 @@
clojure.set set
clojure.walk walk
taoensso.timbre log}}
:shadowed-var {:level :error
;; We temporarily use :include to define an
;; allowlist of core Clojure vars. In the
;; future, as we progressively fix shadowed
;; vars, we should be able to delete this
;; option and lint all vars.
:include [count iter key time]}
:invalid-arity {:skip-args [status-im.utils.fx/defn utils.re-frame/defn]}
;; TODO remove number when this is fixed
;; https://github.com/borkdude/clj-kondo/issues/867
+1 -1
View File
@@ -43,4 +43,4 @@ As a <user|developer|...>, I want to <task> so that <goal>.
[comment]: # (if on Android please replicate bug whilst running adb logcat)
```
...
```
```
+13 -12
View File
@@ -14,17 +14,17 @@ WHITE := $(shell tput -Txterm setaf 7)
YELLOW := $(shell tput -Txterm setaf 3)
RESET := $(shell tput -Txterm sgr0)
HELP_FUN = \
%help; \
while(<>) { push @{$$help{$$2 // 'options'}}, [$$1, $$3] if /^([a-zA-Z\-]+)\s*:.*\#\#(?:@([a-zA-Z\-]+))?\s(.*)$$/ }; \
print "Usage: make [target]\n\nSee STARTING_GUIDE.md for more info.\n\n"; \
for (sort keys %help) { \
print "${WHITE}$$_:${RESET}\n"; \
for (@{$$help{$$_}}) { \
$$sep = " " x (32 - length $$_->[0]); \
print " ${YELLOW}$$_->[0]${RESET}$$sep${GREEN}$$_->[1]${RESET}\n"; \
}; \
print "\n"; \
}
%help; \
while(<>) { push @{$$help{$$2 // 'options'}}, [$$1, $$3] if /^([a-zA-Z\-]+)\s*:.*\#\#(?:@([a-zA-Z\-]+))?\s(.*)$$/ }; \
print "Usage: make [target]\n\nSee STARTING_GUIDE.md for more info.\n\n"; \
for (sort keys %help) { \
print "${WHITE}$$_:${RESET}\n"; \
for (@{$$help{$$_}}) { \
$$sep = " " x (32 - length $$_->[0]); \
print " ${YELLOW}$$_->[0]${RESET}$$sep${GREEN}$$_->[1]${RESET}\n"; \
}; \
print "\n"; \
}
HOST_OS := $(shell uname | tr '[:upper:]' '[:lower:]')
# This can come from Jenkins
@@ -307,6 +307,7 @@ lint: ##@test Run code style checks
clj-kondo --config .clj-kondo/config.edn --cache false --lint src && \
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILES && \
sh scripts/lint-trailing-newline.sh && \
yarn prettier
# NOTE: We run the linter twice because of https://github.com/kkinnear/zprint/issues/271
@@ -315,9 +316,9 @@ lint-fix: ##@test Run code style checks and fix issues
ALL_CLOJURE_FILES=$(call find_all_clojure_files) && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILES && \
sh scripts/lint-trailing-newline.sh --fix && \
yarn prettier
shadow-server: export TARGET := clojure
shadow-server:##@ Start shadow-cljs in server mode for watching
yarn shadow-cljs server
+12 -17
View File
@@ -2,7 +2,9 @@
[<img src="https://play.google.com/intl/en_us/badges/images/generic/en-play-badge.png" alt="Get it on Google Play" height="80"/>](https://play.google.com/store/apps/details?id=im.status.ethereum)
[<img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80"/>](https://f-droid.org/packages/im.status.ethereum/)
[<img src="doc/github_badge.png" alt="Get it on Github" height="80"/>](https://github.com/status-im/status-mobile/releases)
[Get it on Github](https://github.com/status-im/status-mobile/releases)
Join us in creating a browser, messenger, and gateway to a decentralized world. Status is a free (libre) open source mobile client targeting Android & iOS built entirely on [Ethereum](https://ethereum.org/) technologies. That's right, no middle men and `go-ethereum` running directly on your device.
@@ -20,31 +22,31 @@ If this interests you, **help us make Status a reality** - anyone can contribute
## How to 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:
Go straight to the [docs](doc/) 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
[Developer Introduction](doc/starting-guide.md) 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.
Status](doc/starting-guide.md), which talks about managing
project dependencies, coding guidelines and testing procedures.
Check out our [coding guidelines](doc/new-guidelines.md).
- **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**
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.
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, check out our [docs](doc/) and see how you can improve what we have.
- **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!
Content is King, keeping our blog up to date and informing the community of news helps keep everyone on the same page.
- **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!
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](doc/starting-guide.md) 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**
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!
@@ -52,9 +54,6 @@ Status is a visual interface to make permanent changes on the Blockchain, it han
- **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
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!
You can get our Beta builds for both Android and iOS on our [website](https://status.im), through our [nightly builds](https://status.im/nightly/) or by [building it yourself](https://status.im/technical/build_status/).
@@ -68,12 +67,8 @@ Without the dedication of these outstanding individuals, Status would not exist.
## Contact us
Feel free to email us at [support@status.im](mailto:support@status.im) or better yet, [join our chat](https://join.status.im/chat/public/status).
Feel free to email us at [support@status.im](mailto:support@status.im).
## License
Licensed under the [Mozilla Public License v2.0](https://github.com/status-im/status-mobile/blob/develop/LICENSE.md)
## Testing Supported by
[![BrowserStack Status](https://www.browserstack.com/automate/badge.svg?badge_key=SFBWQ3k5R2tnT2t6UGsxU1h1U0g3VFlCNnoxVTRHYWNoTDhsb1laaTJZWT0tLUZMUm5sSVFBSU9qSWM1RUJvK1I3Z3c9PQ==--ad15ae7992b432b33743749d40318952415bd98f)](https://www.browserstack.com/automate/public-build/SFBWQ3k5R2tnT2t6UGsxU1h1U0g3VFlCNnoxVTRHYWNoTDhsb1laaTJZWT0tLUZMUm5sSVFBSU9qSWM1RUJvK1I3Z3c9PQ==--ad15ae7992b432b33743749d40318952415bd98f)
+1 -1
View File
@@ -1,4 +1,4 @@
{
"name": "StatusIm",
"displayName": "StatusIm"
}
}
+1 -1
View File
@@ -74,7 +74,7 @@ pipeline {
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
sh """
python3 -m pytest \
--numprocesses 4 \
--numprocesses 6 \
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
+1 -1
View File
@@ -123,7 +123,7 @@ pipeline {
sh 'cp -f $TEST_ETH_ACCOUNTS_FILE users.py'
sh """
python3 -m pytest \
--numprocesses 4 \
--numprocesses 6 \
--rerun_count=2 \
--testrail_report=True \
-k \"${params.KEYWORD_EXPRESSION}\" \
+1
View File
@@ -24,6 +24,7 @@
[Patching](patching.md)
[Creating a pixel perfect UI](pixel-perfection.md)
## Testing
+1 -1
View File
@@ -45,4 +45,4 @@ The `State` field in the Pivotal story is used to track the progress of a Pivota
| 5 points | 2 - 3 days |
| 8 points | ~1 week |
We should avoid 8 point stories by breaking them down into smaller stories as much as possible.
We should avoid 8 point stories by breaking them down into smaller stories as much as possible.
Binary file not shown.

After

Width:  |  Height:  |  Size: 564 KiB

+46
View File
@@ -80,6 +80,52 @@ This mistake mostly happens with functional components
it's important to name functional components with `f-` prefix
### Component props and API scheme to match Figma as closely as possible
Ideally, the prop names for components (particularly in quo2 Design System) should match the Figma properties as best as possible. This makes it easier for the developer using that component to configure it correctly for the screen it is being used on and avoids unnecessary overwrites and adjustments being made.
#### Avoid unnecessarily grouping categories to reduce the number of props
For example in Figma if there is a component and it has the following variants:
|theme: "light" blur: "False"|theme: "dark" blur: "False"|theme: "light" blur: "True"|theme: "dark" blur: "True"|
|----------------------------|---------------------------|---------------------------|---------------------------|
| type :neutral label "ABC" | type :neutral label "ABC" | | |
| type :active label "ABC" | type :active label "ABC" | | |
| type :danger label "ABC" | type :danger label "ABC" | type :danger label "ABC" | type :danger label "ABC" |
```clojure
;; bad
"theme - :light or :dark
type - can be :neutral :active :danger :danger-blur"
(defn my-component [{:keys [theme type]} label])
;; good
"theme - :light or :dark
type - can be :neutral :active :danger
blur? - boolean
"
(defn my-component [{:keys [theme blur? type]} label])
```
Please note this is only for the external API of the component and there should be no restriction of how the component manages its internal API as that will not affect the developer using the component with the issues described above.
In some cases this is not always possible or does not make sense. However the thought process should be how easy will it be for another developer to use this component with the correct configuration given the screen designs for Figma.
#### Avoid unnecessarily renaming props
In general it can be helpful to avoid renaming props from their counterpart in Figma.
For example if Figma has sizes `:small`, `:medium` and `:large`
```clojure
;; bad
":size - :little, :default or :big"
(defn my-component [{:keys [size]}])
;; good
":size - :small, :medium or :large"
(defn my-component [{:keys [size]}])
```
### Component styles
Prefer to define styles in a separate file named `style.cljs`, colocated with
+17
View File
@@ -0,0 +1,17 @@
# Pixel Perfection
The Status Mobile team aims to align the design implementation perfectly according to a given screens respective Figma design spec.
Currently the Figma Designs match up with an "iPhone 11 Pro" screen size.
To test your implementation is correct you can take the following steps
- Open a new Figma file so that you have write privileges.
- Copy in the component or screen from the Figma file.
- Using the "iPhone 11 Pro" simulator (it is the default now) you take a screenshot of your component and paste it into your Figma file.
- To get the right size, set your screenshot to width 375px
![](images/pixel-perfection/layer-width.png)
- Lower the opacity so you can see it sitting on top of the Figma mock ups.
+1 -1
View File
@@ -3,4 +3,4 @@
"version" : 1,
"author" : "xcode"
}
}
}
@@ -833,6 +833,37 @@ void _SaveAccountAndLogin(const FunctionCallbackInfo<Value>& args) {
}
void _CreateAccountAndLogin(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 1) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for SaveAccountAndLogin")));
return;
}
// Check the argument types
if (!args[0]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'settingsJSON'")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
char *arg0 = *arg0Obj;
// Call exported Go function, which returns a C string
char *c = CreateAccountAndLogin(arg0);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
delete c;
}
void _GenerateAlias(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
@@ -1929,6 +1960,7 @@ void init(Local<Object> exports) {
NODE_SET_METHOD(exports, "hashMessage", _HashMessage);
NODE_SET_METHOD(exports, "resetChainData", _ResetChainData);
NODE_SET_METHOD(exports, "saveAccountAndLogin", _SaveAccountAndLogin);
NODE_SET_METHOD(exports, "createAccountAndLogin", _CreateAccountAndLogin);
NODE_SET_METHOD(exports, "generateAlias", _GenerateAlias);
NODE_SET_METHOD(exports, "validateMnemonic", _ValidateMnemonic);
NODE_SET_METHOD(exports, "multiformatSerializePublicKey", _MultiformatSerializePublicKey);
+1 -1
View File
@@ -18,4 +18,4 @@
"url": "https://github.com/status-im/react-native-status/issues"
},
"homepage": "https://github.com/status-im/react-native-status#readme"
}
}
+1 -1
View File
@@ -194,4 +194,4 @@
}
}
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 213 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 540 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 KiB

Binary file not shown.
Binary file not shown.
Binary file not shown.
+33
View File
@@ -0,0 +1,33 @@
#!/usr/bin/env bash
set -eof pipefail
FILES=$(comm -23 <(sort <(git ls-files --cached --others --exclude-standard)) <(sort <(git ls-files --deleted)) | grep --ignore-case -E '\.(java|cpp|nix|json|sh|md|js|clj|cljs|cljc|edn)$')
N_FILES=$(echo "$FILES" | wc -l)
LINT_SHOULD_FIX=0
if [[ -n $1 && $1 != '--fix' ]]; then
echo "Unknown option '$1'" >&2
exit 1
elif [[ $1 == '--fix' ]]; then
LINT_SHOULD_FIX=1
fi
echo "Checking ${N_FILES} files for missing trailing newlines."
# Do not process the whole file and only check the last character. Ignore empty
# files. Taken from https://stackoverflow.com/a/10082466.
for file in $FILES; do
if [ -s "$file" ] && [ "$(tail -c1 "$file"; echo x)" != $'\nx' ]; then
if [[ $LINT_SHOULD_FIX -eq 1 ]]; then
echo "" >>"$file"
else
LINT_ERROR=1
echo "No trailing newline: $file" >&2
fi
fi
done
if [[ $LINT_ERROR -eq 1 ]]; then
exit 1
fi
+10 -10
View File
@@ -1,18 +1,18 @@
import { Easing } from 'react-native-reanimated';
// Home Stack States
export const CLOSE_WITH_ANIMATION = 0;
export const OPEN_WITH_ANIMATION = 1;
export const CLOSE_WITHOUT_ANIMATION = 2;
export const OPEN_WITHOUT_ANIMATION = 3;
export const CLOSE_WITHOUT_ANIMATION = 0;
export const OPEN_WITHOUT_ANIMATION = 1;
export const CLOSE_WITH_ANIMATION = 2;
export const OPEN_WITH_ANIMATION = 3;
// Floating Screen States
export const CLOSE_SCREEN_WITH_SLIDE_ANIMATION = 0;
export const OPEN_SCREEN_WITH_SLIDE_ANIMATION = 1;
export const CLOSE_SCREEN_WITH_SHELL_ANIMATION = 2;
export const OPEN_SCREEN_WITH_SHELL_ANIMATION = 3;
export const CLOSE_SCREEN_WITHOUT_ANIMATION = 4;
export const OPEN_SCREEN_WITHOUT_ANIMATION = 5;
export const CLOSE_SCREEN_WITHOUT_ANIMATION = 0;
export const OPEN_SCREEN_WITHOUT_ANIMATION = 1;
export const CLOSE_SCREEN_WITH_SLIDE_ANIMATION = 2;
export const OPEN_SCREEN_WITH_SLIDE_ANIMATION = 3;
export const CLOSE_SCREEN_WITH_SHELL_ANIMATION = 4;
export const OPEN_SCREEN_WITH_SHELL_ANIMATION = 5;
export const SHELL_ANIMATION_TIME = 200;
+3 -3
View File
@@ -287,11 +287,11 @@
and then compressed. Example input/output :
input key = zQ3shTAten2v9CwyQD1Kc7VXAqNPDcHZAMsfbLHCZEx6nFqk9 and
output key = 0x025596a7ff87da36860a84b0908191ce60a504afc94aac93c1abd774f182967ce6"
[key callback]
[input-key callback]
(log/info "[native-module] Deserializing and then compressing public key"
{:fn :deserialize-and-compress-key
:key key})
(.deserializeAndCompressKey ^js (status) key callback))
:key input-key})
(.deserializeAndCompressKey ^js (status) input-key callback))
(defn compressed-key->public-key
"Provides compressed key to status-go and gets back the uncompressed public key via deserialization"
-25
View File
@@ -235,31 +235,6 @@
[value velocity snap-points]
(.snapPoint ^js redash value velocity (to-array snap-points)))
(defn cancelable-loop
[{:keys [clock duration finished on-reach]}]
(let [time (value 0)
frame-time (value 0)
position (value 0)
to-value (value 1)
state {:time time
:frameTime frame-time
:finished finished
:position position}
config {:toValue to-value
:duration duration
:easing (:linear easings)}]
(block
[(timing clock state config)
(cond* (and* finished
(eq position to-value))
(call* [] on-reach))
(cond* finished
[(set finished 0)
(set time 0)
(set frame-time 0)
(set position 0)])
position])))
(defn with-easing
[{val :value
:keys [snap-points velocity offset state easing duration
+1 -1
View File
@@ -11,4 +11,4 @@
(for [i (keys icons/icons)]
[rn/view {:flex-direction :row}
[icons/icon (keyword i)]
[rn/text i]])])
[rn/text i]])])
-7
View File
@@ -1,12 +1,5 @@
(ns quo.previews.preview)
(defn descriptor->values
[{:keys [key options type]}]
{key (case type
:boolean [false true]
:text [nil "Just simple text"] ; NOTE(Ferossgp): add example with long text?
:select (mapv :key options))})
(defmacro list-comp
[[binding seq-expr & bindings] body-expr]
(cond (not binding)
+18 -20
View File
@@ -68,8 +68,8 @@
:background-color (:ui-background @colors/theme)})
(defn customizer-boolean
[{:keys [label key state]}]
(let [state* (reagent/cursor state [key])]
[{:keys [label state] :as args}]
(let [state* (reagent/cursor state [(:key args)])]
[rn/view {:style container}
[label-view state label]
[rn/view
@@ -95,8 +95,8 @@
"False"]]]]))
(defn customizer-text
[{:keys [label key state]}]
(let [state* (reagent/cursor state [key])]
[{:keys [label state] :as args}]
(let [state* (reagent/cursor state [(:key args)])]
[rn/view {:style container}
[label-view state label]
[rn/view {:style {:flex 0.6}}
@@ -117,8 +117,8 @@
(defn customizer-select
[]
(let [open (reagent/atom nil)]
(fn [{:keys [label key state options]}]
(let [state* (reagent/cursor state [key])
(fn [{:keys [label state options] :as args}]
(let [state* (reagent/cursor state [(:key args)])
selected (value-for-key @state* options)]
[rn/view {:style container}
[label-view state label]
@@ -133,15 +133,15 @@
[rn/view {:style (modal-view)}
[rn/scroll-view
(doall
(for [{:keys [key value]} options]
^{:key key}
(for [{k :key v :value} options]
^{:key k}
[rn/touchable-opacity
{:style (select-option-style (= @state* key))
{:style (select-option-style (= @state* k))
:on-press #(do
(reset! open false)
(reset! state* key))}
[quo/text {:color (if (= @state* key) :link :secondary)}
value]]))
(reset! state* k))}
[quo/text {:color (if (= @state* k) :link :secondary)}
v]]))
[rn/view {:flex-direction :row}
[rn/touchable-opacity
{:style (select-option-style false)
@@ -175,17 +175,15 @@
{:style {:flex 1}
:padding-horizontal 16}
(doall
(for [{:keys [key type]
:as desc}
descriptors
:let [descriptor (merge desc
{:state state})]]
^{:key key}
(for [desc descriptors
:let [descriptor (merge desc {:state state})]]
^{:key (:key desc)}
[:<>
(case type
(case (:type desc)
:boolean [customizer-boolean descriptor]
:text [customizer-text descriptor]
:select [customizer-select descriptor])]))])
:select [customizer-select descriptor]
nil)]))])
(comment
[{:label "Show error:"
@@ -1,50 +0,0 @@
(ns quo2.components.avatars.channel-avatar
(:require [quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]))
(defn channel-avatar
[{:keys [big? locked? emoji-background-color emoji]}]
(let [lock-exists? locked?
dark? (theme/dark?)]
[rn/view
{:style {:width (if big? 32 24)
:height (if big? 32 24)
:border-radius (if big? 32 24)
:justify-content :center
:align-items :center
:background-color emoji-background-color}}
[rn/view
{:style {:display :flex
:justify-content :center
:align-items :center}}
[text/text
{:size (if big?
:paragraph-1
:label)} emoji]
(when lock-exists?
[rn/view
{:style {:position :absolute
:left (if big?
14
8)
:top (if big?
15
8)
:background-color (if dark?
colors/neutral-90
colors/white)
:border-radius 15
:padding 2}}
[icons/icon
(if locked?
:main-icons/locked
:main-icons/unlocked)
{:color (if dark?
colors/neutral-40
colors/neutral-50)
:container-style {:width 12
:height 12}
:size 12}]])]]))
@@ -0,0 +1,35 @@
(ns quo2.components.avatars.channel-avatar.component-spec
(:require [quo2.components.avatars.channel-avatar.view :as component]
[test-helpers.component :as h]))
(h/describe "Channel Avatar"
(h/test "default render"
(h/render [component/view])
(h/is-truthy (h/query-by-label-text :initials))
(h/is-null (h/query-by-label-text :emoji))
(h/is-null (h/query-by-label-text :lock)))
(h/test "with emoji, no lock set, large size"
(let [emoji "🍓"]
(h/render [component/view {:emoji emoji :size :size/l}])
(h/is-null (h/query-by-label-text :initials))
(h/is-truthy (h/query-by-text emoji))
(h/is-null (h/query-by-label-text :lock))))
(h/test "locked"
(h/render [component/view {:locked? true}])
(h/is-truthy (h/query-by-label-text :lock)))
(h/test "unlocked"
(h/render [component/view {:locked? false}])
(h/is-truthy (h/query-by-label-text :lock)))
(h/test "no emoji, smaller size"
(h/render [component/view {:full-name "Status Mobile"}])
(h/is-truthy (h/query-by-text "S")))
(h/test "no emoji, large size"
(h/render [component/view
{:full-name "Status Mobile"
:size :size/l}])
(h/is-truthy (h/query-by-text "SM"))))
@@ -0,0 +1,28 @@
(ns quo2.components.avatars.channel-avatar.style
(:require [quo2.foundations.colors :as colors]))
(def lock-icon-size 12)
(defn outer-container
[{:keys [size color]}]
(let [size (if (= size :size/l) 32 24)]
{:width size
:height size
:border-radius size
:justify-content :center
:align-items :center
:background-color (colors/theme-alpha color 0.1 0.1)}))
(defn lock-container
[size]
(let [distance (if (= size :size/l) 20 12)]
{:position :absolute
:left distance
:top distance
:background-color (colors/theme-colors colors/white colors/neutral-95)
:border-radius (* 2 lock-icon-size)
:padding 2}))
(def lock-icon
{:width lock-icon-size
:height lock-icon-size})
@@ -0,0 +1,60 @@
(ns quo2.components.avatars.channel-avatar.view
(:require [clojure.string :as string]
[quo2.components.avatars.channel-avatar.style :as style]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
utils.string))
(defn- initials
[full-name size color]
(let [amount-initials (if (= size :size/l) 2 1)]
[text/text
{:accessibility-label :initials
:size :paragraph-2
:weight :semi-bold
:style {:color color}}
(utils.string/get-initials full-name amount-initials)]))
(defn- lock
[locked? size]
;; When `locked?` is nil, we must not display the unlocked icon.
(when (boolean? locked?)
[rn/view
{:accessibility-label :lock
:style (style/lock-container size)}
[icons/icon (if locked? :i/locked :i/unlocked)
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40)
:container-style style/lock-icon
:size 12}]]))
(defn view
"Options:
:size - keyword (default nil) - Container size, for the moment,
only :size/l (meaning large) is supported.
:emoji - string (default nil)
:customization-color - color (default nil) If the component is used for a
community channel, then the default color should be the community custom
color.
:locked? - nil/bool (default nil) - When true/false display a locked/unlocked
icon respectively. When nil does not show icon.
:full-name - string (default nil) - When :emoji is blank, this value will be
used to extract the initials.
"
[{:keys [size emoji customization-color locked? full-name]}]
[rn/view
{:accessibility-label :channel-avatar
:style (style/outer-container {:size size :color customization-color})}
(if (string/blank? emoji)
[initials full-name size customization-color]
[text/text
{:accessibility-label :emoji
:size (if (= size :size/l) :paragraph-1 :label)}
(string/trim emoji)])
[lock locked? size]])
@@ -1,22 +1,9 @@
(ns quo2.components.avatars.user-avatar.view
(:require [clojure.string :as string]
[quo2.components.avatars.user-avatar.style :as style]
(:require [quo2.components.avatars.user-avatar.style :as style]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]))
(defn trim-whitespace [s] (string/join " " (string/split (string/trim s) #"\s+")))
(defn- extract-initials
[full-name amount-initials]
(let [upper-case-first-letter (comp string/upper-case first)
names-list (string/split (trim-whitespace full-name) " ")]
(if (= (first names-list) "")
""
(->> names-list
(map upper-case-first-letter)
(take amount-initials)
(string/join)))))
[react-native.fast-image :as fast-image]
utils.string))
(defn initials-avatar
[{:keys [full-name size draw-ring? customization-color]}]
@@ -29,7 +16,7 @@
{:style style/initials-avatar-text
:size font-size
:weight :semi-bold}
(extract-initials full-name amount-initials)]]))
(utils.string/get-initials full-name amount-initials)]]))
(def valid-ring-sizes #{:big :medium :small})
@@ -1,28 +0,0 @@
(ns quo2.components.buttons.--tests--.buttons-component-spec
(:require ["@testing-library/react-native" :as rtl]
[quo2.components.buttons.button :as button]
[reagent.core :as reagent]))
(defn render-button
([options label]
(rtl/render (reagent/as-element [button/button options label]))))
(js/global.test "default render of button component"
(fn []
(render-button {:accessibility-label "test-button"} "")
(-> (js/expect (rtl/screen.getByLabelText "test-button"))
(.toBeTruthy))))
(js/global.test "button renders with a label"
(fn []
(render-button {} "test-label")
(-> (js/expect (rtl/screen.getByText "test-label"))
(.toBeTruthy))))
(js/global.test "button on-press works"
(let [event (js/jest.fn)]
(fn []
(render-button {:on-press event} "test-label")
(rtl/fireEvent.press (rtl/screen.getByText "test-label"))
(-> (js/expect event)
(.toHaveBeenCalledTimes 1)))))
@@ -0,0 +1,18 @@
(ns quo2.components.buttons.button.component-spec
(:require [quo2.components.buttons.button.view :as button]
[test-helpers.component :as h]))
(h/describe "button tests"
(h/test "default render of button component"
(h/render [button/button {:accessibility-label "test-button"} ""])
(h/is-truthy (h/get-by-label-text "test-button")))
(h/test "button renders with a label"
(h/render [button/button {} "test-label"])
(h/is-truthy (h/get-by-text "test-label")))
(h/test "button on-press works"
(let [event (h/mock-fn)]
(h/render [button/button {:on-press event} "test-label"])
(h/fire-event :press (h/get-by-text "test-label"))
(h/was-called event))))
@@ -1,12 +1,46 @@
(ns quo2.components.buttons.button
(:require [quo2.components.icon :as quo2.icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]
[react-native.blur :as blur]
[reagent.core :as reagent]
[quo2.components.buttons.style :as style]))
(ns quo2.components.buttons.button.style
(:require [quo2.foundations.colors :as colors]))
(def blur-view
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0})
(defn before-icon-style
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
icon-size]}]
(merge
{:margin-left (or (get override-margins :left)
(if (= size 40) 12 8))
:margin-right (or (get override-margins :right) 4)
:align-items :center
:justify-content :center}
(when icon-container-size
{:width icon-container-size
:height icon-container-size})
(when icon-background-color
{:background-color icon-background-color})
(when icon-container-rounded?
{:border-radius (/ (or icon-container-size icon-size) 2)})))
(defn after-icon-style
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
icon-size]}]
(merge
{:margin-left (or (get override-margins :left) 4)
:margin-right (or (get override-margins :right)
(if (= size 40) 12 8))
:align-items :center
:justify-content :center}
(when icon-container-size
{:width icon-container-size
:height icon-container-size})
(when icon-background-color
{:background-color icon-background-color})
(when icon-container-rounded?
{:border-radius (/ (or icon-container-size icon-size) 2)})))
(defn themes
[customization-color]
@@ -179,7 +213,7 @@
24 8))})
(defn style-container
[type size disabled background-color border-color icon above width before after blur-active?]
[{:keys [type size disabled background-color border-color icon above width before after blur-active?]}]
(merge {:height size
:align-items :center
:justify-content :center
@@ -228,132 +262,3 @@
:border-width 1})
(when disabled
{:opacity 0.3})))
(defn- button-internal
"with label
[button opts \"label\"]
opts
{:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/
:danger/:photo-bg/:blur-bg/:blur-bg-outline/:shell/:community
:size 40 [default] /32/24
:icon true/false
:community-color '#FFFFFF'
:community-text-color '#000000'
:before :icon-keyword
:after :icon-keyword}
only icon
[button {:icon true} :i/close-circle]"
[_ _]
(let [pressed-in (reagent/atom false)]
(fn
[{:keys [on-press disabled type size before after above icon-secondary-no-color
width customization-color theme override-background-color pressed
on-long-press accessibility-label icon icon-no-color style inner-style test-ID
blur-active? override-before-margins override-after-margins icon-size icon-container-size
icon-container-rounded?]
:or {type :primary
size 40
customization-color :primary
blur-active? true}}
children]
(let [{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type
blur-overlay-color icon-background-color]}
(get-in (themes customization-color)
[theme type])
state (cond disabled :disabled
(or @pressed-in pressed) :pressed
:else :default)
blur-state (if blur-active? :blurred :default)
icon-size (or icon-size (when (= 24 size) 12))
icon-secondary-color (or icon-secondary-color icon-color)]
[rn/touchable-without-feedback
(merge {:test-ID test-ID
:disabled disabled
:accessibility-label accessibility-label
:on-press-in #(reset! pressed-in true)
:on-press-out #(reset! pressed-in nil)}
(when on-press
{:on-press on-press})
(when on-long-press
{:on-long-press on-long-press}))
[rn/view
{:style (merge
(shape-style-container type icon size)
{:width width}
style)}
[rn/view
{:style (merge
(style-container
type
size
disabled
(or override-background-color (get background-color state))
(get border-color state)
icon
above
width
before
after
blur-active?)
(when (= state :pressed) {:opacity 0.9})
inner-style)}
(when (and (= type :blurred)
blur-active?)
[blur/view
{:blur-radius 20
:blur-type blur-type
:overlay-color blur-overlay-color
:style style/blur-view}])
(when above
[rn/view
[quo2.icons/icon above
{:container-style {:margin-bottom 2}
:color icon-secondary-color
:size icon-size}]])
(when before
[rn/view
{:style (style/before-icon-style
{:override-margins override-before-margins
:size size
:icon-container-size icon-container-size
:icon-background-color (get icon-background-color blur-state)
:icon-container-rounded? icon-container-rounded?
:icon-size icon-size})}
[quo2.icons/icon before
{:color icon-secondary-color
:size icon-size}]])
[rn/view
(cond
(or icon icon-no-color)
[quo2.icons/icon children
{:color icon-color
:no-color icon-no-color
:size icon-size}]
(string? children)
[text/text
{:size (when (#{56 24} size) :paragraph-2)
:weight :medium
:number-of-lines 1
:style {:color label-color}}
children]
(vector? children)
children)]
(when after
[rn/view
{:style (style/after-icon-style
{:override-margins override-after-margins
:size size
:icon-container-size icon-container-size
:icon-background-color (get icon-background-color blur-state)
:icon-container-rounded? icon-container-rounded?
:icon-size icon-size})}
[quo2.icons/icon after
{:no-color icon-secondary-no-color
:color icon-secondary-color
:size icon-size}]])]]]))))
(def button (theme/with-theme button-internal))
@@ -0,0 +1,138 @@
(ns quo2.components.buttons.button.view
(:require [quo2.components.icon :as quo2.icons]
[quo2.components.markdown.text :as text]
[quo2.theme :as theme]
[react-native.core :as rn]
[react-native.blur :as blur]
[reagent.core :as reagent]
[quo2.components.buttons.button.style :as style]))
(defn- button-internal
"with label
[button opts \"label\"]
opts
{:type :primary/:secondary/:grey/:dark-grey/:outline/:ghost/
:danger/:photo-bg/:blur-bg/:blur-bg-outline/:shell/:community
:size 40 [default] /32/24
:icon true/false
:community-color '#FFFFFF'
:community-text-color '#000000'
:before :icon-keyword
:after :icon-keyword}
only icon
[button {:icon true} :i/close-circle]"
[_ _]
(let [pressed-in (reagent/atom false)]
(fn
[{:keys [on-press disabled type size before after above icon-secondary-no-color
width customization-color theme override-background-color pressed
on-long-press accessibility-label icon icon-no-color style inner-style test-ID
blur-active? override-before-margins override-after-margins icon-size icon-container-size
icon-container-rounded?]
:or {type :primary
size 40
customization-color :primary
blur-active? true}}
children]
(let [{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type
blur-overlay-color icon-background-color]}
(get-in (style/themes customization-color)
[theme type])
state (cond disabled :disabled
(or @pressed-in pressed) :pressed
:else :default)
blur-state (if blur-active? :blurred :default)
icon-size (or icon-size (when (= 24 size) 12))
icon-secondary-color (or icon-secondary-color icon-color)]
[rn/touchable-without-feedback
(merge {:test-ID test-ID
:disabled disabled
:accessibility-label accessibility-label
:on-press-in #(reset! pressed-in true)
:on-press-out #(reset! pressed-in nil)}
(when on-press
{:on-press on-press})
(when on-long-press
{:on-long-press on-long-press}))
[rn/view
{:style (merge
(style/shape-style-container type icon size)
{:width width}
style)}
[rn/view
{:style (merge
(style/style-container {:type type
:size size
:disabled disabled
:background-color
(or override-background-color (get background-color state))
:border-color
(get border-color state)
:icon icon
:above above
:width width
:before before
:after after
:blur-active? blur-active?})
(when (= state :pressed) {:opacity 0.9})
inner-style)}
(when (and (= type :blurred)
blur-active?)
[blur/view
{:blur-radius 20
:blur-type blur-type
:overlay-color blur-overlay-color
:style style/blur-view}])
(when above
[rn/view
[quo2.icons/icon above
{:container-style {:margin-bottom 2}
:color icon-secondary-color
:size icon-size}]])
(when before
[rn/view
{:style (style/before-icon-style
{:override-margins override-before-margins
:size size
:icon-container-size icon-container-size
:icon-background-color (get icon-background-color blur-state)
:icon-container-rounded? icon-container-rounded?
:icon-size icon-size})}
[quo2.icons/icon before
{:color icon-secondary-color
:size icon-size}]])
[rn/view
(cond
(or icon icon-no-color)
[quo2.icons/icon children
{:color icon-color
:no-color icon-no-color
:size icon-size}]
(string? children)
[text/text
{:size (when (#{56 24} size) :paragraph-2)
:weight :medium
:number-of-lines 1
:style {:color label-color}}
children]
(vector? children)
children)]
(when after
[rn/view
{:style (style/after-icon-style
{:override-margins override-after-margins
:size size
:icon-container-size icon-container-size
:icon-background-color (get icon-background-color blur-state)
:icon-container-rounded? icon-container-rounded?
:icon-size icon-size})}
[quo2.icons/icon after
{:no-color icon-secondary-no-color
:color icon-secondary-color
:size icon-size}]])]]]))))
(def button (theme/with-theme button-internal))
@@ -62,7 +62,7 @@
:customization-color customize jump-to and mention button color}"
[_]
(let [pressed? (reagent/atom false)]
(fn [{:keys [type label on-press count customization-color style]}]
(fn [{:keys [type label on-press customization-color style] :as args}]
[rn/touchable-opacity
{:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? false)
@@ -102,6 +102,6 @@
(case type
:jump-to label
:search-with-label label
(:mention :notification-down :notification-up) (str count))])
(:mention :notification-down :notification-up) (str (:count args)))])
(when (#{:jump-to :notification-down :notification-up} type)
[icon-view type])]])))
@@ -2,9 +2,10 @@
(:require [react-native.core :as rn]
[quo2.components.buttons.predictive-keyboard.style :as style]
[quo2.components.info.info-message :as info-message]
[quo2.theme :as theme]
[react-native.linear-gradient :as linear-gradient]
[quo2.foundations.colors :as colors]
[quo2.components.buttons.button :as button]))
[quo2.components.buttons.button.view :as button]))
(def ^:private gradients
{:light [(colors/alpha colors/neutral-40 0.05) (colors/alpha colors/neutral-40 0)]
@@ -12,32 +13,33 @@
:blur [colors/white-opa-5 colors/white-opa-0]})
(defn- word-component
[word _ _ {:keys [blur? on-press]}]
[word _ _ {:keys [on-press]}]
[button/button
(merge {:type :blur-bg
:size 32
:on-press #(on-press word)}
(when blur? {:override-theme :dark}))
{:type :blur-bg
:size 32
:on-press #(on-press word)}
word])
(defn- separator
[]
[rn/view {:style {:width 8}}])
(defn view
(defn- view-internal
"Options
- `type` `:words`/`:error`/`:info`/`:empty`.
- `blur?` Boolean to enable blur background support.
- `text` error/info text.
- `words` List of words to display in the keyboard.
- `on-press` Callback called when a word is pressed `(fn [word])`."
[{:keys [type blur? text words on-press]}]
- `on-press` Callback called when a word is pressed `(fn [word])`
- `theme` :light or :dark, received from with-theme HOC."
[{:keys [type blur? text words on-press theme]}]
[linear-gradient/linear-gradient
{:style {:flex-direction :row}
:accessibility-label :predictive-keyboard
:colors (if blur?
(gradients :blur)
(colors/theme-colors (gradients :light) (gradients :dark)))}
(colors/theme-colors (gradients :light) (gradients :dark) theme))}
[rn/view {:style (style/wrapper type)}
(case type
:words
@@ -46,8 +48,7 @@
:data words
:content-container-style style/word-list
:render-fn word-component
:render-data {:blur? blur?
:on-press on-press}
:render-data {:on-press on-press}
:shows-horizontal-scroll-indicator false
:separator [separator]
:horizontal true
@@ -70,3 +71,5 @@
:icon-color colors/white-opa-70}))
text]
nil)]])
(def view (theme/with-theme view-internal))
-42
View File
@@ -1,42 +0,0 @@
(ns quo2.components.buttons.style)
(def blur-view
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0})
(defn before-icon-style
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
icon-size]}]
(merge
{:margin-left (or (get override-margins :left)
(if (= size 40) 12 8))
:margin-right (or (get override-margins :right) 4)
:align-items :center
:justify-content :center}
(when icon-container-size
{:width icon-container-size
:height icon-container-size})
(when icon-background-color
{:background-color icon-background-color})
(when icon-container-rounded?
{:border-radius (/ (or icon-container-size icon-size) 2)})))
(defn after-icon-style
[{:keys [override-margins size icon-container-size icon-background-color icon-container-rounded?
icon-size]}]
(merge
{:margin-left (or (get override-margins :left) 4)
:margin-right (or (get override-margins :right)
(if (= size 40) 12 8))
:align-items :center
:justify-content :center}
(when icon-container-size
{:width icon-container-size
:height icon-container-size})
(when icon-background-color
{:background-color icon-background-color})
(when icon-container-rounded?
{:border-radius (/ (or icon-container-size icon-size) 2)})))
+1 -1
View File
@@ -1,7 +1,7 @@
(ns quo2.components.code.snippet
(:require [cljs-bean.core :as bean]
[clojure.string :as string]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.code.code.style :as style]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]
@@ -1,4 +1,4 @@
(ns quo2.components.separator
(ns quo2.components.common.separator.view
(:require [quo2.foundations.colors :as quo2.colors]
[react-native.core :as rn]))
@@ -3,6 +3,7 @@
[quo2.components.community.style :as style]
[quo2.components.counter.counter :as counter]
[quo2.components.icon :as icons]
[quo2.theme :as theme]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.community.icon :as community-icon]
@@ -21,8 +22,8 @@
:resize-mode :center
:size 20
:color (colors/theme-colors
colors/neutral-40
colors/neutral-50)}]
colors/neutral-50
colors/neutral-40)}]
(pos? unread-mentions-count)
[counter/counter {:type :default} unread-mentions-count]
@@ -34,7 +35,7 @@
{:keys [name
locked?
status
muted?
muted
unread-messages?
unread-mentions-count
community-icon
@@ -59,7 +60,7 @@
:accessibility-label :community-name-text
:number-of-lines 1
:ellipsize-mode :tail
:style {:color (when muted?
:style {:color (when muted
(colors/theme-colors
colors/neutral-40
colors/neutral-60))}}
@@ -71,14 +72,15 @@
{:locked? locked?
:tokens tokens}]
[notification-view
{:muted? muted?
{:muted? muted
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]])
(defn communities-membership-list-item
[props
bottom-sheet?
{:keys [name
muted?
muted
unviewed-messages-count
unviewed-mentions-count
status
@@ -105,17 +107,22 @@
:number-of-lines 1
:ellipsize-mode :tail
:weight :semi-bold
:size :paragraph-1}
:size :paragraph-1
:style (when muted
{:color (if (theme/dark?)
colors/neutral-60
colors/neutral-40)})}
name]]
[rn/view
{:justify-content :center
:margin-right 16}
:margin-right (when bottom-sheet?
16)}
(if (= status :gated)
[community-view/permission-tag-container
{:locked? locked?
:tokens tokens}]
[notification-view
{:muted? muted?
{:muted? muted
:unread-mentions-count unviewed-mentions-count
:unread-messages? (pos? unviewed-messages-count)}])]]])
@@ -5,13 +5,17 @@
[quo2.components.tags.permission-tag :as permission]
[quo2.components.tags.tag :as tag]
[quo2.foundations.colors :as colors]
[quo.gesture-handler :as gesture-handler] ;;TODO move to quo2
[react-native.core :as rn]))
[quo2.theme :as theme]
[react-native.core :as rn]
[react-native.gesture :as gesture]
utils.money))
(defn community-stats
[{:keys [icon members-count icon-color]}]
[rn/view (style/stats-count-container)
[rn/view {:margin-right 4}
[{:keys [icon members-count icon-color accessibility-label]}]
[rn/view
{:accessibility-label accessibility-label
:style (style/stats-count-container)}
[rn/view {:margin-right 2}
[icons/icon icon
{:container-style {:align-items :center
:justify-content :center}
@@ -20,29 +24,32 @@
:color icon-color}]]
[text/text
{:weight :regular
:size :paragraph-1}
:size :paragraph-2}
members-count]])
(defn community-stats-column
[{:keys [type]}]
(let [icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40)]
[{:keys [type theme blur? members-count active-count]}]
(let [icon-color (if (and (= :dark theme) blur?)
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))]
[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}]
{:accessibility-label :stats-members-count
:icon :i/group
:members-count (utils.money/format-amount members-count)
:icon-color icon-color}]
[community-stats
{:icon :i/lightning
:members-count "112.1K"
:icon-color icon-color}]]))
{:accessibility-label :stats-active-count
:icon :i/active-members
:members-count (utils.money/format-amount active-count)
:icon-color icon-color}]]))
(defn community-tags
[{:keys [tags container-style last-item-style]}]
[gesture-handler/scroll-view
[gesture/scroll-view
{:shows-horizontal-scroll-indicator false
:horizontal true
:style container-style}
@@ -84,13 +91,16 @@
:style {:margin-top (if (= size :large) 8 2)}}
description])])
(defn permission-tag-container
[{:keys [locked? tokens on-press]}]
(defn- permission-tag-container-internal
[{:keys [locked? blur? tokens on-press theme]}]
[permission/tag
{:background-color (colors/theme-colors
colors/neutral-10
colors/neutral-80)
:locked? locked?
:tokens tokens
:size 24
:on-press on-press}])
{:accessibility-label :permission-tag
:background-color (if (and (= :dark theme) blur?)
colors/white-opa-10
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))
:locked? locked?
:tokens tokens
:size 24
:on-press on-press}])
(def permission-tag-container (theme/with-theme permission-tag-container-internal))
+2 -2
View File
@@ -17,8 +17,8 @@
:outline colors/neutral-70}})
(defn get-color
[key]
(get-in themes [(theme/get-theme) key]))
[k]
(get-in themes [(theme/get-theme) k]))
(defn counter
[{:keys [type override-text-color override-bg-color style accessibility-label max-value]
+5 -5
View File
@@ -14,11 +14,11 @@
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-10 theme)
(colors/theme-colors colors/neutral-20 colors/neutral-80 theme)))
(def active-background-color (colors/custom-color :blue 50 10))
(def complete-background-color (colors/custom-color :blue 50))
(defn active-background-color [customization-color] (colors/custom-color customization-color 50 10))
(defn complete-background-color [customization-color] (colors/custom-color customization-color 50))
(defn container
[size type in-blur-view? theme]
[{:keys [size type in-blur-view? theme customization-color]}]
(cond-> container-base
(#{1 2} size) (assoc :width 20)
(= size 3) (assoc :width 28)
@@ -28,10 +28,10 @@
:border-color (neutral-border-color in-blur-view? theme))
(= type :active)
(assoc :background-color active-background-color)
(assoc :background-color (active-background-color customization-color))
(= type :complete)
(assoc :background-color complete-background-color)))
(assoc :background-color (complete-background-color customization-color))))
(defn text-color
([type] (text-color type nil))
+8 -4
View File
@@ -6,8 +6,8 @@
[react-native.core :as rn]
[utils.number]))
(defn themed-step
[{:keys [type accessibility-label theme in-blur-view?]} value]
(defn step-internal
[{:keys [type accessibility-label theme in-blur-view? customization-color]} value]
(let [type (or type :neutral)
value (utils.number/parse-int value)
label (str value)
@@ -15,10 +15,14 @@
[rn/view
{:accessible true
:accessibility-label (or accessibility-label :step-counter)
:style (style/container size type in-blur-view? theme)}
:style (style/container {:size size
:type type
:in-blur-view? in-blur-view?
:theme theme
:customization-color customization-color})}
[text/text
{:weight :medium
:size :label
:style {:color (style/text-color type theme)}} label]]))
(def step (theme/with-theme themed-step))
(def step (theme/with-theme step-internal))
+1 -1
View File
@@ -1,6 +1,6 @@
(ns quo2.components.dividers.date
(:require [quo2.components.markdown.text :as text]
[quo2.components.separator :as separator]
[quo2.components.common.separator.view :as separator]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
+11 -11
View File
@@ -1,8 +1,8 @@
(ns quo2.components.dividers.divider-label
(:require [quo2.theme :as theme]
[quo2.components.icon :as icons]
(:require [quo2.components.icon :as icons]
[quo2.components.markdown.text :as markdown.text]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]))
(def chevron-icon-container-width 20)
@@ -36,18 +36,18 @@
padding-top (if increase-padding-top? 16 8)
text-and-icon-color (if dark? colors/neutral-40 colors/neutral-50)
counter-text-color (if dark? colors/white colors/neutral-100)]
[rn/touchable-without-feedback
{:on-press on-press}
[rn/touchable-without-feedback {:on-press on-press}
[rn/view
{:accessible true
:accessibility-label :divider-label
:style (merge {:border-top-width 1
:border-top-color border-and-counter-bg-color
:padding-top padding-top
:padding-bottom padding-bottom
:padding-horizontal 16
:align-items :center
:flex-direction :row}
:style (merge {:border-top-width 1
:border-top-color border-and-counter-bg-color
:padding-top padding-top
:padding-bottom padding-bottom
:padding-left 16
:padding-right 16
:align-items :center
:flex-direction :row}
container-style)}
(when (= chevron-position :left)
[rn/view
@@ -2,9 +2,9 @@
(:require [quo2.foundations.colors :as colors]))
(defn divider
[]
[theme]
{:border-top-width 1
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-90)
:border-top-color (colors/theme-colors colors/neutral-10 colors/neutral-90 theme)
:margin-top 8
:margin-bottom 7
:align-items :center
@@ -45,6 +45,6 @@
:width 20})
(defn right-text
[override-theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)
[theme]
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:margin-right 12})
@@ -1,20 +1,21 @@
(ns quo2.components.drawers.action-drawers.view
(:require [quo2.components.icon :as icon]
(:require [react-native.core :as rn]
[quo2.components.drawers.action-drawers.style :as style]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[quo2.components.drawers.action-drawers.style :as style]))
[quo2.theme :as quo.theme]))
(defn- get-icon-color
[danger? override-theme]
[danger? theme]
(if danger?
colors/danger-60
(colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)))
(colors/theme-colors colors/danger-50 colors/danger-60 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn- divider
[]
[theme]
[rn/view
{:style (style/divider)
{:style (style/divider theme)
:accessible true
:accessibility-label :divider}])
@@ -24,7 +25,7 @@
[rn/view (dissoc props :on-press) child]
[rn/touchable-highlight props child]))
(defn- action
(defn- action-internal
[{:keys [icon
label
sub-label
@@ -34,65 +35,66 @@
disabled?
on-press
add-divider?
override-theme
theme
accessibility-label
icon-color]
:as action-props}]
(when action-props
[:<> {:key label}
(when add-divider?
[divider])
[maybe-pressable disabled?
{:accessibility-label accessibility-label
:style (style/container sub-label disabled?)
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 override-theme)
:on-press on-press}
[rn/view
{:style (style/row-container sub-label)}
[rn/view
{:accessibility-label :left-icon-for-action
:accessible true
:style style/left-icon}
[icon/icon icon
{:color (or icon-color (get-icon-color danger? override-theme))
:size 20}]]
[rn/view
{:style style/text-container}
icon-color]}]
[:<>
(when add-divider?
[divider theme])
[maybe-pressable disabled?
{:accessibility-label accessibility-label
:style (style/container sub-label disabled?)
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)
:on-press on-press}
[rn/view
{:style (style/row-container sub-label)}
[rn/view
{:accessibility-label :left-icon-for-action
:accessible true
:style style/left-icon}
[icon/icon icon
{:color (or icon-color (get-icon-color danger? theme))
:size 20}]]
[rn/view
{:style style/text-container}
[text/text
{:size :paragraph-1
:weight :medium
:style {:color
(cond
danger? (colors/theme-colors colors/danger-50 colors/danger-60 theme)
:else (colors/theme-colors colors/neutral-100 colors/white theme))}}
label]
(when sub-label
[text/text
{:size :paragraph-1
:weight :medium
:style {:color
(cond
danger? (colors/theme-colors colors/danger-50 colors/danger-60 override-theme)
:else (colors/theme-colors colors/neutral-100 colors/white override-theme))}}
label]
(when sub-label
{:size :paragraph-2
:style {:color
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
sub-label])]
(when (or right-text right-icon)
[rn/view {:style style/right-side-container}
(when right-text
[text/text
{:size :paragraph-2
:style {:color
(colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)}}
sub-label])]
(when (or right-text right-icon)
[rn/view {:style style/right-side-container}
(when right-text
[text/text
{:accessibility-label :right-text-for-action
:size :paragraph-1
:style (style/right-text override-theme)}
right-text])
(when right-icon
[rn/view
{:style style/right-icon
:accessible true
:accessibility-label :right-icon-for-action}
[icon/icon right-icon
{:color (get-icon-color danger? override-theme)
:size 20}]])])]]]))
{:accessibility-label :right-text-for-action
:size :paragraph-1
:style (style/right-text theme)}
right-text])
(when right-icon
[rn/view
{:style style/right-icon
:accessible true
:accessibility-label :right-icon-for-action}
[icon/icon right-icon
{:color (get-icon-color danger? theme)
:size 20}]])])]]])
(def ^:private action (quo.theme/with-theme action-internal))
(defn action-drawer
[sections]
[:<>
(doall
(for [actions sections]
(doall
(map action actions))))])
(let [filtered-actions (filter some? actions)]
(doall
(map #(with-meta [action %] {:key (:label %)}) filtered-actions)))))])
@@ -1,4 +1,10 @@
(ns quo2.components.drawers.documentation-drawers.style)
(ns quo2.components.drawers.documentation-drawers.style
(:require [quo2.foundations.colors :as colors]
[react-native.safe-area :as safe-area]))
(def outer-container
;; Margin negative to fill the bottom-sheet container where this component is used
{:margin-bottom (- (+ (safe-area/get-bottom) 8))})
(def container
{:align-items :flex-start
@@ -6,4 +12,10 @@
(def content
{:margin-top 8
:margin-bottom 16})
:margin-bottom (+ (safe-area/get-bottom) 8)})
(defn title
[shell?]
{:color (colors/theme-colors colors/neutral-100
colors/white
(when shell? :dark))})
@@ -1,10 +1,9 @@
(ns quo2.components.drawers.documentation-drawers.view
(:require [quo2.components.markdown.text :as text]
(:require [quo2.components.buttons.button.view :as button]
[quo2.components.drawers.documentation-drawers.style :as style]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]
[react-native.gesture :as gesture]
[quo2.components.buttons.button :as button]
[quo2.foundations.colors :as colors]))
[react-native.gesture :as gesture]))
(defn view
"Options
@@ -14,18 +13,18 @@
- `button-icon` button icon
- `on-press-button` On press handler for the button
- `shell?` use shell theme
`content` Content of the drawer
"
[{:keys [title show-button? on-press-button button-label button-icon shell?]} content]
[gesture/scroll-view
{:style style/outer-container
:always-bounce-vertical false
:content-inset-adjustment-behavior :never}
[rn/view {:style style/container}
[text/text
{:size :heading-2
:accessibility-label :documentation-drawer-title
:style {:color (colors/theme-colors colors/neutral-100
colors/white
(when shell? :dark))}
:style (style/title shell?)
:weight :semi-bold}
title]
[rn/view {:style style/content :accessibility-label :documentation-drawer-content}
@@ -1,9 +1,19 @@
(ns quo2.components.drawers.drawer-buttons.component-spec
(:require [quo2.components.drawers.drawer-buttons.view :as drawer-buttons]
[react-native.core :as rn]
[test-helpers.component :as h]))
[test-helpers.component :as h]
[react-native.safe-area :as safe-area]))
(h/describe "drawer-buttons"
(h/before-each
(fn []
(h/use-fake-timers)))
(h/after-each
(fn []
(h/clear-all-timers)
(h/use-real-timers)))
(h/test "the top heading and subheading render"
(h/render [drawer-buttons/view
{:top-card {:heading :top-heading}
@@ -29,15 +39,16 @@
(h/test "it clicks the top card"
(let [event (h/mock-fn)]
(h/render [drawer-buttons/view
{:top-card {:on-press event
:heading :top-heading}
:bottom-card {:heading :bottom-heading}}
:top-sub-heading
:bottom-sub-heading])
(h/fire-event :press (h/get-by-text "top-heading"))
(-> (js/expect event)
(.toHaveBeenCalled))))
(with-redefs [safe-area/get-top (fn [] 10)]
(h/render [drawer-buttons/view
{:top-card {:on-press event
:heading :top-heading}
:bottom-card {:heading :bottom-heading}}
:top-sub-heading
:bottom-sub-heading])
(h/fire-event :press (h/get-by-text "top-heading"))
(-> (js/expect event)
(.toHaveBeenCalled)))))
(h/test "it clicks the bottom card"
(let [event (h/mock-fn)]
@@ -1,11 +1,20 @@
(ns quo2.components.drawers.drawer-buttons.style
(:require [quo2.foundations.colors :as colors]))
(:require [quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]))
(def outer-container
{:height 216
:border-top-left-radius 20
:border-top-right-radius 20
:overflow :hidden})
(defn outer-container
[height border-radius container-style]
(reanimated/apply-animations-to-style
{:height height
:border-top-left-radius border-radius
:border-top-right-radius border-radius}
(assoc
container-style
:position :absolute
:left 0
:right 0
:bottom 0
:overflow :hidden)))
(def top-card
{:flex 1
@@ -17,7 +26,6 @@
(def bottom-card
{:position :absolute
:top 80
:left 0
:right 0
:bottom 0
@@ -41,6 +49,20 @@
:align-items :center
:border-color colors/white-opa-5})
(def blur-view-style
{:flex 1
:border-top-left-radius 20
:border-top-right-radius 20})
(def blur-content-style
{:flex 1
:background-color :transparent
:position :absolute
:top 0
:left 0
:right 0
:bottom 0})
(def bottom-text
{:flex 1
:color colors/white-70-blur})
@@ -51,4 +73,4 @@
(defn heading-text
[gap]
{:color colors/white
:margin-bottom gap})
:margin-bottom gap})
@@ -4,7 +4,12 @@
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.blur :as blur]
[quo2.components.drawers.drawer-buttons.style :as style]))
[quo2.components.drawers.drawer-buttons.style :as style]
[react-native.reanimated :as reanimated]
[react-native.platform :as platform]
[react-native.safe-area :as safe-area]))
(def default-height 216)
(defn render-bottom
[children]
@@ -29,35 +34,74 @@
children]]
[render-bottom children]))
(defn render-children-top
[children]
(if (label? children)
[text/text
{:size :paragraph-2
:style style/top-text
:weight :semi-bold}
children]
children))
(defn- f-render-children-top
[children top-children-opacity]
(let [scale (reanimated/interpolate top-children-opacity [1 0] [1 1.1])
padding-left (reanimated/interpolate scale [1 1.1] [0 14])]
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity top-children-opacity
:transform [{:scale scale}
{:translate-x padding-left}]}
{})}
(if (label? children)
[text/text
{:size :paragraph-2
:style style/top-text
:weight :semi-bold}
children]
children)]))
(defn card
[{:keys [on-press style heading gap accessibility-label top?]} children]
(defn- f-card
[{:keys [on-press default-on-press style heading gap accessibility-label top? top-title-opacity
top-children-opacity
animated-heading]
:or {top-title-opacity (reanimated/use-shared-value 1)}}
children]
[rn/touchable-highlight
{:accessibility-label accessibility-label
:on-press on-press
:on-press (fn []
(when on-press
(on-press))
(when default-on-press
(default-on-press)))
:border-radius 20
:style style
:underlay-color (:background-color style)}
[rn/view
[text/text
{:size :heading-1
:style (style/heading-text gap)
:weight :semi-bold}
heading]
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity top-title-opacity}
{})}
[text/text
{:size :heading-1
:style (style/heading-text gap)
:weight :semi-bold}
heading]]
(when animated-heading
(let [animated-heading-opacity (reanimated/interpolate top-children-opacity [1 0] [0 1])]
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity top-title-opacity}
{:position :absolute})}
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:opacity animated-heading-opacity}
{})}
[text/text
{:size :heading-1
:style (style/heading-text gap)
:weight :semi-bold}
animated-heading]]]))
(if top?
[render-children-top children]
[:f> f-render-children-top children top-children-opacity]
[render-children-bottom children])]])
(defn view
(defn card
[props children]
[:f> f-card props children])
(defn f-view
"[view opts]
opts
{:container-style style-object
@@ -70,29 +114,101 @@
child-1 string, keyword or hiccup
child-2 string, keyword or hiccup
"
[{:keys [container-style top-card bottom-card]} child-1 child-2]
[rn/view
{:style (merge container-style style/outer-container)}
[blur/view
{:blur-type :dark
:blur-amount 10
:style {:flex 1
:border-top-left-radius 20
:border-top-right-radius 20}}]
[rn/view
{:style {:flex 1
:background-color :transparent
:position :absolute
:top 0
:left 0
:right 0
:bottom 0}}
[card
(merge {:gap 4
:top? true
:style style/top-card}
top-card) child-1]
[card
(merge {:style style/bottom-card
:gap 20}
bottom-card) child-2]]])
[{:keys [container-style top-card bottom-card on-init animations-duration animations-delay]}
child-1
child-2]
(let [max-height (+ (:height (rn/get-window)) (if platform/android? (safe-area/get-top) 0))
height (reanimated/use-shared-value default-height)
top-padding (reanimated/use-shared-value 12)
border-radius (reanimated/use-shared-value 20)
bottom-view-top (reanimated/use-shared-value 80)
top-title-opacity (reanimated/use-shared-value 1)
top-children-opacity (reanimated/use-shared-value 1)
animations-delay (/ animations-delay 1.4)
start-top-animation (fn []
(reanimated/animate-shared-value-with-delay bottom-view-top
(:height (rn/get-screen))
animations-duration
:easing4
animations-delay)
(reanimated/animate-shared-value-with-delay
height
max-height
animations-duration
:easing4
animations-delay)
(reanimated/animate-shared-value-with-delay
top-padding
(+ 68 (safe-area/get-top))
animations-duration
:easing4
animations-delay)
(reanimated/animate-shared-value-with-delay
top-children-opacity
0
animations-duration
:easing4 animations-delay)
(reanimated/animate-shared-value-with-delay
top-title-opacity
0
0
:linear
(+ animations-delay animations-duration 500)))
reset-top-animation (fn []
(reanimated/set-shared-value top-title-opacity 1)
(reanimated/animate-shared-value-with-delay bottom-view-top
80
animations-duration
:easing4
50)
(reanimated/animate-shared-value-with-timing
height
default-height
animations-duration
:easing4)
(reanimated/animate-shared-value-with-timing
top-padding
12
animations-duration
:easing4)
(reanimated/animate-shared-value-with-timing
top-children-opacity
1
animations-duration
:easing4))]
(rn/use-effect (fn []
(when on-init
(on-init reset-top-animation))))
[reanimated/view {:style (style/outer-container height border-radius container-style)}
[blur/view
{:blur-type :dark
:blur-amount 10
:style style/blur-view-style}
[rn/view
{:style style/blur-content-style}
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:padding-top top-padding}
style/top-card)}
[card
(merge {:gap 4
:top? true
:style {:flex 1}
:top-children-opacity top-children-opacity
:top-title-opacity top-title-opacity
:default-on-press start-top-animation}
top-card)
child-1]]
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:top bottom-view-top}
style/bottom-card)}
[card
(merge {:style {:flex 1}
:gap 10}
bottom-card)
child-2]]]]]))
(defn view
[props child-1 child-2]
[:f> f-view props child-1 child-2])
+1 -1
View File
@@ -1,5 +1,5 @@
(ns quo2.components.dropdowns.dropdown
(:require [quo2.components.buttons.button :as button]))
(:require [quo2.components.buttons.button.view :as button]))
(defn dropdown
[_ _]
@@ -1,11 +1,12 @@
(ns quo2.components.empty-state.empty-state.view
(:require [quo2.components.buttons.button :as button]
(:require [quo2.components.buttons.button.view :as button]
[quo2.components.empty-state.empty-state.styles :as styles]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]))
[react-native.fast-image :as fast-image]
[quo2.theme :as theme]))
(defn empty-state
(defn- empty-state-internal
[{:keys [customization-color image title description blur?]
upper-button :upper-button
lower-button :lower-button
@@ -32,19 +33,18 @@
upper-button-on-press :on-press} upper-button]
[rn/view {:style styles/button-container}
[button/button
(cond-> {:type :primary
:size 32
:override-background-color (styles/upper-button-color customization-color)
:on-press upper-button-on-press}
blur? (assoc :override-theme :dark))
{:type :primary
:size 32
:override-background-color (styles/upper-button-color customization-color)
:on-press upper-button-on-press}
upper-button-text]
(when-let [{lower-button-text :text
lower-button-on-press :on-press} lower-button]
[button/button
(cond-> {:style {:margin-top 12}
:size 32
:type :blur-bg
:on-press lower-button-on-press}
blur? (assoc :override-theme :dark))
{:style {:margin-top 12}
:size 32
:type :blur-bg
:on-press lower-button-on-press}
lower-button-text])])])
(def empty-state (theme/with-theme empty-state-internal))
+1 -1
View File
@@ -1,6 +1,6 @@
(ns quo2.components.header
(:require [oops.core :refer [oget]]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
+2 -2
View File
@@ -14,8 +14,8 @@
:error colors/danger-60}})
(defn get-color
[key]
(get-in themes [(theme/get-theme) key]))
[k]
(get-in themes [(theme/get-theme) k]))
(defn info-message
"[info-message opts \"message\"]
@@ -30,12 +30,12 @@
:close-button colors/white}})
(defn get-color
[theme key]
(get-in themes [theme key]))
[theme k]
(get-in themes [theme k]))
(defn get-color-by-type
[theme type key]
(get-in themes [theme type key]))
[theme type k]
(get-in themes [theme type k]))
(defn container
[{:keys [theme type include-button?]}]
@@ -1,6 +1,6 @@
(ns quo2.components.info.information-box.view
(:require [clojure.string :as string]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.icon :as icons]
[quo2.components.info.information-box.style :as style]
[quo2.components.markdown.text :as text]
@@ -1,6 +1,6 @@
(ns quo2.components.inputs.profile-input.view
(:require
[quo2.components.buttons.button :as buttons]
[quo2.components.buttons.button.view :as buttons]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.inputs.profile-input.style :as style]
[quo2.components.inputs.title-input.view :as title-input]
@@ -37,7 +37,6 @@
[buttons/button
{:accessibility-label :select-profile-picture-button
:type :grey
:override-theme :dark
:override-background-color (colors/alpha colors/white 0.05)
:on-press on-press
:icon-size 20
@@ -50,6 +49,5 @@
[title-input/title-input
(merge title-input-props
{:blur? true
:override-theme :dark
:placeholder placeholder
:customization-color customization-color})]]])
@@ -3,50 +3,50 @@
[react-native.platform :as platform]))
(defn get-focused-placeholder-color
[blur? override-theme]
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 override-theme)
(colors/theme-colors colors/neutral-30 colors/neutral-60 override-theme))
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme))
)
(defn get-placeholder-color
[blur? override-theme]
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 override-theme)
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 theme)
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
(defn- get-disabled-color
[blur? override-theme]
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30)
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
(defn- get-char-count-color
[blur? override-theme]
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40)
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
(defn get-selection-color
[customization-color blur? override-theme]
[customization-color blur? theme]
(colors/alpha (if blur?
(colors/theme-colors colors/neutral-100 colors/white override-theme)
(colors/theme-colors colors/neutral-100 colors/white theme)
(colors/custom-color customization-color
(if (or (= :dark override-theme) colors/dark?) 60 50)))
(if (or (= :dark theme) colors/dark?) 60 50)))
(if platform/ios? 1 0.2)))
(def text-input-container {:flex 1})
(defn title-text
[disabled? blur? override-theme]
[disabled? blur? theme]
{:text-align-vertical :bottom
:color (if disabled?
(get-disabled-color blur? override-theme)
(colors/theme-colors colors/neutral-100 colors/white override-theme))})
(get-disabled-color blur? theme)
(colors/theme-colors colors/neutral-100 colors/white theme))})
(defn char-count
[blur? override-theme]
{:color (get-char-count-color blur? override-theme)})
[blur? theme]
{:color (get-char-count-color blur? theme)})
(def container
{:flex-direction :row
@@ -12,14 +12,14 @@
(str 0 value)
value))
(defn title-input
(defn- title-input-internal
[{:keys [blur?
on-change-text
auto-focus
placeholder
max-length
default-value
override-theme]
theme]
:or {max-length 0
auto-focus false
default-value ""}}]
@@ -38,10 +38,10 @@
(text/text-style
{:size :heading-2
:weight :semi-bold
:style (style/title-text disabled? blur? override-theme)})
:style (style/title-text disabled? blur? theme)})
:default-value default-value
:accessibility-label :profile-title-input
:keyboard-appearance (theme/theme-value :light :dark override-theme)
:keyboard-appearance (theme/theme-value :light :dark theme)
:on-focus #(swap! focused? (constantly true))
:on-blur #(swap! focused? (constantly false))
:auto-focus auto-focus
@@ -50,22 +50,24 @@
:editable (not disabled?)
:max-length max-length
:placeholder placeholder
:selection-color (style/get-selection-color customization-color blur? override-theme)
:selection-color (style/get-selection-color customization-color blur? theme)
:placeholder-text-color (if @focused?
(style/get-focused-placeholder-color blur? override-theme)
(style/get-placeholder-color blur? override-theme))}]]
(style/get-focused-placeholder-color blur? theme)
(style/get-placeholder-color blur? theme))}]]
[rn/view
{:style style/counter-container}
[text/text
[text/text
{:style (style/char-count blur? override-theme)
{:style (style/char-count blur? theme)
:size :paragraph-2}
(pad-0
(str
(count @value)))]
[text/text
{:style (style/char-count blur? override-theme)
{:style (style/char-count blur? theme)
:size :paragraph-2}
(str "/"
(pad-0
(str max-length)))]]]])))
(def title-input (theme/with-theme title-input-internal))
@@ -1,5 +1,5 @@
(ns quo2.components.links.link-preview.view
(:require [quo2.components.buttons.button :as button]
(:require [quo2.components.buttons.button.view :as button]
[quo2.components.links.link-preview.style :as style]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]))
+47 -53
View File
@@ -1,12 +1,11 @@
(ns quo2.components.list-items.channel
(:require [quo2.components.avatars.channel-avatar :as channel-avatar]
(:require [quo2.components.avatars.channel-avatar.view :as channel-avatar]
[quo2.components.common.unread-grey-dot.view :as unread-grey-dot]
[quo2.components.counter.counter :as quo2.counter]
[quo2.components.icon :as quo2.icons]
[quo2.components.markdown.text :as quo2.text]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]
[quo2.components.common.unread-grey-dot.view :refer [unread-grey-dot]]))
[react-native.core :as rn]))
(def ^:private custom-props
[:name :locked? :mentions-count :unread-messages?
@@ -14,61 +13,56 @@
(defn list-item
[{:keys [locked? mentions-count unread-messages?
muted? is-active-channel? emoji channel-color]
:or {channel-color colors/primary-50}
muted? is-active-channel? emoji channel-color
default-color]
:as props}]
(let [standard-props (apply dissoc props custom-props)
(let [channel-color (or channel-color default-color)
standard-props (apply dissoc props custom-props)
name-text (:name props)]
[rn/touchable-opacity standard-props
[rn/view
{:style (merge {:height 48
:display :flex
:border-radius 12
:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:padding-left 12
:padding-right 12}
(when is-active-channel?
{:background-color (colors/theme-alpha channel-color 0.05 0.05)}))}
{:style (cond-> {:height 48
:border-radius 12
:flex-direction :row
:justify-content :space-between
:align-items :center
:width "100%"
:padding-left 12
:padding-right 12}
is-active-channel? (assoc :background-color
(colors/theme-alpha channel-color 0.05 0.05)))}
[rn/view
{:display :flex
:flex-direction :row
:justify-content :flex-start
:align-items :center
{:style {:flex-direction :row
:justify-content :flex-start
:align-items :center}
:accessible true
:accessibility-label :chat-name-text}
[channel-avatar/channel-avatar
{:big? true
:locked? locked?
:emoji-background-color (colors/theme-alpha channel-color 0.1 0.1)
:emoji emoji}]
[channel-avatar/view
{:size :size/l
:locked? locked?
:full-name (:name props)
:customization-color channel-color
: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 (cond-> {:margin-left 12}
(and (not locked?) muted?)
(assoc :color (colors/theme-colors colors/neutral-40 colors/neutral-60)))
:weight :medium
:size :paragraph-1} (str "# " name-text)]]
[rn/view
{:style {:height 20
:justify-content :center}}
(when (and (not locked?)
muted?)
[quo2.icons/icon :i/muted
{:size 20
:color colors/neutral-40
:container-style {:margin-right 1
:margin-top 2}}])
(when (and (not locked?)
(not muted?)
(pos? (int mentions-count)))
[rn/view
{:style {:margin-right 2
:margin-top 2}}
[quo2.counter/counter {:override-bg-color channel-color} mentions-count]])
(when (and (not locked?)
(not muted?)
(not (pos? (int mentions-count)))
unread-messages?)
[unread-grey-dot :unviewed-messages-public])]]]))
:size :paragraph-1}
(str "# " name-text)]]
(when-not locked?
[rn/view {:style {:height 20 :justify-content :center}}
(cond
muted?
[quo2.icons/icon :i/muted
{:size 20
:color colors/neutral-40
:container-style {:margin-right 1 :margin-top 2}}]
(pos? (int mentions-count))
[rn/view {:style {:margin-right 2 :margin-top 2}}
[quo2.counter/counter {:override-bg-color channel-color}
mentions-count]]
unread-messages?
[unread-grey-dot/unread-grey-dot :unviewed-messages-public])])]]))
@@ -0,0 +1,70 @@
(ns quo2.components.list-items.community.component-spec
(:require [quo2.components.list-items.community.view :as component]
[test-helpers.component :as h]))
(h/describe "Community list"
(h/test "default render"
(h/render [component/view {}])
(h/is-truthy (h/get-by-label-text :community-item-title))
(h/is-null (h/query-by-label-text :community-item-info)))
(h/describe "type share"
(h/test "renders"
(h/render [component/view
{:type :share
:title "Title"
:subtitle "Subtitle"}])
(h/is-truthy (h/get-by-text "# Title"))
(h/is-truthy (h/get-by-text "Subtitle"))
(h/is-null (h/query-by-label-text :community-item-info))))
(h/describe "type engage"
(h/test "default, no info"
(h/render [component/view {:type :engage}])
(h/is-null (h/query-by-label-text :community-item-info)))
(h/test "info is :navigation"
(h/render [component/view {:type :engage :info :navigation}])
(h/is-truthy (h/get-by-label-text :info-navigation)))
(h/test "info is :token-gated"
(h/render [component/view {:type :engage :info :token-gated}])
(h/is-truthy (h/get-by-label-text :info-token-gated)))
(h/test "info is :muted"
(h/render [component/view {:type :engage :info :muted}])
(h/is-truthy (h/get-by-label-text :info-muted)))
(h/test "info is :notification"
(h/render [component/view {:type :engage :info :notification}])
(h/is-truthy (h/get-by-label-text :info-notification-dot)))
(h/test "info is :mention"
(h/render [component/view
{:type :engage
:info :mention
:unread-count 9000}])
(h/is-truthy (h/get-by-text "99+"))))
(h/describe "type discover"
(h/test "default, no info, no member stats"
(h/render [component/view {:type :discover}])
(h/is-null (h/query-by-label-text :stats-members-count))
(h/is-null (h/query-by-label-text :community-item-info)))
(h/test "info is :token-gated, show member stats"
(let [on-press-info (h/mock-fn)]
(h/render [component/view
{:type :discover
:info :token-gated
:locked? true
:blur? false
:on-press-info on-press-info
:members {:members-count 9876 :active-count 1350}
:tokens [{:id 1 :group [{:id 1}]}]}])
(h/is-truthy (h/get-by-label-text :community-item-info))
(h/is-truthy (h/get-by-label-text :permission-tag))
(h/is-truthy (h/get-by-label-text :stats-members-count))
(h/is-truthy (h/get-by-label-text :stats-active-count))
(h/fire-event :press (h/get-by-label-text :permission-tag))
(h/was-called on-press-info)))))
@@ -0,0 +1,65 @@
(ns quo2.components.list-items.community.style
(:require [quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]))
(def logo
{:border-radius 50
:border-width 0
:width 32
:height 32
:margin-right 10})
(defn notification-dot
[blur? theme]
{:width 8
:height 8
:border-radius 4
:background-color (if (and (= :dark theme) blur?)
colors/white-opa-40
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme))})
(defn title
[{:keys [type info blur? theme]}]
{:color (cond
(and (= type :engage) (= info :muted))
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
(and (= type :engage) (= info :default) (not blur?))
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
(and (= type :engage) (= info :default) (= :dark theme) blur?)
colors/white-70-blur
:else
(colors/theme-colors colors/neutral-100 colors/white theme))})
(defn subtitle
[blur? theme]
{:color (if (and (= :dark theme) blur?)
colors/white-opa-40
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))})
(defn container
[{:keys [type pressed? blur? customization-color theme info]}]
(merge {:padding-vertical 8
:padding-horizontal 12
:border-radius 12
:flex-direction :row
:align-items :center
:background-color (cond
(and pressed? (= type :engage) (= info :default) (= :dark theme) blur?)
colors/white-opa-5
(and pressed? (#{:engage :share} type))
(colors/theme-alpha customization-color 0.05 0.05)
(and (not pressed?) (= type :discover) (not blur?))
(colors/theme-colors colors/white colors/neutral-90 theme)
(and (not pressed?) (= type :discover) (= :dark theme) blur?)
colors/white-opa-5
(and pressed? (= type :discover))
(colors/theme-colors colors/white :transparent theme))}
(when (and (= type :discover) (not pressed?))
(shadows/get 3))))
@@ -0,0 +1,165 @@
(ns quo2.components.list-items.community.view
(:require [quo2.components.community.community-view :as community-view]
[quo2.components.counter.counter :as counter]
[quo2.components.icon :as icons]
[quo2.components.list-items.community.style :as style]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn- logo-component
[logo]
[rn/image {:source logo :style style/logo}])
(defn- title-component
[{:keys [title type] :as props}]
[text/text
{:weight :semi-bold
:size :paragraph-1
:accessibility-label :community-item-title
:number-of-lines 1
:ellipsize-mode :tail
:style (style/title props)}
(if (= type :share)
(str "# " title)
title)])
(defn- subtitle-component
[subtitle blur? theme]
[text/text
{:size :paragraph-2
:number-of-lines 1
:accessibility-label :community-item-subtitle
:style (style/subtitle blur? theme)}
subtitle])
(defn- notification-dot
[blur? theme]
[rn/view
{:style (style/notification-dot blur? theme)
:accessibility-label :info-notification-dot}])
(defn- info-component
[{:keys [customization-color info type blur? locked? on-press-info theme tokens unread-count]}]
(let [component
(cond
(and (= type :discover) (= info :token-gated) (seq tokens))
[community-view/permission-tag-container
{:locked? locked?
:tokens tokens
:on-press on-press-info
:theme theme
:blur? blur?}]
(and (= type :engage) (= info :mention) (pos? unread-count))
[counter/counter
{:type :default
:override-bg-color customization-color}
unread-count]
(and (= type :engage) (= info :notification))
[notification-dot blur? theme]
(and (= type :engage) (= info :muted))
[icons/icon :i/muted
{:accessibility-label :info-muted
:color (colors/theme-colors colors/neutral-40 colors/neutral-60 theme)}]
(and (= type :engage) (= info :token-gated))
[icons/icon (if locked? :i/locked :i/unlocked)
{:accessibility-label :info-token-gated
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}]
(and (= type :engage) (= info :navigation))
[icons/icon :i/chevron-right
{:accessibility-label :info-navigation
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}])]
(when component
[rn/view
{:accessibility-label :community-item-info
:style {:margin-left 10}}
component])))
(defn- view-internal
"Options:
:type - :discover/engage/share
:info - keyword - Acceptable values vary based on the :type option.
:title - string
:logo - image resource
:theme - :light/dark
:container-style - style map - Override styles in top-level view component.
:members - {:members-count number, :active-count number} - When non-nil, the
statistics component will be shown.
:tokens - A sequence of maps, e.g. [{:id 1 :group [{:id 1 :token-icon an-icon}]}].
:locked? - boolean - When true, the permission-tag icon or the token gated
icon will appear as closed.
:blur? - boolean - It will be taken into account when true and dark mode is
enabled.
:customization-color - color - It will be passed down to components that
should vary based on a custom color.
:on-press/:on-long-press - fn - Used by the top-level pressable component.
:on-press-info - fn - Will be called when the info component is pressed.
:unread-count - number - When the info is :mention, it will be used to show
the number of unread mentions.
"
[]
(let [pressed? (reagent/atom false)]
(fn [{:keys [members type info tokens locked? title subtitle
logo blur? customization-color
on-press on-long-press on-press-info
container-style unread-count theme]}]
[rn/pressable
{:accessibility-label :container
:on-press-in (fn [] (reset! pressed? true))
:on-press on-press
:on-long-press on-long-press
:on-press-out (fn [] (reset! pressed? false))
:style (merge (style/container {:blur? blur?
:customization-color customization-color
:info info
:type type
:pressed? @pressed?
:theme theme})
container-style)}
[logo-component logo]
[rn/view {:style {:flex 1}}
[title-component
{:blur? blur?
:info info
:theme theme
:title title
:type type}]
(when (and (= type :share) subtitle)
[subtitle-component subtitle blur? theme])
(when (and members (= type :discover))
[community-view/community-stats-column
{:type :list-view
:theme theme
:blur? blur?
:members-count (:members-count members)
:active-count (:active-count members)}])]
[info-component
{:blur? blur?
:customization-color customization-color
:info info
:type type
:locked? locked?
:on-press-info on-press-info
:theme theme
:tokens tokens
:unread-count unread-count}]])))
(def view (quo.theme/with-theme view-internal))
@@ -7,11 +7,11 @@
(defn themes
[type]
(case type
:main {:icon-color (theme-colors colors/neutral-50 colors/neutral-10)
:background (theme-colors colors/white colors/neutral-90)
:main {:icon-color (theme-colors colors/neutral-50 colors/neutral-40)
:background (theme-colors colors/white colors/neutral-95)
:text-color (theme-colors colors/neutral-100 colors/white)}
:danger {:icon-color (theme-colors colors/danger-50 colors/danger-60)
:background (theme-colors colors/white colors/neutral-90)
:background (theme-colors colors/white colors/neutral-95)
:text-color (theme-colors colors/danger-50 colors/danger-60)}
:transparent {:icon-color (theme-colors colors/neutral-50 colors/neutral-10)
:text-color (theme-colors colors/neutral-100 colors/white)}))
@@ -0,0 +1,95 @@
(ns quo2.components.loaders.skeleton.constants)
(def ^:const layout-dimensions
{:messages {:height 56
:padding-top 12}
:list-items {:height 56
:padding-top 12}
:notifications {:height 90
:padding-top 8}})
(def ^:const content-dimensions
{:messages {0 {:author {:width 112
:height 8
:margin-bottom 8}
:message {:width 144
:height 16
:margin-bottom 0}}
1 {:author {:width 96
:height 8
:margin-bottom 8}
:message {:width 212
:height 16
:margin-bottom 0}}
2 {:author {:width 80
:height 8
:margin-bottom 8}
:message {:width 249
:height 16
:margin-bottom 0}}
3 {:author {:width 124
:height 8
:margin-bottom 8}
:message {:width 156
:height 16
:margin-bottom 0}}}
:list-items {0 {:author {:width 112
:height 8
:margin-bottom 0}
:message {:width 144
:height 16
:margin-bottom 8}}
1 {:author {:width 96
:height 8
:margin-bottom 0}
:message {:width 212
:height 16
:margin-bottom 8}}
2 {:author {:width 80
:height 8
:margin-bottom 0}
:message {:width 249
:height 16
:margin-bottom 8}}
3 {:author {:width 124
:height 8
:margin-bottom 0}
:message {:width 156
:height 16
:margin-bottom 8}}}
:notifications {0 {:author {:width 109
:height 8
:margin-bottom 8}
:message {:width 167
:height 16
:margin-bottom 8}
:message2 {:width 242
:height 30
:margin-bottom 0}}
1 {:author {:width 165
:height 8
:margin-bottom 8}
:message {:width 112
:height 16
:margin-bottom 8}
:message2 {:width 294
:height 30
:margin-bottom 0}}
2 {:author {:width 136
:height 8
:margin-bottom 8}
:message {:width 178
:height 16
:margin-bottom 8}
:message2 {:width 178
:height 30
:margin-bottom 0}}
3 {:author {:width 136
:height 8
:margin-bottom 8}
:message {:width 166
:height 16
:margin-bottom 8}
:message2 {:width 256
:height 30
:margin-bottom 0}}}})
@@ -0,0 +1,29 @@
(ns quo2.components.loaders.skeleton.style
(:require [quo2.components.loaders.skeleton.constants :as constants]))
(defn container
[content]
{:flex-direction :row
:padding 12
:padding-top (get-in constants/layout-dimensions [content :padding-top])
:height (get-in constants/layout-dimensions [content :height])})
(defn avatar
[color]
{:height 32
:width 32
:border-radius 16
:background-color color})
(def content-container
{:padding-left 8})
(defn content-view
[{:keys [type index content color]}]
(let [{:keys [width height margin-bottom]}
(get-in constants/content-dimensions [content index type])]
{:height height
:width width
:border-radius 6
:background-color color
:margin-bottom margin-bottom}))
@@ -0,0 +1,46 @@
(ns quo2.components.loaders.skeleton.view
(:require [quo2.theme :as theme]
[react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.loaders.skeleton.style :as style]
[quo2.components.loaders.skeleton.constants :as constants]))
(defn- skeleton-item
[index content color]
[rn/view {:style (style/container content)}
[rn/view {:style (style/avatar color)}]
[rn/view {:style style/content-container}
[rn/view
{:style (style/content-view
{:type (if (= content :list-items) :message :author)
:index index
:content content
:color color})}]
[rn/view
{:style (style/content-view
{:type (if (= content :list-items) :author :message)
:index index
:content content
:color color})}]
(when (= content :notifications)
[rn/view
{:style (style/content-view {:type :message2
:index index
:content content
:color color})}])]])
(defn- internal-view
[{:keys [content theme blur? parent-height]}]
(let [skeleton-height (get-in constants/layout-dimensions [content :height])
number-of-skeletons (int (Math/ceil (/ parent-height skeleton-height)))
color (cond
blur? colors/white-opa-5
(= theme :dark) colors/neutral-90
:else colors/neutral-5)]
[rn/view {:style {:padding 8}}
(doall
(for [index (range number-of-skeletons)]
^{:key index}
[skeleton-item (mod index 4) content color]))]))
(def view (theme/with-theme internal-view))
@@ -0,0 +1,38 @@
(ns quo2.components.markdown.list.component-spec
(:require [quo2.components.markdown.list.view :as list]
[test-helpers.component :as h]))
(h/describe "tests for markdown/list component"
(h/test "renders component with title"
(h/render [list/view {:title "test title"}])
(h/is-truthy (h/get-by-text "test title")))
(h/test "renders component with description"
(h/render [list/view
{:title "test title"
:description "test description"}])
(h/is-truthy (h/get-by-text "test description")))
(h/test "renders component with title and description"
(h/render [list/view
{:title "test title"
:description "test description"}])
(h/is-truthy (h/get-by-text "test title"))
(h/is-truthy (h/get-by-text "test description")))
(h/test "renders step component when step-number is valid and type is step"
(h/render [list/view
{:type :step
:step-number 1}])
(h/is-truthy (h/get-by-label-text :step-counter)))
(h/test "renders decription with a context tag component and description after the tag"
(h/render [list/view
{:step-number 1
:description "Lorem ipsum "
:tag-name "dolor"
:description-after-tag "text after tag"}])
(h/is-truthy (h/get-by-text "Lorem ipsum"))
(h/is-truthy (h/get-by-label-text :user-avatar))
(h/is-truthy (h/get-by-text "dolor"))
(h/is-truthy (h/get-by-text "text after tag"))))
@@ -0,0 +1,15 @@
(ns quo2.components.markdown.list.style)
(defn container
[container-style]
(merge container-style
{:flex-direction :row
:flex 1
:align-items :flex-start}))
(def index
{:margin-left 5})
(def text-container
{:margin-left 8
:flex 1})
@@ -0,0 +1,65 @@
(ns quo2.components.markdown.list.view
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.components.counter.step.view :as step]
[quo2.components.markdown.list.style :as style]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[quo2.components.tags.context-tag.view :as context-tag]))
(defn get-colors
[theme blur?]
(cond (and blur? (= theme :dark)) colors/white-opa-40
(= theme :dark) colors/neutral-50
:else colors/neutral-40))
(defn description-text
[{:keys [description tag-name tag-picture description-after-tag blur?]}]
(if-not tag-name
[text/text
{:accessibility-label :list-item-description
:size :paragraph-2}
description]
[rn/view {:style {:flex-direction :row :align-items :center}}
[text/text
{:accessibility-label :list-item-description
:size :paragraph-2}
description]
[rn/view {:style {:margin-left 4}}
[context-tag/context-tag {:blur? blur?} tag-picture tag-name]]
[text/text
{:style {:margin-left 4}
:accessibility-label :list-item-description-after-tag
:size :paragraph-2}
description-after-tag]]))
(defn- internal-view
[{:keys [theme title description tag-picture tag-name description-after-tag step-number
customization-color type blur? container-style]
:or {type :bullet}}]
[rn/view {:style (style/container container-style)}
[rn/view {:style style/index}
(if (= type :step)
[step/step
{:in-blur-view? blur?
:customization-color customization-color
:type (if customization-color :complete :neutral)} step-number]
[icon/icon :i/bullet {:color (get-colors theme blur?)}])]
[rn/view {:style style/text-container}
(when title
[text/text
{:accessibility-label :list-item-title
:weight :semi-bold
:size :paragraph-2}
title])
(when description
[rn/view (when title {:style {:margin-top 0}})
[description-text
{:description description
:tag-name tag-name
:tag-picture tag-picture
:description-after-tag description-after-tag
:blur? blur?}]])]])
(def view (theme/with-theme internal-view))
+4 -4
View File
@@ -17,8 +17,8 @@
:background colors/neutral-95}})
(defn get-color
[key]
(get-in themes [(theme/get-theme) key]))
[k]
(get-in themes [(theme/get-theme) k]))
(def ui-images
{:light {:horizontal (js/require "../resources/images/ui/message-gap-hborder-light.png")
@@ -28,8 +28,8 @@
:circles (js/require "../resources/images/ui/message-gap-circle-bg-dark.png")}})
(defn get-image
[key]
(get-in ui-images [(theme/get-theme) key]))
[k]
(get-in ui-images [(theme/get-theme) k]))
;;; components
;;;; borders
@@ -5,12 +5,12 @@
(defn dynamic-button-view
[type dynamic-buttons style]
(when-let [{:keys [count on-press customization-color label]} (get dynamic-buttons type)]
(when-let [{:keys [on-press customization-color label] :as props} (get dynamic-buttons type)]
[dynamic-button/dynamic-button
{:type type
:label label
:on-press on-press
:count count
:count (:count props)
:style style
:customization-color customization-color}]))
+15 -13
View File
@@ -1,11 +1,12 @@
(ns quo2.components.navigation.page-nav
(:require [clojure.string :as string]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
[react-native.core :as rn]
[quo2.theme :as theme]))
(def ^:private centrify-style
{:display :flex
@@ -30,7 +31,7 @@
{:no-color true})))
(defn left-section-view
[{:keys [on-press icon accessibility-label type icon-background-color icon-override-theme]
[{:keys [on-press icon accessibility-label type icon-background-color]
:or {type :grey}}
put-middle-section-on-left?]
[rn/view {:style (when put-middle-section-on-left? {:margin-right 5})}
@@ -40,7 +41,6 @@
:type type
:size 32
:accessibility-label accessibility-label
:override-theme icon-override-theme
:override-background-color icon-background-color}
icon]])
@@ -87,10 +87,10 @@
(defn- mid-section-view
[{:keys [horizontal-description? one-icon-align-left? type left-align?
main-text right-icon main-text-icon-color left-icon on-press avatar]
main-text right-icon main-text-icon-color left-icon on-press avatar theme]
:as props}]
(let [text-color (if (colors/dark?) colors/neutral-5 colors/neutral-95)
text-secondary-color (if (colors/dark?) colors/neutral-40 colors/neutral-50)
(let [text-color (colors/theme-colors colors/neutral-95 colors/neutral-5 theme)
text-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
component-instance [mid-section-comp (assoc props :text-secondary-color text-secondary-color)]]
[rn/touchable-opacity {:on-press on-press}
[rn/view
@@ -152,7 +152,7 @@
:justify-content :flex-end)}
(let [last-icon-index (-> right-section-buttons count dec)]
(map-indexed (fn [index
{:keys [icon on-press type style icon-override-theme icon-background-color
{:keys [icon on-press type style icon-background-color
accessibility-label label]
:or {type :grey}}]
^{:key index}
@@ -168,12 +168,11 @@
:type type
:before (when label icon)
:size 32
:override-theme icon-override-theme
:override-background-color icon-background-color}
(if label label icon)]])
right-section-buttons))])
(defn page-nav
(defn- page-nav-internal
"[page-nav opts]
opts
{ :one-icon-align-left? true/false
@@ -198,25 +197,26 @@
{:type button-type
:on-press event
:icon icon
:icon-override-theme :light/:dark
}
:right-section-buttons vector of
{:type button-type
:on-press event
:icon icon
:icon-override-theme :light/:dark
}
:theme :light or :dark
}
"
[{:keys [container-style one-icon-align-left? horizontal-description?
align-mid? page-nav-color page-nav-background-uri
mid-section
left-section
right-section-buttons]}]
right-section-buttons
theme]}]
(let [put-middle-section-on-left? (or align-mid?
(> (count right-section-buttons) 1))
mid-section-props
{:type (:type mid-section)
:theme theme
:horizontal-description? horizontal-description?
:description-img (:description-img mid-section)
:main-text (:main-text mid-section)
@@ -258,3 +258,5 @@
(not put-middle-section-on-left?)
[mid-section-view mid-section-props]))]
[right-section-view right-section-buttons]]))
(def page-nav (theme/with-theme page-nav-internal))
@@ -1,7 +1,7 @@
(ns quo2.components.notifications.activity-log.view
(:require [clojure.string :as string]
[quo.core :as quo]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.notifications.activity-log.style :as style]
@@ -150,8 +150,8 @@
[activity-reply-text-input props reply-input])
(when items
[rn/view style/footer-container
(for [{:keys [key] :as item} items]
^{:key key}
(for [item items]
^{:key (:key item)}
[footer-item-view item replying? reply-input])])])))
(defn view
@@ -30,10 +30,10 @@
:path-length path-length}))
(defn- linear-ease
[time start goal duration]
[input-time start goal duration]
(if (zero? duration)
start
(-> time
(-> input-time
(/ duration)
(* goal)
(+ start))))
@@ -4,10 +4,10 @@
[react-native.core :as rn]))
(defn info-count
([count]
(info-count {} count))
([props count]
(when (> count 0)
([amount]
(info-count {} amount))
([props amount]
(when (> amount 0)
[rn/view
(merge props
{:style (merge {:width 16
@@ -23,4 +23,4 @@
{:style (merge typography/font-medium
typography/label
{:color colors/white :text-align :center})}
count]])))
amount]])))
@@ -18,10 +18,10 @@
:background-color :transparent})
(defn content-container
[override-theme]
[theme]
(merge
(:shadow-1 shadows/normal-scale)
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
(shadows/get 1 theme)
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
:flex-direction :row
:padding-vertical 8
:padding-horizontal 12}))
@@ -18,10 +18,10 @@
:background-color :transparent})
(defn content-container
[override-theme]
[theme]
(merge
(:shadow-1 shadows/normal-scale)
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
(shadows/get 1 theme)
{:background-color (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
:flex-direction :row
:justify-content :space-between
:padding-vertical 8
@@ -21,8 +21,7 @@
(defn toast-undo-action
[duration on-press override-theme]
[toast-action-container
{:on-press on-press :accessibility-label :toast-undo-action}
[toast-action-container {:on-press on-press :accessibility-label :toast-undo-action}
[rn/view {:style {:margin-right 5}}
[count-down-circle/circle-timer {:duration duration}]]
[text/text
@@ -31,17 +30,17 @@
(defn- toast-container
[{:keys [left title text right container-style override-theme]}]
[rn/view
{:style (merge style/box-container container-style)}
[rn/view {:style (merge style/box-container container-style)}
[blur/view
{:style style/blur-container
:blur-amount 13
:blur-radius 10
:blur-type :transparent
:overlay-color :transparent}]
[rn/view
{:style (style/content-container override-theme)}
[rn/view {:style style/left-side-container} left]
[rn/view {:style (style/content-container override-theme)}
[rn/view {:style style/left-side-container}
left]
[rn/view {:style style/right-side-container}
(when title
[text/text
@@ -57,7 +56,7 @@
:style (style/text override-theme)
:accessibility-label :toast-content}
text])]
(when right right)]])
right]])
(defn toast
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
@@ -6,7 +6,7 @@
[quo2.foundations.colors :as colors]
[react-native.hole-view :as hole-view]
[quo2.components.markdown.text :as text]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.profile.profile-card.style :as style]
[quo2.components.avatars.user-avatar.view :as user-avatar]))
@@ -54,7 +54,6 @@
[user-avatar/user-avatar
{:full-name name
:profile-picture profile-picture
:override-theme :dark
:size :medium
:status-indicator? false
:customization-color customization-color
@@ -66,7 +65,7 @@
:size 32
:blurred? true
:labelled? true
:resource :main-icons2/check
:resource :i/check
:accessibility-label :logged-in-tag
:icon-color colors/success-50
:override-theme :dark
@@ -76,7 +75,6 @@
{:size 32
:type :blur-bg
:icon true
:override-theme :dark
:style style/option-button
:on-press on-options-press
:accessibility-label :profile-card-options}
@@ -4,7 +4,7 @@
[quo2.foundations.colors :as colors]
[react-native.core :as rn :refer [use-effect]]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.record-audio.record-audio.helpers :as helpers]))
(defn f-record-button
@@ -1,6 +1,6 @@
(ns quo2.components.settings.accounts.view
(:require [quo2.components.avatars.account-avatar :as account-avatar]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.markdown.text :as text]
[quo2.components.settings.accounts.style :as style]
[react-native.core :as rn]))
@@ -0,0 +1,20 @@
(ns quo2.components.settings.category.component-spec
(:require [test-helpers.component :as h]
[quo2.components.settings.category.view :as category]))
(h/describe "category tests"
(h/test "category label renders"
(h/render [category/category
{:label "label"
:data [{:title "Item 1"
:left-icon :i/browser
:chevron? true}]}])
(h/is-truthy (h/get-by-text "label")))
(h/test "category item renders"
(h/render [category/category
{:label "label"
:data [{:title "Item 1"
:left-icon :i/browser
:chevron? true}]}])
(h/is-truthy (h/get-by-text "Item 1"))))
@@ -0,0 +1,44 @@
(ns quo2.components.settings.category.style
(:require [quo2.foundations.colors :as colors]))
(def container
{:left 0
:right 0
:padding-horizontal 20
:padding-top 12
:padding-bottom 8})
(defn items
[theme blur?]
{:margin-top 12
:border-radius 16
:background-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/white colors/neutral-95 theme))
:border-width 1
:border-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
(defn separator
[theme blur?]
{:height 1
:background-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
(defn blur-container
[]
{:position :absolute
:left 0
:right 0
:bottom 0
:top 0
:overflow :hidden})
(defn blur-view
[]
{:style {:flex 1}
:blur-radius 10
:blur-type (colors/theme-colors :light :dark)
:blur-amount 20})
@@ -0,0 +1,27 @@
(ns quo2.components.settings.category.view
(:require
[quo2.components.markdown.text :as text]
[quo2.components.settings.settings-list.view :as settings-list]
[quo2.foundations.colors :as colors]
[react-native.blur :as blur]
[react-native.core :as rn]
[quo2.components.settings.category.style :as style]
[quo2.theme :as quo.theme]))
(defn- category-internal
[{:keys [label data blur? theme]}]
[rn/view {:style style/container}
(when blur?
[rn/view (style/blur-container) [blur/view (style/blur-view)]])
[text/text
{:weight :medium
:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
label]
[rn/flat-list
{:data data
:style (style/items theme blur?)
:render-fn (fn [item] [settings-list/settings-list item])
:separator [rn/view {:style (style/separator theme blur?)}]}]])
(def category (quo.theme/with-theme category-internal))
@@ -26,4 +26,4 @@
{:data [{:id 1
:label "Item 1"}
]} types/tab])
(h/is-truthy (h/get-by-text "Item 1"))))
(h/is-truthy (h/get-by-text "Item 1"))))
@@ -2,7 +2,7 @@
(:require [quo2.components.settings.settings-list.style :as style]
[quo2.components.icon :as icons]
[quo2.components.selectors.selectors.view :as selectors]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[quo2.components.markdown.text :as text]
[quo2.components.tags.status-tags :as status-tag]
[quo2.foundations.colors :as colors]
@@ -4,7 +4,7 @@
[react-native.blur :as blur]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.buttons.button :as button]
[quo2.components.buttons.button.view :as button]
[react-native.core :as rn]))
(defn view
@@ -41,8 +41,8 @@
:margin-right 8})
(defn get-color-by-type
[type key]
(get-in themes [(theme/get-theme) type key]))
[type k]
(get-in themes [(theme/get-theme) type k]))
(defn account-selector
"[account-selector opts]
@@ -73,4 +73,3 @@
:size :paragraph-1
:style {:color account-text-color}}
account-text]]]))

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