Compare commits

...
Author SHA1 Message Date
alwx 615810e7f4 Offsets for composer + dynamic height calculation 2023-07-28 12:45:44 +02:00
alwx 9a5b2859c8 Offsets for composer + dynamic height calculation 2023-07-28 12:39:11 +02:00
Ulises Manuel Cárdenas 4f044765e1 [#16278] fix tips in white camera border (#16716)
* Remove unnecessary wrapper
* Fix border tips and refactor
* Add comment about using 1.9 width
2023-07-26 14:08:57 -06:00
Parvesh Monu 7cd9f76043 Fix UI freezing when image is opened from activity center (#16707) 2023-07-26 18:19:10 +05:30
Icaro Motta 238e35a281 Unshadow more Clojure core vars (#16777)
This is a continuation of https://github.com/status-im/status-mobile/pull/16500 (Lint
& fix some shadowed core Clojure(Script) vars).

Notes: As a reminder, the goal is to eventually disallow shadowing core Clojure
vars entirely, but to get there and avoid rebase hell and regressions, we need
to do in smaller steps, especially because we can't safely automate the process
of unshadowing vars.

We are already down from ~500 shadowed core vars to 350 in total.

Why is this PR is using names such as "s", "v" or "sym"? Names such as s or v
are the so called idiomatic names, and are listed in the Clojure Style Guide
https://guide.clojure.style/#idiomatic-names. I used them whenever I felt
appropriate. For the var cljs.core/symbol I opted to use sym, even though the
symbol in question is not necessarily a Clojure symbol, I think the alias
conveys the meaning well enough
(https://www.clojure.org/guides/learn/syntax#_symbols_and_idents).

New vars linted:

- comparator
- identity
- str
- symbol
- val

Outstanding shadowed vars include type, name, hash, comp.
2023-07-26 11:26:12 +00:00
Alexander 57c538e9d0 Update navigation bar to support dark mode (#16762)
* Dark mode top bar

* Fixes

* Style fix
2023-07-26 09:48:51 +02:00
Omar BasemandMilad e49a3ab5cd feat: category reorder component (#16719)
* feat: category reorder component

---------

Co-authored-by: Milad <mmilad.sanati@gmail.com>
2023-07-26 11:11:17 +04:00
Mohamed Javid 1721b40b3f Refactor toast component to use theme context (#16711)
This commit refactors the "Toast" component to use theme context for consistency across the codebase.

Each toast will have its theme provider, which will help the children to use the context properly without interfering with other toast's context.

The following components are refactored to use with-theme / theme-context as it is used in the "Toast":

- "text" component
- "user-avatar" component
- "icon" component
- "circle-timer" component

This commit also updates the icon keyword used in the ":toasts/upsert" event dispatch to respect icon guidelines.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2023-07-25 20:36:02 +05:30
mmilad75 ec6800216b Notification Centre - add Empty Content screen (#16715)
* Notification Centre - add Empty Content screen (#16715)
2023-07-25 18:06:00 +03:30
Alexander 15add24cd7 Show authout details in message preview of context drawer (#16765) 2023-07-25 15:34:32 +02:00
Parvesh Monu 28f790b436 fix missing duration value in muted chat button text (#16769) 2023-07-25 17:22:12 +05:30
Tetiana Churikova 9aafe61f5f gh: update templates (#16771) 2023-07-25 12:33:34 +02:00
frank 02d45fa06f discard backup message when recovering account (#16748)
* discard backup message when recovering account

* fix test failed

* update status-go-version.json
2023-07-25 15:03:57 +08:00
Yevheniia Berdnyk 99dc79842d e2e: nigthly fixes 24.07 2023-07-24 23:14:16 +03:00
Parvesh Monu 2a8e6cb304 Implement activity logs photos component (#16760) 2023-07-25 00:49:26 +05:30
Yevheniia Berdnyk eb3de978ce e2e: mute chats 2023-07-24 17:43:44 +03:00
Brian Sztamfater e672bf9163 feat: onboarding transition for new to status flow (#16554)
Signed-off-by: Brian Sztamfater <brian@status.im>
2023-07-24 10:17:36 -03:00
Omar Basem e33c877989 feat: camera screen (1/2) (#16569)
* feat: camera screen (1/2)
2023-07-24 16:46:43 +04:00
BalogunofAfrica c5a486622d feat: browser input (#16487) 2023-07-24 13:28:43 +02:00
flexsurferandYevheniia Berdnyk 00f39225ea Do not show biometrics onboarding screen if biometric is not available (#16744)
* fix biometric screen

* updated e2e

---------

Co-authored-by: Yevheniia Berdnyk <ie.berdnyk@gmail.com>
2023-07-24 13:06:35 +02:00
Ulises Manuel Cárdenas 0ac6817488 [#16551] - shared community name in switcher (#16576)
* Fix community tag text ellipsis
* Fix channel card overflow and ellipsis in switcher
2023-07-21 14:15:29 -06:00
Jamie Caprani 33d41dc5d5 Refactor Button and correct use of community color (#16536)
* chore: refactor button and add use for community colors

* chore: update color in button to work with community color

* chore: correct uses of button across app
2023-07-21 06:43:41 -07:00
Omar Basem 76eea91ba2 feat: category quo2 component (#16713)
* feat: category component
2023-07-21 10:13:36 +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
208 changed files with 4396 additions and 2047 deletions
+9 -1
View File
@@ -20,7 +20,15 @@
;; future, as we progressively fix shadowed
;; vars, we should be able to delete this
;; option and lint all vars.
:include [count iter key time]}
:include [comparator
count
identity
iter
key
str
symbol
time
val]}
: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
View File
@@ -22,7 +22,6 @@ KEYCARD_TEST_MENU=0
QR_READ_TEST_MENU=1
ENABLE_ROOT_ALERT=1
ENABLE_QUO_PREVIEW=1
MAX_IMAGES_BATCH=5
APN_TOPIC=im.status.ethereum.pr
COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1
-1
View File
@@ -21,7 +21,6 @@ COMMANDS_ENABLED=1
KEYCARD_TEST_MENU=1
QR_READ_TEST_MENU=1
ENABLE_ROOT_ALERT=0
MAX_IMAGES_BATCH=5
APN_TOPIC=im.status.ethereum.pr
VERIFY_TRANSACTION_CHAIN_ID=5
VERIFY_ENS_CHAIN_ID=5
-1
View File
@@ -26,7 +26,6 @@ VERIFY_TRANSACTION_CHAIN_ID=5
VERIFY_ENS_CHAIN_ID=5
TEST_STATEOFUS=1
BLANK_PREVIEW=0
MAX_IMAGES_BATCH=5
DATABASE_MANAGEMENT_ENABLED=1
COMMUNITIES_ENABLED=1
COMMUNITIES_MANAGEMENT_ENABLED=1
-1
View File
@@ -17,7 +17,6 @@ RPC_NETWORKS_ONLY=0
PARTITIONED_TOPIC=0
CONTRACT_NODES=1
ENABLE_ROOT_ALERT=1
MAX_IMAGES_BATCH=5
BLANK_PREVIEW=0
COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1
+4 -5
View File
@@ -1,8 +1,8 @@
---
name: Bug Report
about: Bug Report
name: MVPBug Report
about: MVPBug Report
title: ''
labels: bug
labels: E:MobileBugfixesMVP
assignees: ''
---
@@ -22,8 +22,7 @@ assignees: ''
### Reproduction
1) Open Status
2)
1.
### Additional Information
+30
View File
@@ -0,0 +1,30 @@
---
name: Wont fix Report
about: to facilitate future handling, identify and address non-urgent issues that won't be prioritized in the near future
title: ''
labels: likely_wont_fix
assignees: ''
---
## Problem
#### Expected behavior
#### Actual behavior
### Reproduction
1.
### Additional Information
- Status version: release
- Operating System: Android, iOS
[comment]: # (Please, add logs/notes if necessary)
+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)
@@ -626,10 +626,10 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void loginWithKeycard(final String accountData, final String password, final String chatKey) {
public void loginWithKeycard(final String accountData, final String password, final String chatKey, final String nodeConfigJSON) {
Log.d(TAG, "loginWithKeycard");
this.migrateKeyStoreDir(accountData, password);
String result = Statusgo.loginWithKeycard(accountData, password, chatKey);
String result = Statusgo.loginWithKeycard(accountData, password, chatKey, nodeConfigJSON);
if (result.startsWith("{\"error\":\"\"")) {
Log.d(TAG, "LoginWithKeycard result: " + result);
} else {
@@ -633,14 +633,15 @@ RCT_EXPORT_METHOD(loginAccount:(NSString *)request) {
RCT_EXPORT_METHOD(loginWithKeycard:(NSString *)accountData
password:(NSString *)password
chatKey:(NSString *)chatKey) {
chatKey:(NSString *)chatKey
nodeConfigJSON:(NSString *)nodeConfigJSON) {
#if DEBUG
NSLog(@"LoginWithKeycard() method called");
#endif
[self getExportDbFilePath];
[self migrateKeystore:accountData password:password];
NSString *result = StatusgoLoginWithKeycard(accountData, password, chatKey);
NSString *result = StatusgoLoginWithKeycard(accountData, password, chatKey, nodeConfigJSON);
NSLog(@"%@", result);
}
@@ -1041,7 +1041,7 @@ void _LoginWithKeycard(const FunctionCallbackInfo<Value>& args) {
Isolate* isolate = args.GetIsolate();
Local<Context> context = isolate->GetCurrentContext();
if (args.Length() != 3) {
if (args.Length() != 4) {
// Throw an Error that is passed back to JavaScript
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong number of arguments for LoginWithKeycard")));
@@ -1065,6 +1065,11 @@ void _LoginWithKeycard(const FunctionCallbackInfo<Value>& args) {
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'keyHex'")));
return;
}
if (!args[3]->IsString()) {
isolate->ThrowException(Exception::TypeError(
String::NewFromUtf8Literal(isolate, "Wrong argument type for 'nodeConfigJSON'")));
return;
}
String::Utf8Value arg0Obj(isolate, args[0]->ToString(context).ToLocalChecked());
@@ -1073,9 +1078,11 @@ void _LoginWithKeycard(const FunctionCallbackInfo<Value>& args) {
char *arg1 = *arg1Obj;
String::Utf8Value arg2Obj(isolate, args[2]->ToString(context).ToLocalChecked());
char *arg2 = *arg2Obj;
String::Utf8Value arg3Obj(isolate, args[3]->ToString(context).ToLocalChecked());
char *arg3 = *arg3Obj;
// Call exported Go function, which returns a C string
char *c = LoginWithKeycard(arg0, arg1, arg2);
char *c = LoginWithKeycard(arg0, arg1, arg2, arg3);
Local<String> ret = String::NewFromUtf8(isolate, c).ToLocalChecked();
args.GetReturnValue().Set(ret);
+1 -1
View File
@@ -44,7 +44,7 @@
"react-native-camera-kit": "^13.0.0",
"react-native-config": "^1.5.0",
"react-native-dialogs": "^1.0.4",
"react-native-draggable-flatlist": "^3.0.3",
"react-native-draggable-flatlist": "^4.0.1",
"react-native-fast-image": "^8.5.11",
"react-native-fetch-polyfill": "^1.1.2",
"react-native-fs": "^2.14.1",
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 421 KiB

+8 -8
View File
@@ -225,12 +225,12 @@
(.verifyDatabasePassword ^js (status) key-uid hashed-password callback))
(defn login-with-keycard
[{:keys [key-uid multiaccount-data password chat-key]}]
[{:keys [key-uid multiaccount-data password chat-key node-config]}]
(log/debug "[native-module] login-with-keycard")
(clear-web-data)
(init-keystore
key-uid
#(.loginWithKeycard ^js (status) multiaccount-data password chat-key)))
#(.loginWithKeycard ^js (status) multiaccount-data password chat-key (types/clj->json node-config))))
(defn set-soft-input-mode
[mode]
@@ -461,19 +461,19 @@
(.numberToHex ^js (status) (str num)))
(defn sha3
[str]
[s]
(log/debug "[native-module] sha3")
(.sha3 ^js (status) str))
(.sha3 ^js (status) s))
(defn utf8-to-hex
[str]
[s]
(log/debug "[native-module] utf8-to-hex")
(.utf8ToHex ^js (status) str))
(.utf8ToHex ^js (status) s))
(defn hex-to-utf8
[str]
[s]
(log/debug "[native-module] hex-to-utf8")
(.hexToUtf8 ^js (status) str))
(.hexToUtf8 ^js (status) s))
(defn check-address-checksum
[address]
+14 -14
View File
@@ -82,8 +82,8 @@
:restDisplacementThreshold 0.001}})
(defn set-value
[anim val]
(ocall anim "setValue" val))
[anim v]
(ocall anim "setValue" v))
(def Value (oget animated "Value"))
@@ -178,20 +178,20 @@
(.withOffset ^js redash (clj->js config)))
(defn with-spring-transition
[val config]
(.withSpringTransition ^js redash val (clj->js config)))
[v config]
(.withSpringTransition ^js redash v (clj->js config)))
(defn with-timing-transition
[val config]
(.withTimingTransition ^js redash val (clj->js config)))
[v config]
(.withTimingTransition ^js redash v (clj->js config)))
(defn use-spring-transition
[val config]
(.useSpringTransition ^js redash val (clj->js config)))
[v config]
(.useSpringTransition ^js redash v (clj->js config)))
(defn use-timing-transition
[val config]
(.useTimingTransition ^js redash val (clj->js config)))
[v config]
(.useTimingTransition ^js redash v (clj->js config)))
(defn re-timing
[config]
@@ -232,11 +232,11 @@
:onGestureEvent (.-onGestureEvent ^js gesture)}))
(defn snap-point
[value velocity snap-points]
(.snapPoint ^js redash value velocity (to-array snap-points)))
[v velocity snap-points]
(.snapPoint ^js redash v velocity (to-array snap-points)))
(defn with-easing
[{val :value
[{v :value
:keys [snap-points velocity offset state easing duration
animation-over]
:or {duration 250
@@ -257,7 +257,7 @@
(set position offset))
(cond* (neq state (:end gh/states))
[(set animation-over 0)
(set position (add offset val))])
(set position (add offset v))])
(cond* (and* (eq state (:end gh/states))
(not* animation-over))
[(set position
+5 -5
View File
@@ -12,9 +12,9 @@
;; Inspired from UIX, Rum and Rumext
(defn set-ref-val!
[ref val]
(oset! ref "current" val)
val)
[ref v]
(oset! ref "current" v)
v)
(defn set-native-props
[^js ref ^js props]
@@ -54,8 +54,8 @@
#js [value set-value])))
(defn use-ref
[val]
(let [ref (react/useRef val)]
[v]
(let [ref (react/useRef v)]
(reify
cljs.core/IHash
(-hash [_] (goog/getUid ref))
@@ -41,7 +41,7 @@
:border-radius dimensions}))
(defn initials-avatar
[size draw-ring? customization-color]
[size draw-ring? customization-color theme]
(let [outer-dimensions (get-in sizes [size :outer])
inner-dimensions (get-in sizes [size (if draw-ring? :inner :outer)])]
{:position :absolute
@@ -52,7 +52,7 @@
:border-radius inner-dimensions
:justify-content :center
:align-items :center
:background-color (colors/custom-color-by-theme customization-color 50 60)}))
:background-color (colors/custom-color-by-theme customization-color 50 60 nil nil theme)}))
(def initials-avatar-text
{:color colors/white-opa-70})
@@ -67,7 +67,7 @@
:background-color background}))
(defn dot
[size ring?]
[size ring? theme]
(let [dimensions (get-in sizes [size :status-indicator])
border-width (get-in sizes [size :status-indicator-border])
right (case size
@@ -89,5 +89,5 @@
:height dimensions
:border-width border-width
:border-radius dimensions
:background-color (colors/theme-colors colors/white colors/neutral-100)
:border-color (colors/theme-colors colors/white colors/neutral-100)}))
:background-color (colors/theme-colors colors/white colors/neutral-100 theme)
:border-color (colors/theme-colors colors/white colors/neutral-100 theme)}))
@@ -1,17 +1,18 @@
(ns quo2.components.avatars.user-avatar.view
(:require [quo2.components.avatars.user-avatar.style :as style]
[quo2.components.markdown.text :as text]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]
utils.string))
(defn initials-avatar
[{:keys [full-name size draw-ring? customization-color]}]
[{:keys [full-name size draw-ring? customization-color theme]}]
(let [font-size (get-in style/sizes [size :font-size])
amount-initials (if (#{:xs :xxs :xxxs} size) 1 2)]
[rn/view
{:accessibility-label :initials-avatar
:style (style/initials-avatar size draw-ring? customization-color)}
:style (style/initials-avatar size draw-ring? customization-color theme)}
[text/text
{:style style/initials-avatar-text
:size font-size
@@ -20,12 +21,12 @@
(def valid-ring-sizes #{:big :medium :small})
(defn user-avatar
(defn- user-avatar-internal
"If no `profile-picture` is given, draws the initials based on the `full-name` and
uses `ring-background` to display the ring behind the initials when given. Otherwise,
shows the `profile-picture` which already comes with the ring drawn."
[{:keys [full-name status-indicator? online? size profile-picture ring-background
customization-color static? muted?]
customization-color static? muted? theme]
:or {status-indicator? true
online? true
size :big
@@ -49,11 +50,14 @@
{:full-name full-name
:size size
:draw-ring? draw-ring?
:customization-color customization-color}])
:customization-color customization-color
:theme theme}])
(when status-indicator?
[rn/view
{:accessibility-label :status-indicator
:style (style/dot size draw-ring?)}
:style (style/dot size draw-ring? theme)}
[rn/view
{:accessibility-label :inner-status-indicator-dot
:style (style/inner-dot size online?)}]])]))
(def user-avatar (quo.theme/with-theme user-avatar-internal))
@@ -0,0 +1,58 @@
(ns quo2.components.browser.browser-input.component-spec
(:require [quo2.components.browser.browser-input.view :as browser-input]
[test-helpers.component :as h]))
(h/describe "Browser input"
(h/test "Renders empty in default state"
(h/render [browser-input/browser-input
{:on-change-text (h/mock-fn)
:value ""}])
(h/is-truthy (h/get-by-label-text :browser-input)))
(h/test "On change text is fired"
(let [on-change-text (h/mock-fn)]
(h/render [browser-input/browser-input
{:on-change-text on-change-text
:value "mock text"}])
(h/fire-event :change-text (h/get-by-label-text :browser-input) "mock-text-new")
(h/was-called on-change-text)))
(h/describe "Input Label"
(h/test "Doesn't render label text when input is focused"
(h/render [browser-input/browser-input
{:auto-focus true}])
(h/is-null (h/query-by-label-text :browser-input-label)))
(h/test "Renders label text when input has a value and input is not focused"
(h/render [browser-input/browser-input
{:default-value "mock default"}])
(h/is-truthy (h/query-by-label-text :browser-input-label)))
(h/test "Renders site favicon when specified"
(h/render [browser-input/browser-input
{:default-value "mock default" :favicon :i/verified}])
(h/is-truthy (h/query-by-label-text :browser-input-favicon)))
(h/test "Renders lock icon when lock is enabled"
(h/render [browser-input/browser-input
{:default-value "mock default" :locked? true}])
(h/is-truthy (h/query-by-label-text :browser-input-locked-icon))))
(h/describe "Clear button"
(h/test "Doesn't render in default state"
(h/render [browser-input/browser-input])
(h/is-null (h/query-by-label-text :browser-input-clear-button)))
(h/test "Renders when there is a value"
(h/render [browser-input/browser-input
{:default-value "mock text"}])
(h/is-truthy (h/query-by-label-text :browser-input-clear-button)))
(h/test "Is pressable"
(let [on-clear (h/mock-fn)]
(h/render [browser-input/browser-input
{:default-value "mock text"
:on-clear on-clear}])
(h/is-truthy (h/query-by-label-text :browser-input-clear-button))
(h/fire-event :press (h/query-by-label-text :browser-input-clear-button))
(h/was-called on-clear)))))
@@ -0,0 +1,56 @@
(ns quo2.components.browser.browser-input.style
(:require [quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))
(def clear-icon-container
{:align-items :center
:height 20
:justify-content :center
:margin-left 8
:top 4
:width 20})
(def favicon-icon-container
{:margin-right 2})
(defn input
[disabled?]
(assoc (text/text-style {:size :paragraph-1
:weight :regular})
:flex 1
:min-height 36
:min-width 120
:opacity (if disabled? 0.3 1)))
(def lock-icon-container
{:margin-left 2})
(defn active-container
[display?]
{:align-items :center
:flex-direction :row
:justify-content :center
:opacity (if display? 1 0)})
(def default-container
{:align-items :center
:bottom 0
:flex-direction :row
:left 0
:padding-horizontal 20
:position :absolute
:right 0
:top 0
:z-index 10})
(defn text
[]
(assoc (text/text-style {:size :paragraph-1
:weight :medium})
:color
(colors/theme-colors colors/neutral-100 colors/white)))
(def root-container
{:height 60
:padding-horizontal 20
:padding-vertical 8})
@@ -0,0 +1,144 @@
(ns quo2.components.browser.browser-input.view
(:require [quo2.components.icon :as icon]
[quo2.components.browser.browser-input.style :as style]
[react-native.core :as rn]
[reagent.core :as reagent]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo2.theme]
[clojure.string :as string]
[react-native.platform :as platform]))
(defn remove-http-https-www
[value]
(string/replace value #"(https?://(www\.)?|http://)" ""))
(defn clear-icon-color
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 theme)
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)))
(defn lock-icon-color
[blur? theme]
(if blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn- clear-button
[{:keys [on-press blur? theme]}]
[rn/touchable-opacity
{:accessibility-label :browser-input-clear-button
:on-press on-press
:style style/clear-icon-container}
[icon/icon :i/clear
{:color (clear-icon-color blur? theme)}]])
(defn lock-icon
[{:keys [blur? theme]}]
[rn/view
[icon/icon :i/locked
{:accessibility-label :browser-input-locked-icon
:color (lock-icon-color blur? theme)
:container-style style/lock-icon-container
:size 16}]])
(defn cursor-color
[customization-color theme]
(colors/theme-colors (colors/custom-color customization-color 50)
(colors/custom-color customization-color 60)
theme))
(defn placeholder-color
[state blur? theme]
(cond
(and blur? (= state :active))
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
blur?
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 theme)
(= state :active)
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
:else
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
(def ^:private props-to-remove
[:cursor-color :placeholder-text-color :editable :on-change-text :on-focus
:on-blur :on-clear :value :disabled? :blur? :customization-color :theme])
(defn browser-input-internal
[{:keys [default-value]
:or {default-value ""}}]
(let [state (reagent/atom :default)
value (reagent/atom default-value)
set-active #(reset! state :active)
set-default #(reset! state :default)
set-value #(reset! value %)
ref (atom nil)
clear-input (fn []
(.clear ^js @ref)
(reset! value ""))
focus-input (fn []
(set-active)
(.focus ^js @ref))]
(fn [{:keys [disabled? blur? on-change-text customization-color
on-clear on-focus on-blur theme get-ref locked?
favicon favicon-color favicon-size]
:as props}]
(let [clean-props (apply dissoc props props-to-remove)]
[rn/view {:style style/root-container}
(when (and (seq @value) (= @state :default))
[rn/touchable-opacity
{:style style/default-container
:on-press focus-input}
(when favicon
[icon/icon favicon
{:accessibility-label :browser-input-favicon
:color favicon-color
:container-style style/favicon-icon-container
:size favicon-size}])
[rn/text
{:accessibility-label :browser-input-label
:style (style/text)} (remove-http-https-www @value)]
(when locked?
[lock-icon
{:blur? blur?
:theme theme}])])
[rn/view {:style (style/active-container (or (empty? @value) (= @state :active)))}
[rn/text-input
(merge
clean-props
{:accessibility-label :browser-input
:auto-capitalize :none
:auto-correct false
:cursor-color (cursor-color customization-color theme)
:editable (not disabled?)
:keyboard-appearance (colors/theme-colors :light :dark theme)
:keyboard-type :web-search
:on-blur (fn []
(set-default)
(when on-blur (on-blur)))
:on-change-text (fn [new-text]
(set-value new-text)
(when on-change-text (on-change-text new-text)))
:on-focus (fn []
(set-active)
(when on-focus (on-focus)))
:placeholder-text-color (placeholder-color @state blur? theme)
:ref (fn [r]
(reset! ref r)
(when get-ref (get-ref r)))
:selection-color (when platform/ios?
(cursor-color customization-color theme))
:select-text-on-focus true
:style (style/input disabled?)})]
(when (seq @value)
[clear-button
{:blur? blur?
:on-press (fn []
(clear-input)
(when on-clear (on-clear)))
:theme theme}])]]))))
(def browser-input (quo2.theme/with-theme browser-input-internal))
@@ -0,0 +1,103 @@
(ns quo2.components.buttons.button.properties
(:require [quo2.foundations.colors :as colors]))
(defn custom-color-type
[customization-color icon-only?]
{:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color (colors/custom-color customization-color 50)
:border-radius (when icon-only? 24)})
(defn grey-photo
[theme pressed?]
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:icon-background-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
:blur-overlay-color (if pressed?
(colors/theme-colors colors/white-opa-50
colors/neutral-80-opa-50
theme)
(colors/theme-colors colors/white-opa-40
colors/neutral-80-opa-40
theme))
:blur-type (if (= theme :light) :light :dark)})
(defn grey-blur
[theme pressed?]
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-70 theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:background-color (if pressed?
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 theme))})
(defn outline-blur
[theme pressed?]
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
:icon-secondary-color (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if pressed?
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
(colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme))})
(defn grey
[theme pressed?]
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:background-color (if pressed?
(colors/theme-colors colors/neutral-20 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
(defn dark-grey
[theme pressed?]
{:icon-color (colors/theme-colors colors/neutral-100 colors/white theme)
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:background-color (if pressed?
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-20 colors/neutral-90 theme))})
(defn outline
[theme pressed?]
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:border-color (if pressed?
(colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
(colors/theme-colors colors/neutral-30 colors/neutral-70 theme))})
(defn ghost
[theme pressed?]
{:icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:icon-secondary-color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
:label-color (colors/theme-colors colors/neutral-100 colors/white theme)
:background-color (when pressed?
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
(defn black
[pressed?]
{:icon-color colors/white
:label-color colors/white
:background-color (if pressed? colors/neutral-80 colors/neutral-95)})
(defn get-values
[{:keys [customization-color theme type background pressed? icon-only?]}]
(cond
(= type :primary) (custom-color-type customization-color icon-only?)
(= type :positive) (custom-color-type customization-color icon-only?)
(= type :danger) (custom-color-type customization-color icon-only?)
;; TODO Remove type blurred - https://github.com/status-im/status-mobile/issues/16535
(and (= :photo background) (= type :grey)) (grey-photo theme pressed?)
;; TODO Remove type blur-bg - https://github.com/status-im/status-mobile/issues/16535
(or (= type :blur-bg)
(and (= :blur background) (= type :grey))) (grey-blur theme pressed?)
(and (= :blur background) (= type :outline)) (outline-blur theme pressed?)
(= type :grey) (grey theme pressed?)
(= type :dark-grey) (dark-grey theme pressed?)
(= type :outline) (outline theme pressed?)
(= type :ghost) (ghost theme pressed?)
;; TODO: remove type shell - https://github.com/status-im/status-mobile/issues/16535
(or (= type :shell) (= type :black)) (black pressed?)))
+53 -211
View File
@@ -1,5 +1,4 @@
(ns quo2.components.buttons.button.style
(:require [quo2.foundations.colors :as colors]))
(ns quo2.components.buttons.button.style)
(def blur-view
{:position :absolute
@@ -8,254 +7,97 @@
:right 0
:bottom 0})
(defn before-icon-style
(defn icon-style
[{:keys [icon-container-size icon-background-color icon-container-rounded?
icon-size margin-left margin-right]}]
(cond-> (merge {:margin-left margin-left
:margin-right margin-right
:align-items :center
:justify-content :center})
icon-container-size
(assoc :width icon-container-size :height icon-container-size)
icon-background-color
(assoc :background-color icon-background-color)
icon-container-rounded?
(assoc :border-radius (/ (or icon-container-size icon-size) 2))))
(defn icon-left-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)})))
(icon-style
{:margin-left (or (get override-margins :left)
(if (= size 40) 12 8))
:margin-right (or (get override-margins :right) 4)
:icon-container-size icon-container-size
:icon-background-color icon-background-color
:icon-container-rounded? icon-container-rounded?
:icon-size icon-size}))
(defn after-icon-style
(defn icon-right-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]
{:light
{:primary {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default (colors/custom-color customization-color 50)
:pressed (colors/custom-color customization-color 60)
:disabled (colors/custom-color customization-color 50)}}
:secondary {:icon-color colors/primary-50
:label-color colors/primary-50
:background-color {:default colors/primary-50-opa-20
:pressed colors/primary-50-opa-40
:disabled colors/primary-50-opa-20}}
:grey {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:default colors/neutral-10
:pressed colors/neutral-20
:disabled colors/neutral-10}}
:dark-grey {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:default colors/neutral-20
:pressed colors/neutral-30
:disabled colors/neutral-20}}
:outline {:icon-color colors/neutral-50
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:border-color {:default colors/neutral-30
:pressed colors/neutral-40
:disabled colors/neutral-30}}
:ghost {:icon-color colors/neutral-50
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:pressed colors/neutral-10}}
:danger {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/danger-50
:pressed colors/danger-60
:disabled colors/danger-50}}
:positive {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/success-50
:pressed colors/success-60
:disabled colors/success-50-opa-30}}
:photo-bg {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:background-color {:default colors/white-opa-40
:pressed colors/white-opa-50
:disabled colors/white-opa-40}}
:blur-bg {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:background-color {:default colors/neutral-80-opa-5
:pressed colors/neutral-80-opa-10
:disabled colors/neutral-80-opa-5}}
:blurred {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-100
:icon-background-color {:default colors/neutral-20
:blurred colors/neutral-80-opa-10}
:label-color colors/neutral-100
:background-color {:default colors/neutral-10
:pressed colors/neutral-10
:disabled colors/neutral-10-opa-10-blur}
:blur-overlay-color colors/neutral-10-opa-40-blur
:blur-type :light}
:blur-bg-outline {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:border-color {:default colors/neutral-80-opa-10
:pressed colors/neutral-80-opa-20
:disabled colors/neutral-80-opa-10}}
:shell {:icon-color colors/white
:label-color colors/white
:background-color {:default colors/neutral-95
:pressed colors/neutral-95
:disabled colors/neutral-95}}}
:dark
{:primary {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default (colors/custom-color customization-color 60)
:pressed (colors/custom-color customization-color 50)
:disabled (colors/custom-color customization-color 60)}}
:secondary {:icon-color colors/primary-50
:label-color colors/primary-50
:background-color {:default colors/primary-50-opa-20
:pressed colors/primary-50-opa-30
:disabled colors/primary-50-opa-20}}
:grey {:icon-color colors/white
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:default colors/neutral-90
:pressed colors/neutral-60
:disabled colors/neutral-90}}
:dark-grey {:icon-color colors/white
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:default colors/neutral-70
:pressed colors/neutral-60
:disabled colors/neutral-70}}
:outline {:icon-color colors/neutral-40
:icon-secondary-color colors/neutral-40
:label-color colors/white
:border-color {:default colors/neutral-70
:pressed colors/neutral-60
:disabled colors/neutral-70}}
:ghost {:icon-color colors/neutral-40
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:pressed colors/neutral-80}}
:danger {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/danger-60
:pressed colors/danger-50
:disabled colors/danger-60}}
:positive {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/success-60
:pressed colors/success-50
:disabled colors/success-60-opa-30}}
:photo-bg {:icon-color colors/white
:icon-secondary-color colors/neutral-30
:label-color colors/white
:background-color {:default colors/neutral-80-opa-40
:pressed colors/neutral-80-opa-50
:disabled colors/neutral-80-opa-40}}
:blur-bg {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/white-opa-5
:pressed colors/white-opa-10
:disabled colors/white-opa-5}}
:blurred {:icon-color colors/white
:icon-secondary-color colors/white
:icon-background-color {:default colors/neutral-80
:blurred colors/white-opa-10}
:label-color colors/white
:background-color {:default colors/neutral-90
:pressed colors/neutral-90
:disabled colors/neutral-90-opa-10-blur}
:blur-overlay-color colors/neutral-80-opa-40
:blur-type :dark}
:blur-bg-outline {:icon-color colors/white
:icon-secondary-color colors/white-opa-40
:label-color colors/white
:border-color {:default colors/white-opa-10
:pressed colors/white-opa-20
:disabled colors/white-opa-5}}
:shell {:icon-color colors/white
:label-color colors/white
:background-color {:default colors/neutral-95}}}})
(icon-style {:margin-left (or (get override-margins :left) 4)
:margin-right (or (get override-margins :right)
(if (= size 40) 12 8))
:icon-container-size icon-container-size
:icon-background-color icon-background-color
:icon-container-rounded? icon-container-rounded?
:icon-size icon-size}))
(defn shape-style-container
[type icon size]
[size border-radius]
{:height size
:border-radius (if (and icon (#{:primary :secondary :danger} type))
24
:border-radius (if border-radius
border-radius
(case size
56 12
40 12
32 10
24 8))})
8))})
(defn style-container
[{:keys [type size disabled background-color border-color icon above width before after blur-active?]}]
[{:keys [size disabled border-radius background-color border-color icon-only? icon-above width
icon-left icon-right]}]
(merge {:height size
:align-items :center
:justify-content :center
:flex-direction (if above :column :row)
:padding-horizontal (when-not (or icon before after)
:flex-direction (if icon-above :column :row)
:padding-horizontal (when-not (or icon-only? icon-left icon-right)
(case size
56 16
40 16
32 12
24 8))
:padding-left (when-not (or icon before)
8))
:padding-left (when-not (or icon-only? icon-left)
(case size
56 16
40 16
32 12
24 8))
:padding-right (when-not (or icon after)
8))
:padding-right (when-not (or icon-only? icon-right)
(case size
56 16
40 16
32 12
24 8))
:padding-top (when-not (or icon before after)
8))
:padding-top (when-not (or icon-only? icon-left icon-right)
(case size
56 0
40 9
32 5
24 3))
:padding-bottom (when-not (or icon before after)
3))
:padding-bottom (when-not (or icon-only? icon-left icon-right)
(case size
56 0
40 9
32 5
24 4))
:overflow :hidden}
(when (or (and (= type :blurred) (not blur-active?))
(not= type :blurred))
{:background-color background-color})
(shape-style-container type icon size)
4))
:overflow :hidden
:background-color background-color}
(shape-style-container size border-radius)
(when width
{:width width})
(when icon
(when icon-only?
{:width size})
(when border-color
{:border-color border-color
+77 -76
View File
@@ -5,110 +5,116 @@
[react-native.core :as rn]
[react-native.blur :as blur]
[reagent.core :as reagent]
[quo2.components.buttons.button.style :as style]))
[quo2.components.buttons.button.style :as style]
[quo2.components.buttons.button.properties :as button-properties]
[quo2.foundations.customization-colors :as customization-colors]))
(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
{on-press callback
on-long-press callback
disabled boolean
:type :primary/:positive:grey/:dark-grey/:outline/:ghost/
:danger/:black (TODO remove :photo-bg/:blur-bg/:blur-bg-outline/:shell/:community)
background :photo/:blur or nil
:size 40 [default] /32/24/56
:icon true/false
:community-color '#FFFFFF'
:community-text-color '#000000'
:above :icon-keyword
:before :icon-keyword
:after :icon-keyword}
:customization-color keyword or hexstring
:theme :light/:dark
only icon
[button {:icon true} :i/close-circle]"
[_ _]
(let [pressed-in (reagent/atom false)]
(let [pressed? (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?]
[{:keys [on-press on-long-press disabled type background size before after above
width customization-color theme override-background-color
accessibility-label icon style inner-style]
:or {type :primary
size 40
customization-color :primary
blur-active? true}}
customization-color (cond (= type :primary) :blue
(= type :positive) :success
(= type :danger) :danger
:else nil)}}
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))
(let [icon-only? icon ;; TODO Update external api to icon-only? -
;; https://github.com/status-im/status-mobile/issues/16535
container-style style ;; TODO Update external api to container-style and remove prop width
icon-left before ;; TODO Update external api to icon-left
icon-right after ;; TODO Update external api to icon-right
icon-above above ;; TODO Update external api to icon-above
{:keys [icon-color icon-secondary-color background-color label-color border-color blur-type
blur-overlay-color icon-background-color border-radius]}
(button-properties/get-values {:customization-color customization-color
:background background
:type type
:theme theme
:pressed? @pressed?
:icon-only? icon-only?})
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}))
{:disabled disabled
:accessibility-label accessibility-label
:on-press-in #(reset! pressed? true)
:on-press-out #(reset! pressed? nil)
:on-press on-press
:on-long-press on-long-press}
[rn/view
{:style (merge
(style/shape-style-container type icon size)
(style/shape-style-container size border-radius)
{:width width}
style)}
container-style)}
[rn/view
{:style (merge
(style/style-container {:type type
:size size
(style/style-container {:size size
:disabled disabled
:border-radius border-radius
:background-color
(or override-background-color (get background-color state))
:border-color
(get border-color state)
:icon icon
:above above
(or override-background-color background-color)
:border-color border-color
:icon-only? icon-only?
:icon-above icon-above
:width width
:before before
:after after
:blur-active? blur-active?})
(when (= state :pressed) {:opacity 0.9})
:icon-left icon-left
:icon-right icon-right})
inner-style)}
(when (and (= type :blurred)
blur-active?)
(when customization-color
[customization-colors/overlay
{:customization-color customization-color
:theme theme
:pressed? @pressed?}])
(when (= background :photo)
[blur/view
{:blur-radius 20
:blur-type blur-type
:overlay-color blur-overlay-color
:style style/blur-view}])
(when above
(when icon-above
[rn/view
[quo2.icons/icon above
[quo2.icons/icon icon-above
{:container-style {:margin-bottom 2}
:color icon-secondary-color
:size icon-size}]])
(when before
(when icon-left
[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
{:style (style/icon-left-icon-style
{:size size
:icon-background-color icon-background-color
:icon-size icon-size})}
[quo2.icons/icon icon-left
{:color icon-secondary-color
:size icon-size}]])
[rn/view
(cond
(or icon icon-no-color)
icon-only?
[quo2.icons/icon children
{:color icon-color
:no-color icon-no-color
:size icon-size}]
{:color icon-color
:size icon-size}]
(string? children)
[text/text
@@ -116,23 +122,18 @@
:weight :medium
:number-of-lines 1
:style {:color label-color}}
children]
(vector? children)
children)]
(when after
(when icon-right
[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}]])]]]))))
{:style (style/icon-right-icon-style
{:size size
:icon-background-color icon-background-color
:icon-size icon-size})}
[quo2.icons/icon icon-right
{:color icon-secondary-color
:size icon-size}]])]]]))))
(def button (theme/with-theme button-internal))
@@ -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,18 +22,65 @@
: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]
unread-messages?
[unread-grey-dot :unviewed-messages-public]))
(defn communities-membership-list-item
(defn communities-list-view-item
[props
{:keys [name
muted?
locked?
status
muted
unread-messages?
unread-mentions-count
community-icon
tokens]}]
[rn/view
{:style (merge (style/community-card 16)
{:margin-bottom 12})}
[rn/touchable-highlight
(merge {:style {:height 56
:border-radius 16}}
props)
[rn/view {:style style/detail-container}
[rn/view (style/list-info-container)
[community-icon/community-icon
{:images community-icon} 32]
[rn/view
{:flex 1
:margin-horizontal 12}
[text/text
{:weight :semi-bold
:size :paragraph-1
:accessibility-label :community-name-text
:number-of-lines 1
:ellipsize-mode :tail
:style {:color (when muted
(colors/theme-colors
colors/neutral-40
colors/neutral-60))}}
name]
[community-view/community-stats-column
{:type :list-view}]]
(if (= status :gated)
[community-view/permission-tag-container
{:locked? locked?
:tokens tokens}]
[notification-view
{:muted? muted
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]])
(defn communities-membership-list-item
[props
bottom-sheet?
{:keys [name
muted
unviewed-messages-count
unviewed-mentions-count
status
@@ -59,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)}])]]])
@@ -12,11 +12,11 @@
{:style (style/token-row padding?)}
(doall
(map-indexed (fn [token-index token]
(let [{:keys [img-src symbol amount sufficient? purchasable? loading?]} token]
(let [{:keys [img-src amount sufficient? purchasable? loading?]} token]
^{:key token-index}
[rn/view {:style style/token-tag-spacing}
[token-tag/token-tag
{:symbol symbol
{:symbol (:symbol token)
:value amount
:size 24
:sufficient? sufficient?
@@ -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)))))])
+4 -2
View File
@@ -1,10 +1,12 @@
(ns quo2.components.dropdowns.dropdown
(:require [quo2.components.buttons.button.view :as button]))
(:require [quo2.components.dropdowns.old-button-view :as old-button]))
(defn dropdown
[_ _]
(fn [{:keys [on-change selected] :as opts} children]
[button/button
;TODO: Dropdown needs to be implemented/refactored to be its own component -
;https://github.com/status-im/status-mobile/issues/16456
[old-button/button
(merge
opts
{:after (if selected :i/chevron-top :i/chevron-down)
@@ -0,0 +1,264 @@
(ns quo2.components.dropdowns.old-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]
{:light
{:primary {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default (colors/custom-color customization-color 50)
:pressed (colors/custom-color customization-color 60)
:disabled (colors/custom-color customization-color 50)}}
:secondary {:icon-color colors/primary-50
:label-color colors/primary-50
:background-color {:default colors/primary-50-opa-20
:pressed colors/primary-50-opa-40
:disabled colors/primary-50-opa-20}}
:grey {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:default colors/neutral-10
:pressed colors/neutral-20
:disabled colors/neutral-10}}
:dark-grey {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:default colors/neutral-20
:pressed colors/neutral-30
:disabled colors/neutral-20}}
:outline {:icon-color colors/neutral-50
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:border-color {:default colors/neutral-30
:pressed colors/neutral-40
:disabled colors/neutral-30}}
:ghost {:icon-color colors/neutral-50
:icon-secondary-color colors/neutral-50
:label-color colors/neutral-100
:background-color {:pressed colors/neutral-10}}
:danger {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/danger-50
:pressed colors/danger-60
:disabled colors/danger-50}}
:positive {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/success-50
:pressed colors/success-60
:disabled colors/success-50-opa-30}}
:photo-bg {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:background-color {:default colors/white-opa-40
:pressed colors/white-opa-50
:disabled colors/white-opa-40}}
:blur-bg {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:background-color {:default colors/neutral-80-opa-5
:pressed colors/neutral-80-opa-10
:disabled colors/neutral-80-opa-5}}
:blurred {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-100
:icon-background-color {:default colors/neutral-20
:blurred colors/neutral-80-opa-10}
:label-color colors/neutral-100
:background-color {:default colors/neutral-10
:pressed colors/neutral-10
:disabled colors/neutral-10-opa-10-blur}
:blur-overlay-color colors/neutral-10-opa-40-blur
:blur-type :light}
:blur-bg-outline {:icon-color colors/neutral-100
:icon-secondary-color colors/neutral-80-opa-40
:label-color colors/neutral-100
:border-color {:default colors/neutral-80-opa-10
:pressed colors/neutral-80-opa-20
:disabled colors/neutral-80-opa-10}}
:shell {:icon-color colors/white
:label-color colors/white
:background-color {:default colors/neutral-95
:pressed colors/neutral-95
:disabled colors/neutral-95}}}
:dark
{:primary {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default (colors/custom-color customization-color 60)
:pressed (colors/custom-color customization-color 50)
:disabled (colors/custom-color customization-color 60)}}
:secondary {:icon-color colors/primary-50
:label-color colors/primary-50
:background-color {:default colors/primary-50-opa-20
:pressed colors/primary-50-opa-30
:disabled colors/primary-50-opa-20}}
:grey {:icon-color colors/white
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:default colors/neutral-90
:pressed colors/neutral-60
:disabled colors/neutral-90}}
:dark-grey {:icon-color colors/white
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:default colors/neutral-70
:pressed colors/neutral-60
:disabled colors/neutral-70}}
:outline {:icon-color colors/neutral-40
:icon-secondary-color colors/neutral-40
:label-color colors/white
:border-color {:default colors/neutral-70
:pressed colors/neutral-60
:disabled colors/neutral-70}}
:ghost {:icon-color colors/neutral-40
:icon-secondary-color colors/neutral-40
:label-color colors/white
:background-color {:pressed colors/neutral-80}}
:danger {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/danger-60
:pressed colors/danger-50
:disabled colors/danger-60}}
:positive {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/success-60
:pressed colors/success-50
:disabled colors/success-60-opa-30}}
:photo-bg {:icon-color colors/white
:icon-secondary-color colors/neutral-30
:label-color colors/white
:background-color {:default colors/neutral-80-opa-40
:pressed colors/neutral-80-opa-50
:disabled colors/neutral-80-opa-40}}
:blur-bg {:icon-color colors/white
:icon-secondary-color colors/white-opa-70
:label-color colors/white
:background-color {:default colors/white-opa-5
:pressed colors/white-opa-10
:disabled colors/white-opa-5}}
:blurred {:icon-color colors/white
:icon-secondary-color colors/white
:icon-background-color {:default colors/neutral-80
:blurred colors/white-opa-10}
:label-color colors/white
:background-color {:default colors/neutral-90
:pressed colors/neutral-90
:disabled colors/neutral-90-opa-10-blur}
:blur-overlay-color colors/neutral-80-opa-40
:blur-type :dark}
:blur-bg-outline {:icon-color colors/white
:icon-secondary-color colors/white-opa-40
:label-color colors/white
:border-color {:default colors/white-opa-10
:pressed colors/white-opa-20
:disabled colors/white-opa-5}}
:shell {:icon-color colors/white
:label-color colors/white
:background-color {:default colors/neutral-95}}}})
(defn shape-style-container
[type icon size]
{:height size
:border-radius (if (and icon (#{:primary :secondary :danger} type))
24
(case size
56 12
40 12
32 10
24 8))})
(defn style-container
[{:keys [type size disabled background-color border-color icon above width before after blur-active?]}]
(merge {:height size
:align-items :center
:justify-content :center
:flex-direction (if above :column :row)
:padding-horizontal (when-not (or icon before after)
(case size
56 16
40 16
32 12
24 8))
:padding-left (when-not (or icon before)
(case size
56 16
40 16
32 12
24 8))
:padding-right (when-not (or icon after)
(case size
56 16
40 16
32 12
24 8))
:padding-top (when-not (or icon before after)
(case size
56 0
40 9
32 5
24 3))
:padding-bottom (when-not (or icon before after)
(case size
56 0
40 9
32 5
24 4))
:overflow :hidden}
(when (or (and (= type :blurred) (not blur-active?))
(not= type :blurred))
{:background-color background-color})
(shape-style-container type icon size)
(when width
{:width width})
(when icon
{:width size})
(when border-color
{:border-color border-color
:border-width 1})
(when disabled
{:opacity 0.3})))
@@ -0,0 +1,138 @@
(ns quo2.components.dropdowns.old-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.dropdowns.old-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))
@@ -24,7 +24,3 @@
{:color colors/white}))
(def button-container {:margin-top 20})
(defn upper-button-color
[customization-color]
(colors/custom-color-by-theme customization-color 50 60))
@@ -33,10 +33,10 @@
upper-button-on-press :on-press} upper-button]
[rn/view {:style styles/button-container}
[button/button
{:type :primary
:size 32
:override-background-color (styles/upper-button-color customization-color)
:on-press upper-button-on-press}
{:type :primary
:size 32
:customization-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]
+7 -7
View File
@@ -3,6 +3,7 @@
[quo2.components.icons.icons :as icons]
[quo2.components.icons.svg :as icons.svg]
[quo2.foundations.colors :as colors]
[quo2.theme :as quo.theme]
[react-native.core :as rn]))
(defn- valid-color?
@@ -12,11 +13,10 @@
(not (string/blank? color)))))
(defn memo-icon-fn
[icon-name
{:keys [color color-2 no-color
container-style size accessibility-label]
[{:keys [color color-2 no-color
container-style size accessibility-label theme]
:or {accessibility-label :icon}}
_]
icon-name]
(let [size (or size 20)]
^{:key icon-name}
(if-let [svg-icon (icons.svg/get-icon icon-name size)]
@@ -34,15 +34,15 @@
(when (not no-color)
{:tint-color (if (and (string? color) (not (string/blank? color)))
color
(colors/theme-colors colors/neutral-100 colors/white))})
(colors/theme-colors colors/neutral-100 colors/white theme))})
container-style)
:accessibility-label accessibility-label
:source (icons/icon-source (str (name icon-name) size))}])))
(def themed-icon (memoize memo-icon-fn))
(def ^:private themed-icon (memoize (quo.theme/with-theme memo-icon-fn)))
(defn icon
([icon-name] (icon icon-name nil))
([icon-name params]
(themed-icon icon-name params (colors/dark?))))
(themed-icon params icon-name)))
+2 -1
View File
@@ -35,4 +35,5 @@
(get-icons 16)
(get-icons 20)
(get-icons 24)
(get-icons 32)))
(get-icons 32)
(get-icons 48)))
@@ -4,7 +4,6 @@
[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]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.hole-view :as hole-view]))
@@ -35,16 +34,16 @@
:status-indicator? false
:size :medium)]]
[buttons/button
{:accessibility-label :select-profile-picture-button
:type :grey
:override-background-color (colors/alpha colors/white 0.05)
:on-press on-press
:icon-size 20
:width 24
:size 24
:icon :i/camera
:style style/button
:inner-style style/button-inner} :i/camera]]
{:accessibility-label :select-profile-picture-button
:type :grey
:background :blur
:on-press on-press
:icon-size 20
:width 24
:size 24
:icon :i/camera
:style style/button
:inner-style style/button-inner} :i/camera]]
[rn/view {:style style/input-container}
[title-input/title-input
(merge title-input-props
@@ -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)}))
+19 -10
View File
@@ -1,12 +1,12 @@
(ns quo2.components.markdown.text
(:require [quo2.foundations.colors :as colors]
[quo2.foundations.typography :as typography]
[quo2.theme :as theme]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn text-style
[{:keys [size align weight style]}]
[{:keys [size align weight style theme]}]
(merge (case (or weight :regular)
:regular typography/font-regular
:medium typography/font-medium
@@ -25,14 +25,23 @@
{:text-align (or align :auto)}
(if (:color style)
style
(assoc style :color (if (= (theme/get-theme) :dark) colors/white colors/neutral-100)))))
(assoc style
:color
(if (= (or theme (quo.theme/get-theme)) :dark) colors/white colors/neutral-100)))))
(defn- text-view-internal
[props & children]
(let [style (text-style props)]
(into [rn/text
(merge {:style style}
(dissoc props :style :size :align :weight :color :theme))]
children)))
(def ^:private text-view (quo.theme/with-theme text-view-internal))
(defn text
[]
(let [this (reagent/current-component)
props (reagent/props this)
style (text-style props)]
(into [rn/text
(merge {:style style}
(dissoc props :style :size :align :weight :color))]
(reagent/children this))))
(let [this (reagent/current-component)
props (reagent/props this)
children (reagent/children this)]
(into [text-view props] children)))
+3 -2
View File
@@ -82,11 +82,12 @@
:border-radius 50}])
(defn timestamp
[str]
[s]
[text/text
{:size :label
:style {:text-transform :none
:color (get-color :time)}} str])
:color (get-color :time)}}
s])
(defn info-button
[on-press]
@@ -25,11 +25,12 @@
(def message-body
{:color colors/white})
(def message-container
(defn message-container
[attachment]
{:border-radius 12
:margin-top 12
:padding-horizontal 12
:padding-vertical 8
:padding-vertical (if (#{:photo :gif} attachment) 12 8)
:background-color colors/white-opa-5})
(def footer-container
@@ -74,8 +74,8 @@
context))))
(defn- activity-message
[{:keys [title body title-number-of-lines body-number-of-lines]}]
[rn/view {:style style/message-container}
[{:keys [title body title-number-of-lines body-number-of-lines attachment]}]
[rn/view {:style (style/message-container attachment)}
(when title
[text/text
{:size :paragraph-2
@@ -0,0 +1,13 @@
(ns quo2.components.notifications.activity-logs-photos.style)
(def photos-container
{:flex 1
:height 40
:flex-direction :row})
(defn photo
[index]
{:width 40
:height 40
:border-radius 10
:margin-left (if (= index 0) 0 8)})
@@ -0,0 +1,14 @@
(ns quo2.components.notifications.activity-logs-photos.view
(:require [react-native.core :as rn]
[quo2.components.notifications.activity-logs-photos.style :as style]))
(defn view
[{:keys [photos]}]
[rn/view {:style style/photos-container}
(map-indexed
(fn [index photo]
^{:key index}
[rn/image
{:source photo
:style (style/photo index)}])
photos)])
@@ -1,7 +1,7 @@
(ns quo2.components.notifications.count-down-circle
(:require [goog.string :as gstring]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[react-native.svg :as svg]
[reagent.core :as reagent]))
@@ -48,8 +48,8 @@
{:color {:dark colors/neutral-80-opa-40
:light colors/white-opa-40}})
(defn circle-timer
[{:keys [color duration size stroke-width trail-color rotation initial-remaining-time]}]
(defn- circle-timer-internal
[{:keys [color duration size stroke-width trail-color rotation initial-remaining-time theme]}]
(let [rotation (or rotation :clockwise)
duration (or duration 4)
stroke-width (or stroke-width 1)
@@ -98,8 +98,10 @@
[svg/path
{:d path
:fill :none
:stroke (or color (get-in themes [:color (theme/get-theme)]))
:stroke (or color (get-in themes [:color theme]))
:stroke-linecap :square
:stroke-width stroke-width
:stroke-dasharray path-length
:stroke-dashoffset (linear-ease @display-time 0 path-length duration)}])]])})))
(def circle-timer (quo.theme/with-theme circle-timer-internal))
@@ -3,10 +3,12 @@
[quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]))
(def box-container
{:margin-horizontal 12
:border-radius 12
:overflow :hidden})
(defn box-container
[theme]
(merge (shadows/get 1 theme)
{:margin-horizontal 12
:border-radius 12
:overflow :hidden}))
(def blur-container
{:height "100%"
@@ -19,35 +21,33 @@
(defn content-container
[theme]
(merge
(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
:padding-left 10
:padding-right 8
:border-radius 12}))
{: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
:padding-left 10
:padding-right 8
:border-radius 12})
(defn title
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
[theme]
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
(defn text
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
[theme]
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
(defn icon
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)
[theme]
{:color (colors/theme-colors colors/white colors/neutral-100 theme)
:container-style {:width 20 :height 20}})
(def left-side-container {:padding 2})
(def right-side-container {:padding 4 :flex 1})
(defn action-container
[override-theme]
{:background-color (colors/theme-colors colors/white-opa-5 colors/neutral-80-opa-5 override-theme)
[theme]
{:background-color (colors/theme-colors colors/white-opa-5 colors/neutral-80-opa-5 theme)
:flex-direction :row
:padding-vertical 3
:padding-horizontal 8
@@ -4,33 +4,40 @@
[quo2.components.markdown.text :as text]
[quo2.components.notifications.count-down-circle :as count-down-circle]
[quo2.components.notifications.toast.style :as style]
[quo2.theme :as theme]
[quo2.theme :as quo.theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[utils.i18n :as i18n]))
(defn toast-action-container
[{:keys [on-press style]} & children]
[{:keys [on-press style theme]} & children]
[rn/touchable-highlight
{:on-press on-press
:underlay-color :transparent}
[into
[rn/view
{:style (merge (style/action-container (theme/get-theme)) style)}]
{:style (merge (style/action-container theme) style)}]
children]])
(defn toast-undo-action
[duration on-press override-theme]
[toast-action-container {:on-press on-press :accessibility-label :toast-undo-action}
(defn toast-undo-action-internal
[{:keys [undo-duration undo-on-press theme]}]
[toast-action-container
{:on-press undo-on-press
:accessibility-label :toast-undo-action
:theme theme}
[rn/view {:style {:margin-right 5}}
[count-down-circle/circle-timer {:duration duration}]]
[count-down-circle/circle-timer {:duration undo-duration}]]
[text/text
{:size :paragraph-2 :weight :medium :style (style/text override-theme)}
{:size :paragraph-2
:weight :medium
:style (style/text theme)}
[i18n/label :t/undo]]])
(defn- toast-container
[{:keys [left title text right container-style override-theme]}]
[rn/view {:style (merge style/box-container container-style)}
(def ^:private toast-undo-action (quo.theme/with-theme toast-undo-action-internal))
(defn- toast-container-internal
[{:keys [left title text right container-style theme]}]
[rn/view {:style (merge (style/box-container theme) container-style)}
[blur/view
{:style style/blur-container
:blur-amount 13
@@ -38,7 +45,7 @@
:blur-type :transparent
:overlay-color :transparent}]
[rn/view {:style (style/content-container override-theme)}
[rn/view {:style (style/content-container theme)}
[rn/view {:style style/left-side-container}
left]
[rn/view {:style style/right-side-container}
@@ -46,34 +53,39 @@
[text/text
{:size :paragraph-1
:weight :semi-bold
:style (style/title override-theme)
:style (style/title theme)
:accessibility-label :toast-title}
title])
(when text
[text/text
{:size :paragraph-2
:weight :medium
:style (style/text override-theme)
:style (style/text theme)
:accessibility-label :toast-content}
text])]
right]])
(def ^:private toast-container (quo.theme/with-theme toast-container-internal))
(defn toast
[{:keys [icon icon-color title text action undo-duration undo-on-press container-style
override-theme user]}]
[toast-container
{:left (cond icon
[icon/icon icon
(cond-> (style/icon override-theme)
icon-color
(assoc :color icon-color))]
theme user]}]
(let [context-theme (or theme (quo.theme/get-theme))]
[quo.theme/provider {:theme context-theme}
[toast-container
{:left (cond icon
[icon/icon icon
(cond-> (style/icon context-theme)
icon-color
(assoc :color icon-color))]
user
[user-avatar/user-avatar user])
:title title
:text text
:right (if undo-duration
[toast-undo-action undo-duration undo-on-press override-theme]
action)
:container-style container-style
:override-theme override-theme}])
user
[user-avatar/user-avatar user])
:title title
:text text
:right (if undo-duration
[toast-undo-action
{:undo-duration undo-duration
:undo-on-press undo-on-press}]
action)
:container-style container-style}]]))
@@ -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
@@ -74,9 +73,9 @@
(when show-options-button?
[button/button
{:size 32
:type :blur-bg
:type :grey
:background :blur
:icon true
:override-theme :dark
:style style/option-button
:on-press on-options-press
:accessibility-label :profile-card-options}
@@ -0,0 +1,53 @@
(ns quo2.components.settings.category.component-spec
(:require
[quo2.components.settings.category.view :as category]
[test-helpers.component :as h]))
(h/describe "Settings Category tests"
(h/test "category label renders"
(h/render [category/category
{:list-type :settings
: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
{:list-type :settings
:label "Label"
:data [{:title "Item 1"
:left-icon :i/browser
:chevron? true}]}])
(h/is-truthy (h/get-by-text "Item 1"))))
(h/describe "Reorder Category tests"
(h/test "category label renders"
(h/render [category/category
{:list-type :reorder
:label "Label"
:data [{:title "Item 1"
:right-icon :i/globe
:chevron? true}]}])
(h/is-truthy (h/get-by-text "Label")))
(h/test "category item renders"
(h/render [category/category
{:list-type :reorder
:label "Label"
:data [{:title "Item 1"
:right-icon :i/globe
:chevron? true}]}])
(h/is-truthy (h/get-by-text "Item 1")))
(h/test "category item subtitle renders"
(h/render [category/category
{:list-type :reorder
:label "Label"
:data [{:title "Item 1"
:subtitle "subtitle"
:right-icon :i/globe
:chevron? true}]}])
(h/is-truthy (h/get-by-text "subtitle"))))
@@ -0,0 +1,41 @@
(ns quo2.components.settings.category.reorder.view
(:require
[quo2.components.markdown.text :as text]
[quo2.components.settings.reorder-item.types :as types]
[quo2.components.settings.reorder-item.view :as reorder-item]
[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]
[react-native.draggable-flatlist :as draggable-flatlist]
[reagent.core :as reagent]))
(defn on-drag-end-fn
[data atom-data]
(reset! atom-data data)
(reagent/flush))
(defn- reorder-category-internal
[{:keys [label data blur? theme]}]
(reagent/with-let [atom-data (reagent/atom data)]
[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]
[draggable-flatlist/draggable-flatlist
{:data @atom-data
:key-fn (fn [item index] (str (:title item) index))
:style style/reorder-items
:render-fn (fn [item _ _ _ _ drag] [reorder-item/reorder-item item types/item
{:blur? blur? :drag drag}])
:on-drag-end-fn (fn [_ _ data]
(on-drag-end-fn data atom-data))
:separator [rn/view
{:style (style/reorder-separator blur? theme)}]}]]))
(def reorder-category (quo.theme/with-theme reorder-category-internal))
@@ -0,0 +1,27 @@
(ns quo2.components.settings.category.settings.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/settings-items theme blur?)
:render-fn (fn [item] [settings-list/settings-list item])
:separator [rn/view {:style (style/settings-separator theme blur?)}]}]])
(def settings-category (quo.theme/with-theme category-internal))
@@ -0,0 +1,54 @@
(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 settings-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))})
(def reorder-items
{:margin-top 12})
(defn settings-separator
[theme blur?]
{:height 1
:background-color (if blur?
colors/white-opa-5
(colors/theme-colors colors/neutral-10 colors/neutral-80 theme))})
(defn reorder-separator
[blur? theme]
{:height 4
:background-color (if blur?
:transparent
(colors/theme-colors colors/neutral-5 colors/neutral-95 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,9 @@
(ns quo2.components.settings.category.view
(:require [quo2.components.settings.category.settings.view :as settings]
[quo2.components.settings.category.reorder.view :as reorder]))
(defn category
[{:keys [list-type] :as props}]
(if (= list-type :settings)
[settings/settings-category props]
[reorder/reorder-category props]))
@@ -1,11 +1,14 @@
(ns quo2.components.settings.reorder-item.items.item
(:require [react-native.core :as rn]
[quo2.components.settings.reorder-item.style :as style]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]))
(:require
[quo2.theme :as quo.theme]
[react-native.core :as rn]
[quo2.components.settings.reorder-item.style :as style]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]
[react-native.fast-image :as fast-image]))
(defn view
(defn- view-internal
[{:keys
[title
subtitle
@@ -13,10 +16,14 @@
image-size
right-text
right-icon
on-press]}]
on-press
theme]}
blur?
drag]
[rn/touchable-opacity
{:on-press on-press
:style (merge (style/item-container) (when subtitle style/item-container-extended))}
{:on-press on-press
:on-long-press drag
:style (merge (style/item-container blur?) (when subtitle style/item-container-extended))}
[icon/icon :main-icons/drag
{:color (colors/theme-colors
colors/neutral-50
@@ -25,23 +32,25 @@
{:style style/body-container}
[rn/view
{:style style/image-container}
[rn/image
[fast-image/fast-image
{:source image
:style (style/image image-size)}]]
[rn/view
{:style style/text-container}
[rn/view
[text/text
{:style style/item-text
:weight :medium}
{:weight :medium}
title]
(when subtitle
[text/text
{:style style/item-subtitle
:weight :regular}
{:style style/item-subtitle
:size :paragraph-2}
subtitle])]
(when right-text
[text/text {:style style/right-text} right-text])
(when right-icon
[rn/view {:style style/right-icon-container} [icon/icon right-icon (style/right-icon)]])]]
[icon/icon :tiny-icons/chevron-right (style/chevron)]])
[icon/icon :tiny-icons/chevron-right (style/chevron theme)]])
(def view (quo.theme/with-theme view-internal))
@@ -2,19 +2,21 @@
(:require [quo2.foundations.colors :as colors]))
(defn item-container
[]
[blur?]
{:flex-direction :row
:align-items :center
:padding-horizontal 10
:border-radius 14
:margin-bottom 23
:height 45
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
:border-radius 16
:padding-horizontal 12
:padding-vertical 12
:height 48
:background-color (if blur?
colors/white-opa-5
(colors/theme-colors
colors/white
colors/neutral-90))})
(def item-container-extended
{:height 52})
{:height 56})
(def body-container
{:flex 1
@@ -31,20 +33,17 @@
{:width size
:height size})
(def item-text
{:font-size 14})
(defn chevron
[]
[theme]
{:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)
colors/neutral-40
theme)
:height 14
:width 14})
(def item-subtitle
{:color colors/neutral-50
:font-size 13})
{:color colors/neutral-50})
(def right-text
{:font-size 15
@@ -7,9 +7,9 @@
[quo2.components.settings.reorder-item.types :as types]))
(defn reorder-item
[item type]
[item type {:keys [blur? drag]}]
(case type
types/item [item/view item]
types/item [item/view item blur? drag]
types/placeholder [placeholder/view item]
types/skeleton [skeleton/view]
types/tab [tab/view item]
@@ -42,7 +42,14 @@
(colors/theme-colors colors/neutral-100 colors/white override-theme))
(def community-tag
{:padding-vertical 2})
{:padding-vertical 2
:padding-left 2})
(def community-tag-text-container
{:margin-left 4
:flex 1
:flex-direction :row
:align-items :center})
(defn community-tag-text
[override-theme]
+37 -27
View File
@@ -1,10 +1,10 @@
(ns quo2.components.tags.context-tag.view
(:require [quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.avatars.group-avatar :as group-avatar]
(:require [quo2.components.avatars.group-avatar :as group-avatar]
[quo2.components.avatars.user-avatar.style :as user-avatar-style]
[quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.tags.context-tag.style :as style]
[quo2.components.avatars.user-avatar.style :as user-avatar-style]
[react-native.core :as rn]))
(defn trim-public-key
@@ -40,31 +40,39 @@
(trim-public-key public-key)]])
(defn context-tag
[{:keys [text-style blur? no-avatar-placeholder?] :as params} photo name channel-name]
(let [text-params {:weight :medium
:size :paragraph-2
:style (assoc text-style :justify-content :center)}
[{:keys [text-style blur? no-avatar-placeholder? text-container-style ellipsize-text?]
:as props}
photo
name
channel-name]
(let [text-props {:weight :medium
:size :paragraph-2
:style (assoc text-style :justify-content :center)
:number-of-lines 1
:ellipsize-mode :tail}
empty-photo? (nil? photo)
avatar-size :xxs
avatar-outer-size (get-in user-avatar-style/sizes [avatar-size :outer])]
[rn/view {:flex-direction :row}
[base-tag (assoc-in params [:style :padding-left] 3)
(if (and empty-photo? no-avatar-placeholder?)
[rn/view {:style {:width avatar-outer-size}}]
[user-avatar/user-avatar
{:full-name name
:profile-picture photo
:size avatar-size
:status-indicator? false}])
[rn/view {:style style/context-tag-text-container}
[text/text text-params (str " " name)]
(when channel-name
[:<>
[icons/icon
:i/chevron-right
{:color (style/context-tag-icon-color blur?)
:size 16}]
[text/text text-params (str "# " channel-name)]])]]]))
[base-tag (update-in props [:style :padding-left] #(or % 3))
(if (and empty-photo? no-avatar-placeholder?)
[rn/view {:style {:width avatar-outer-size}}]
[user-avatar/user-avatar
{:full-name name
:profile-picture photo
:size avatar-size
:status-indicator? false}])
[rn/view {:style (or text-container-style style/context-tag-text-container)}
(if ellipsize-text?
[rn/view {:style {:flex 1}}
[text/text text-props name]]
[text/text text-props (str " " name)])
(when channel-name
[:<>
[icons/icon
:i/chevron-right
{:color (style/context-tag-icon-color blur?)
:size 16}]
[text/text text-props (str "# " channel-name)]])]]))
(defn user-avatar-tag
[params username photo]
@@ -88,8 +96,10 @@
(defn community-tag
[avatar community-name {:keys [override-theme] :as params}]
[context-tag
(merge {:style style/community-tag
:text-style (style/community-tag-text override-theme)}
(merge {:style style/community-tag
:text-style (style/community-tag-text override-theme)
:text-container-style style/community-tag-text-container
:ellipsize-text? true}
params)
avatar
community-name])
+6 -5
View File
@@ -105,10 +105,11 @@
:loading? true/false
}"
[_ _]
(fn [{:keys [symbol value size img-src border-color purchasable? sufficient? loading?]
:or
{size :small}}]
(let [sufficient? (when-not loading? sufficient?)
(fn [{:keys [value size img-src border-color purchasable? sufficient? loading?]
:or {size :small}
:as props}]
(let [sym (:symbol props)
sufficient? (when-not loading? sufficient?)
border-color (if sufficient? colors/success-50 border-color)]
[tag
{:size size
@@ -119,4 +120,4 @@
[loading-icon]
(when (or purchasable? sufficient?)
[icon size border-color sufficient?]))}
(str value " " symbol)])))
(str value " " sym)])))
+8
View File
@@ -12,6 +12,7 @@
quo2.components.buttons.dynamic-button
quo2.components.buttons.predictive-keyboard.view
quo2.components.buttons.slide-button.view
quo2.components.browser.browser-input.view
quo2.components.code.snippet
quo2.components.colors.color-picker.view
quo2.components.common.separator.view
@@ -62,6 +63,7 @@
quo2.components.navigation.floating-shell-button
quo2.components.navigation.page-nav
quo2.components.notifications.activity-log.view
quo2.components.notifications.activity-logs-photos.view
quo2.components.notifications.count-down-circle
quo2.components.notifications.info-count
quo2.components.notifications.notification-dot
@@ -82,6 +84,7 @@
quo2.components.settings.privacy-option
quo2.components.settings.reorder-item.view
quo2.components.settings.settings-list.view
quo2.components.settings.category.view
quo2.components.share.qr-code.view
quo2.components.share.share-qr-code.view
quo2.components.tabs.account-selector
@@ -137,6 +140,9 @@
(def predictive-keyboard quo2.components.buttons.predictive-keyboard.view/view)
(def slide-button quo2.components.buttons.slide-button.view/view)
;;;; BROWSER
(def browser-input quo2.components.browser.browser-input.view/browser-input)
;;;; CODE
(def snippet quo2.components.code.snippet/snippet)
@@ -209,6 +215,7 @@
;;;; NOTIFICATIONS
(def activity-log quo2.components.notifications.activity-log.view/view)
(def activity-logs-photos quo2.components.notifications.activity-logs-photos.view/view)
(def info-count quo2.components.notifications.info-count/info-count)
(def notification-dot quo2.components.notifications.notification-dot/notification-dot)
(def count-down-circle quo2.components.notifications.count-down-circle/circle-timer)
@@ -231,6 +238,7 @@
(def account quo2.components.settings.accounts.view/account)
(def settings-list quo2.components.settings.settings-list.view/settings-list)
(def reorder-item quo2.components.settings.reorder-item.view/reorder-item)
(def category quo2.components.settings.category.view/category)
;;;; SHARE
(def qr-code quo2.components.share.qr-code.view/qr-code)
+2
View File
@@ -5,6 +5,7 @@
[quo2.components.buttons.button.component-spec]
[quo2.components.buttons.predictive-keyboard.component-spec]
[quo2.components.buttons.slide-button.component-spec]
[quo2.components.browser.browser-input.component-spec]
[quo2.components.colors.color-picker.component-spec]
[quo2.components.counter.--tests--.counter-component-spec]
[quo2.components.counter.step.component-spec]
@@ -37,5 +38,6 @@
[quo2.components.selectors.selectors.component-spec]
[quo2.components.settings.reorder-item.component-spec]
[quo2.components.settings.settings-list.component-spec]
[quo2.components.settings.category.component-spec]
[quo2.components.share.share-qr-code.component-spec]
[quo2.components.tags.--tests--.status-tags-component-spec]))
+16 -7
View File
@@ -136,6 +136,8 @@
;;Solid
(def black "#000000")
(def black-opa-0 (alpha black 0))
(def black-opa-30 (alpha black 0.3))
(def black-opa-60 (alpha black 0.6))
(def onboarding-header-black "#000716")
;;;;Primary
@@ -180,6 +182,8 @@
(def danger-50 "#E95460")
(def danger-60 "#BA434D")
(def system-yellow "#FFD60A")
;;50 with transparency
(def danger-50-opa-5 (alpha danger-50 0.05))
(def danger-50-opa-10 (alpha danger-50 0.1))
@@ -244,11 +248,13 @@
([color suffix]
(custom-color color suffix nil))
([color suffix opacity]
(let [color-keyword (keyword color)
(let [hex? (not (keyword? color))
color-keyword (keyword color)
base-color (get-in colors-map
[color-keyword suffix]
color)]
(if opacity (alpha base-color (/ opacity 100)) base-color))))))
[color-keyword suffix])]
(if hex?
color
(if opacity (alpha base-color (/ opacity 100)) base-color)))))))
(defn custom-color-by-theme
"(custom-color-by-theme color suffix-light suffix-dark opacity-light opacity-dark)
@@ -256,11 +262,14 @@
suffix-light 50/60
suffix-dark 50/60
opacity-light 0-100 (optional)
opacity-dark 0-100 (optional)"
opacity-dark 0-100 (optional)
theme :light/:dark (optional)"
([color suffix-light suffix-dark]
(custom-color-by-theme color suffix-light suffix-dark nil nil))
(custom-color-by-theme color suffix-light suffix-dark nil nil (theme/get-theme)))
([color suffix-light suffix-dark opacity-light opacity-dark]
(if (theme/dark?)
(custom-color-by-theme color suffix-light suffix-dark opacity-light opacity-dark (theme/get-theme)))
([color suffix-light suffix-dark opacity-light opacity-dark theme]
(if (= theme :dark)
(custom-color color suffix-dark opacity-dark)
(custom-color color suffix-light opacity-light))))
@@ -0,0 +1,20 @@
(ns quo2.foundations.customization-colors
(:require [quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(defn get-overlay-color
[theme pressed? customization-color]
(let [community-color (string? customization-color)]
(if (or community-color (= theme :light))
(colors/alpha colors/black (if pressed? 0.2 0))
(colors/alpha colors/black (if pressed? 0 0.2)))))
(defn overlay
[{:keys [theme pressed? customization-color]}]
[rn/view
{:position :absolute
:top 0
:left 0
:right 0
:bottom 0
:background-color (get-overlay-color theme pressed? customization-color)}])
+9 -1
View File
@@ -1,8 +1,16 @@
(ns react-native.camera-kit
(:require ["react-native-camera-kit" :refer (Camera CameraType)]
[reagent.core :as reagent]))
[reagent.core :as reagent]
[oops.core :as oops]
[taoensso.timbre :as log]))
(def camera (reagent/adapt-react-class Camera))
(def camera-type-front (.-Front CameraType))
(def camera-type-back (.-Back CameraType))
(defn capture
[^js camera-ref on-success]
(-> (.capture camera-ref)
(.then #(on-success (oops/oget % :uri)))
(.catch #(log/warn "couldn't capture photo" {:error %}))))
+11
View File
@@ -0,0 +1,11 @@
(ns react-native.draggable-flatlist
(:require
[react-native.flat-list :as rn-flat-list]
[reagent.core :as reagent]
["react-native-draggable-flatlist" :default DraggableFlatList]))
(def rn-draggable-flatlist (reagent/adapt-react-class DraggableFlatList))
(defn draggable-flatlist
[props]
[rn-draggable-flatlist (rn-flat-list/base-list-props props)])
+21 -21
View File
@@ -91,9 +91,9 @@
(.-value anim)))
(defn set-shared-value
[anim val]
(when (and anim (some? val))
(set! (.-value anim) val)))
[anim v]
(when (and anim (some? v))
(set! (.-value anim) v)))
(defn interpolate
([shared-value input-range output-range]
@@ -112,47 +112,47 @@
;; Animators
(defn animate-shared-value-with-timing
[anim val duration easing]
[anim v duration easing]
(set-shared-value anim
(with-timing val
(with-timing v
(js-obj "duration" duration
"easing" (get easings easing)))))
(defn animate-shared-value-with-delay
[anim val duration easing delay]
[anim v duration easing delay]
(set-shared-value anim
(with-delay delay
(with-timing val
(with-timing v
(js-obj "duration" duration
"easing" (get easings easing))))))
(defn animate-delay
([animation val delay]
(animate-delay animation val delay default-duration))
([animation val delay duration]
([animation v delay]
(animate-delay animation v delay default-duration))
([animation v delay duration]
(set-shared-value animation
(with-delay delay
(with-timing val
(with-timing v
(clj->js {:duration duration
:easing (default-easing)}))))))
(defn animate-shared-value-with-repeat
[anim val duration easing number-of-repetitions reverse?]
[anim v duration easing number-of-repetitions reverse?]
(set-shared-value anim
(with-repeat (with-timing val
(with-repeat (with-timing v
(js-obj "duration" duration
"easing" (get easings easing)))
number-of-repetitions
reverse?)))
(defn animate-shared-value-with-delay-repeat
([anim val duration easing delay number-of-repetitions]
(animate-shared-value-with-delay-repeat anim val duration easing delay number-of-repetitions false))
([anim val duration easing delay number-of-repetitions reverse?]
([anim v duration easing delay number-of-repetitions]
(animate-shared-value-with-delay-repeat anim v duration easing delay number-of-repetitions false))
([anim v duration easing delay number-of-repetitions reverse?]
(set-shared-value anim
(with-delay delay
(with-repeat
(with-timing val
(with-timing v
#js
{:duration duration
:easing (get easings easing)})
@@ -160,9 +160,9 @@
reverse?)))))
(defn animate-shared-value-with-spring
[anim val {:keys [mass stiffness damping]}]
[anim v {:keys [mass stiffness damping]}]
(set-shared-value anim
(with-spring val
(with-spring v
(js-obj "mass" mass
"damping" damping
"stiffness" stiffness))))
@@ -183,7 +183,7 @@
:easing (default-easing)})))))
(defn with-timing-duration
[val duration]
(with-timing val
[v duration]
(with-timing v
(clj->js {:duration duration
:easing (in-out (.-quad ^js Easing))})))
+3 -3
View File
@@ -4,8 +4,8 @@
[react-native.share :as share]
[react-native.cameraroll :as cameraroll]
[status-im.ui.components.react :as react]
[status-im2.config :as config]
[react-native.fs :as fs]
[status-im2.constants :as constants]
[utils.re-frame :as rf]
[status-im.utils.platform :as platform]
[taoensso.timbre :as log]))
@@ -48,7 +48,7 @@
[{:keys [db]} chat-id uri]
(let [current-chat-id (or chat-id (:current-chat-id db))
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
(when (and (< (count images) config/max-images-batch)
(when (and (< (count images) constants/max-album-photos)
(not (get images uri)))
{::image-selected [uri current-chat-id]})))
@@ -68,5 +68,5 @@
[{:keys [db]} chat-id]
(let [current-chat-id (or chat-id (:current-chat-id db))
images (get-in db [:chat/inputs current-chat-id :metadata :sending-image])]
(when (< (count images) config/max-images-batch)
(when (< (count images) constants/max-album-photos)
{::chat-open-image-picker-camera current-chat-id})))
+3 -2
View File
@@ -40,10 +40,10 @@
; referenced function: contact-list-item
(defn- rename-mentionable-users
[mentionable-users]
(reduce (fn [acc [id val]]
(reduce (fn [acc [id v]]
(assoc acc
id
(set/rename-keys val
(set/rename-keys v
{:id :public-key
:primaryName :primary-name
:secondaryName :secondary-name
@@ -55,6 +55,7 @@
{}
mentionable-users))
(defn- transfer-mention-result
[result]
(let [{:keys [input-segments mentionable-users state chat-id new-text]}
+61 -2
View File
@@ -3,6 +3,7 @@
[clojure.string :as string]
[clojure.walk :as walk]
[quo.design-system.colors :as colors]
[quo2.foundations.colors :as quo2.colors]
[re-frame.core :as re-frame]
[status-im.utils.types :as types]
[status-im.async-storage.core :as async-storage]
@@ -16,6 +17,7 @@
[taoensso.timbre :as log]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[status-im2.common.muting.helpers :refer [format-mute-till]]
[status-im2.contexts.chat.events :as chat.events]))
(def crop-size 1000)
@@ -72,7 +74,8 @@
:isMember :is-member?
:adminSettings :admin-settings
:tokenPermissions :token-permissions
:communityTokensMetadata :tokens-metadata})
:communityTokensMetadata :tokens-metadata
:muteTill :muted-till})
(update :admin-settings
set/rename-keys
{:pinMessageAllMembersEnabled :pin-message-all-members-enabled?})
@@ -80,7 +83,8 @@
(update :chats <-chats-rpc)
(update :categories <-categories-rpc)
(assoc :token-images
(reduce (fn [acc {:keys [symbol image]}] (assoc acc symbol image))
(reduce (fn [acc {sym :symbol image :image}]
(assoc acc sym image))
{}
(:communityTokensMetadata c)))))
@@ -938,3 +942,58 @@
{:error %
:event
:communities/check-and-delete-pending-request-to-join-community})}]})
(rf/defn mute-community-chats
{:events [:community/mute-community-chats]}
[{:keys [db]} chat-id muted? muted-till]
(log/debug "muted community chat successfully" chat-id muted?)
{:db (update-in db [:chats chat-id] merge {:muted muted? :muted-till muted-till})})
(rf/defn mute-and-unmute-community-chats
{:events [:community/update-community-chats-mute-status]}
[{:keys [db]} community-id muted? mute-till]
(let [channels (get-in db [:communities community-id :chats])
chats (mapv vector (keys channels) (vals channels))]
(doseq [x chats]
(doseq [{:keys [id]} x]
(let [chat-id (str community-id id)]
(rf/dispatch [:community/mute-community-chats chat-id muted? mute-till]))))))
(rf/defn mute-chat-failed
{:events [:community/mute-community-failed]}
[{:keys [db]} community-id muted? error]
(log/error "mute community failed" community-id error)
{:db (update-in db [:communities community-id :muted] (not muted?))}
(rf/dispatch [:community/update-community-chats-mute-status community-id muted? error]))
(rf/defn mute-community-successfully
{:events [:community/mute-community-successful]}
[{:keys [db]} community-id muted? muted-till]
(log/debug "muted community successfully" community-id muted-till)
(rf/dispatch [:community/update-community-chats-mute-status community-id muted? muted-till])
(let [time-string (fn [mute-title mute-duration]
(i18n/label mute-title {:duration mute-duration}))]
{:db (assoc-in db [:communities community-id :muted-till] muted-till)
:dispatch [:toasts/upsert
{:icon :correct
:icon-color (quo2.colors/theme-colors
quo2.colors/success-60
quo2.colors/success-50)
:text (if muted?
(when (some? muted-till)
(time-string :t/muted-until (format-mute-till muted-till)))
(i18n/label :t/community-unmuted))}]}))
(rf/defn set-community-muted
{:events [:community/set-muted]}
[{:keys [db]} community-id muted? muted-type]
(let [params (if muted? [{:communityId community-id :mutedType muted-type}] [community-id])
method (if muted? "wakuext_muteCommunityChats" "wakuext_unMuteCommunityChats")]
{:db (assoc-in db [:communities community-id :muted] muted?)
:json-rpc/call [{:method method
:params params
:on-error #(rf/dispatch [:community/mute-community-failed community-id
muted? %])
:on-success #(rf/dispatch [:community/mute-community-successful
community-id muted? %])}]}))
+2 -2
View File
@@ -143,8 +143,8 @@
(defn generate-erc20-uri
"Generate a EIP 681 URI encapsulating ERC20 token transfer"
[address {:keys [symbol value] :as m} all-tokens]
(when-let [token (tokens/symbol->token all-tokens symbol)]
[address {sym :symbol value :value :as m} all-tokens]
(when-let [token (tokens/symbol->token all-tokens sym)]
(generate-uri (:address token)
(merge (dissoc m :value :symbol)
{:function-name "transfer"
+12 -7
View File
@@ -190,18 +190,23 @@
(is (.equals (money/bignumber "111122223333441239") (eip681/parse-eth-value "111122223333441239"))))
(deftest extract-request-details
(let [{:keys [value symbol address]} (eip681/extract-request-details
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
:value "1ETH"}
{})]
(let [{value :value
sym :symbol
address :address}
(eip681/extract-request-details
{:address "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7"
:value "1ETH"}
{})]
(is (.equals (money/ether->wei (money/bignumber 1)) value))
(is (= :ETH symbol))
(is (= :ETH sym))
(is (= "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" address)))
(is (= (eip681/extract-request-details
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e" :chain-id 1 :function-name "unknown"}
{})
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e" :chain-id 1 :function-name "unknown"}))
(let [{:keys [value symbol address]}
(let [{value :value
sym :symbol
address :address}
(eip681/extract-request-details
{:address "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
:chain-id 1
@@ -213,5 +218,5 @@
:symbol :SNT
:decimals 18}})]
(is (.equals (money/bignumber 1000) value))
(is (= :SNT symbol))
(is (= :SNT sym))
(is (= "0x89205a3a3b2a69de6dbf7f01ed13b2108b2c43e7" address))))
+12 -12
View File
@@ -5,10 +5,10 @@
(def default-native-currency
(memoize
(fn [symbol]
(fn [sym]
{:name "Native"
:symbol :ETH
:symbol-display symbol
:symbol-display sym
:decimals 18
:icon {:source (js/require "../resources/images/tokens/default-token.png")}})))
@@ -41,13 +41,13 @@
(set (map #(-> % val :symbol) all-native-currencies)))
(defn native-currency
[{:keys [symbol] :as current-network}]
[{sym :symbol :as current-network}]
(let [chain (ethereum/network->chain-keyword current-network)]
(get all-native-currencies chain (default-native-currency symbol))))
(get all-native-currencies chain (default-native-currency sym))))
(defn ethereum?
[symbol]
(native-currency-symbols symbol))
[sym]
(native-currency-symbols sym))
(def token-icons
{:mainnet (resolve-icons :mainnet)
@@ -74,17 +74,17 @@
(string/lower-case (:name %2))))))
(defn symbol->token
[all-tokens symbol]
(some #(when (= symbol (:symbol %)) %) (vals all-tokens)))
[all-tokens sym]
(some #(when (= sym (:symbol %)) %) (vals all-tokens)))
(defn address->token
[all-tokens address]
(get all-tokens (string/lower-case address)))
(defn asset-for
[all-tokens current-network symbol]
[all-tokens current-network sym]
(let [native-coin (native-currency current-network)]
(if (or (= (:symbol-display native-coin) symbol)
(= (:symbol native-coin) symbol))
(if (or (= (:symbol-display native-coin) sym)
(= (:symbol native-coin) sym))
native-coin
(symbol->token all-tokens symbol))))
(symbol->token all-tokens sym))))
@@ -52,10 +52,8 @@
(defn- parse-token-transfer
[chain-tokens contract]
(let [{:keys [symbol] :as token} (get chain-tokens
contract
default-erc20-token)]
{:symbol symbol
(let [token (get chain-tokens contract default-erc20-token)]
{:symbol (:symbol token)
:token token
;; NOTE(goranjovic) - just a flag we need when we merge this entry
;; with the existing entry in the app, e.g. transaction info with
@@ -387,11 +385,10 @@
:addresses [address]
:before-block min-known-block
:fetch-more? (utils.mobile-sync/syncing-allowed? cofx)
;; Transfers are requested before and including `min-known-block` because
;; there is no guarantee that all transfers from that block are shown
;; already. To make sure that we fetch the whole `default-transfers-limit`
;; of transfers the number of transfers already received for
;; `min-known-block` is added to the page size.
;; Transfers are requested before and including `min-known-block` because there is no
;; guarantee that all transfers from that block are shown already. To make sure that we fetch
;; the whole `default-transfers-limit` of transfers the number of transfers already received
;; for `min-known-block` is added to the page size.
:limit-per-address {address (+ default-transfers-limit
min-block-transfers-count)}}}
(tx-fetching-in-progress [address]))))
+1 -1
View File
@@ -307,7 +307,7 @@
(defn login
[args]
(native-module/login-with-keycard args))
(native-module/login-with-keycard (assoc args :node-config {:ProcessBackedupMessages false})))
(defn send-transaction-with-signature
[{:keys [transaction signature on-completed]}]
+3 -2
View File
@@ -75,7 +75,7 @@
(assoc :recovered-account? true))
:keycard/check-nfc-enabled nil}
(bottom-sheet/hide-bottom-sheet-old)
(navigation/navigate-to :keycard-recovery-intro nil)))
(navigation/navigate-to-within-stack [:keycard-recovery-intro :new-to-status])))
(rf/defn access-key-pressed
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
@@ -253,7 +253,8 @@
encryption-pass
#(let [{:keys [error]} (types/json->clj %)]
(if (string/blank? error)
(native-module/login-with-keycard login-params)
(native-module/login-with-keycard
(assoc login-params :node-config {:ProcessBackedupMessages true}))
(throw
(js/Error.
"Please shake the phone to report this error and restart the app. Migration failed unexpectedly.")))))))
+10 -9
View File
@@ -34,17 +34,18 @@
(or display-name primary-name alias (gfycat/generate-gfy public-key)))))
(defn contact-by-identity
[contacts identity]
(or (get contacts identity)
(contact.db/public-key->new-contact identity)))
[contacts contact-identity]
(or (get contacts contact-identity)
(contact.db/public-key->new-contact contact-identity)))
(defn contact-two-names-by-identity
[contact current-multiaccount identity]
(let [me? (= (:public-key current-multiaccount) identity)]
[contact profile contact-identity]
(let [me? (= (:public-key profile) contact-identity)]
(if me?
[(or (:preferred-name current-multiaccount)
[(or (:preferred-name profile)
(:display-name profile)
(:primary-name contact)
(gfycat/generate-gfy identity))]
(gfycat/generate-gfy contact-identity))]
[(:primary-name contact) (:secondary-name contact)])))
(defn displayed-photo
@@ -211,8 +212,8 @@
(rf/merge cofx
{:json-rpc/call [{:method "multiaccounts_deleteIdentityImage"
:params [key-uid]
;; NOTE: In case of an error we could fallback to previous image in UI
;; with a toast error
;; NOTE: In case of an error we could fallback to previous image in
;; UI with a toast error
:on-success #(log/info "[multiaccount] Delete profile image" %)}]}
(multiaccounts.update/optimistic :images nil)
(bottom-sheet/hide-bottom-sheet-old))))
+2 -2
View File
@@ -158,7 +158,7 @@
:on-success #(re-frame/dispatch [:navigate-back])}]}))
(defn new-network
[random-id network-name symbol upstream-url chain-type chain-id]
[random-id network-name sym upstream-url chain-type chain-id]
(let [data-dir (str "/ethereum/" (name chain-type) "_rpc")
config {:NetworkId (or (when chain-id (int chain-id))
(ethereum/chain-keyword->chain-id chain-type))
@@ -167,7 +167,7 @@
:URL upstream-url}}]
{:id random-id
:name network-name
:symbol symbol
:symbol sym
:config config}))
(rf/defn save
+2 -2
View File
@@ -181,7 +181,7 @@
(defn get-transfer-token
[db to data]
(let [{:keys [symbol decimals] :as token} (tokens/address->token (:wallet/all-tokens db) to)]
(let [{:keys [decimals] :as token} (tokens/address->token (:wallet/all-tokens db) to)]
(when (and token data (string? data))
(when-let [type (get-method-type data)]
(let [[address value _] (native-module/decode-parameters
@@ -197,7 +197,7 @@
:value value
:amount (money/to-fixed (money/token->unit value decimals))
:token token
:symbol symbol}))))))
:symbol (:symbol token)}))))))
(defn parse-tx-obj
[db {:keys [from to value data cancel? hash]}]
@@ -140,11 +140,11 @@
nil)))})))
(views/defview animated-bottom-panel
[val view on-close on-touch-outside show-overlay?]
[m view on-close on-touch-outside show-overlay?]
(views/letsubs [{window-height :height} [:dimensions/window]]
[bottom-panel
(when val
(select-keys val
(when m
(select-keys m
[:from :contact :amount :token :approve? :message :cancel? :hash :name :url :icons
:wc-version :params :connector :description :topic :relay :self :peer :permissions
:state])) view window-height on-close on-touch-outside
+4 -2
View File
@@ -298,8 +298,10 @@
(i18n/label :t/save)]]]))
(defn gwei
[val]
(str (money/to-fixed val 2) " " (i18n/label :t/gwei)))
[amount]
(str (money/to-fixed amount 2)
" "
(i18n/label :t/gwei)))
(defn fees-warning
[]
@@ -23,102 +23,104 @@
(defview add-custom-token
[]
(letsubs [{:keys [contract name symbol decimals in-progress? error error-name error-symbol]}
(letsubs [{:keys [contract name decimals in-progress? error error-name error-symbol]
:as m}
[:wallet/custom-token-screen]]
[react/keyboard-avoiding-view {:flex 1 :background-color colors/white}
[react/scroll-view
{:keyboard-should-persist-taps :handled
:style {:flex 1
:padding-horizontal 16}}
[react/view {:padding-vertical 8}
[react/view
{:style {:flex-direction :row
:justify-content :space-between
:padding-vertical 10}}
[react/text (i18n/label :t/contract-address)]
(when in-progress?
[react/view {:flex-direction :row :justify-content :center}
[react/view {:height 20}
[react/activity-indicator {:width 24 :height 24 :animating true}]]
[react/text {:style {:color colors/gray :margin-left 5}}
(i18n/label :t/processing)]])]
(when-not in-progress?
;;tooltip covers button
[react/view {:position :absolute :z-index 1000 :right 0 :top 10}
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:wallet.custom-token.ui/contract-address-paste])}
[react/text {:style {:color colors/blue}}
(i18n/label :t/paste)]]])
[quo/text-input
{:on-change-text #(debounce-and-save :contract %)
:error error
:default-value contract
:monospace true
:multiline true
:height 78
:auto-focus false
:placeholder (i18n/label :t/specify-address)}]]
[react/view {:padding-vertical 8}
[quo/text-input
{:on-change-text #(debounce-and-save :name %)
:label (i18n/label :t/name)
:default-value name
:error error-name
:auto-focus false
:placeholder (i18n/label :t/name-of-token)}]]
[react/view {:padding-vertical 8}
[react/view {:style {:flex-direction :row}}
[react/view
{:flex 1
:padding-right 8}
(let [sym (:symbol m)]
[react/keyboard-avoiding-view {:flex 1 :background-color colors/white}
[react/scroll-view
{:keyboard-should-persist-taps :handled
:style {:flex 1
:padding-horizontal 16}}
[react/view {:padding-vertical 8}
[react/view
{:style {:flex-direction :row
:justify-content :space-between
:padding-vertical 10}}
[react/text (i18n/label :t/contract-address)]
(when in-progress?
[react/view {:flex-direction :row :justify-content :center}
[react/view {:height 20}
[react/activity-indicator {:width 24 :height 24 :animating true}]]
[react/text {:style {:color colors/gray :margin-left 5}}
(i18n/label :t/processing)]])]
(when-not in-progress?
;;tooltip covers button
[react/view {:position :absolute :z-index 1000 :right 0 :top 10}
[react/touchable-highlight
{:on-press #(re-frame/dispatch [:wallet.custom-token.ui/contract-address-paste])}
[react/text {:style {:color colors/blue}}
(i18n/label :t/paste)]]])
[quo/text-input
{:on-change-text #(debounce-and-save :symbol %)
:label (i18n/label :t/symbol)
:error error-symbol
:default-value symbol
{:on-change-text #(debounce-and-save :contract %)
:error error
:default-value contract
:monospace true
:multiline true
:height 78
:auto-focus false
:show-cancel false
:placeholder "ABC"}]]
[react/view
{:flex 1
:padding-left 8}
:placeholder (i18n/label :t/specify-address)}]]
[react/view {:padding-vertical 8}
[quo/text-input
{:label (i18n/label :t/decimals)
:on-change-text #(debounce-and-save :decimals %)
:default-value decimals
:keyboard-type :number-pad
:max-length 2
{:on-change-text #(debounce-and-save :name %)
:label (i18n/label :t/name)
:default-value name
:error error-name
:auto-focus false
:show-cancel false
:placeholder "18"}]]]]
#_[quo/text-input
{:label (i18n/label :t/balance)
:default-value (when (and balance decimals)
(wallet.utils/format-amount balance decimals))
:editable false
:placeholder (i18n/label :t/no-tokens-found)}]]
:placeholder (i18n/label :t/name-of-token)}]]
[react/view {:padding-vertical 8}
[react/view {:style {:flex-direction :row}}
[react/view
{:flex 1
:padding-right 8}
[quo/text-input
{:on-change-text #(debounce-and-save :symbol %)
:label (i18n/label :t/symbol)
:error error-symbol
:default-value sym
:auto-focus false
:show-cancel false
:placeholder "ABC"}]]
[react/view
{:flex 1
:padding-left 8}
[quo/text-input
{:label (i18n/label :t/decimals)
:on-change-text #(debounce-and-save :decimals %)
:default-value decimals
:keyboard-type :number-pad
:max-length 2
:auto-focus false
:show-cancel false
:placeholder "18"}]]]]
#_[quo/text-input
{:label (i18n/label :t/balance)
:default-value (when (and balance decimals)
(wallet.utils/format-amount balance decimals))
:editable false
:placeholder (i18n/label :t/no-tokens-found)}]]
[toolbar/toolbar
{:show-border? true
:right
[quo/button
{:type :secondary
:after :main-icon/next
:disabled (boolean
(or in-progress?
error
error-name
error-symbol
(string/blank? contract)
(string/blank? name)
(string/blank? symbol)
(string/blank? decimals)))
:on-press #(re-frame/dispatch [:wallet.custom-token.ui/add-pressed])}
(i18n/label :t/add)]}]]))
[toolbar/toolbar
{:show-border? true
:right
[quo/button
{:type :secondary
:after :main-icon/next
:disabled (boolean
(or in-progress?
error
error-name
error-symbol
(string/blank? contract)
(string/blank? name)
(string/blank? sym)
(string/blank? decimals)))
:on-press #(re-frame/dispatch [:wallet.custom-token.ui/add-pressed])}
(i18n/label :t/add)]}]])))
(defview custom-token-details
[]
(letsubs [{:keys [address name symbol decimals custom?] :as token}
(letsubs [{:keys [address name decimals custom?] :as token}
[:get-screen-params]]
[react/keyboard-avoiding-view
{:style {:flex 1}
@@ -149,7 +151,7 @@
{:label (i18n/label :t/symbol)
:editable false
:show-cancel false
:default-value symbol}]]
:default-value (:symbol token)}]]
[react/view {:flex 1 :padding-left 8}
[quo/text-input
{:label (i18n/label :t/decimals)
@@ -112,8 +112,8 @@
[react/text {:style {:color colors/blue}} (i18n/label :t/set-max)]]])
(defn fiat-value
[amount {:keys [symbol]} prices wallet-currency]
(when-let [price (get-in prices [(keyword symbol) (keyword (:code wallet-currency)) :price])]
[amount {sym :symbol} prices wallet-currency]
(when-let [price (get-in prices [(keyword sym) (keyword (:code wallet-currency)) :price])]
(let [norm-amount (js/parseFloat (money/normalize amount))
amount (if (js/isNaN norm-amount) 0 norm-amount)]
[react/text
@@ -51,7 +51,12 @@
(fn [_ [_ old-token] [_ new-token]]
(not= (:checked? old-token) (:checked? new-token)))
:reagent-render
(fn [{:keys [symbol name icon color checked?] :as token}]
(fn [{sym :symbol
title :name
icon :icon
color :color
checked? :checked?
:as token}]
[quo/list-item
{:active checked?
:accessory :checkbox
@@ -59,14 +64,13 @@
:animated false
:icon (if icon
[wallet.components/token-icon icon]
[chat-icon/custom-icon-view-list name color])
:title name
:subtitle (clojure.core/name symbol)
:on-press #(re-frame/dispatch
[:wallet.settings/toggle-visible-token (keyword symbol) (not checked?)])
:on-long-press #(re-frame/dispatch
[:bottom-sheet/show-sheet-old
{:content (custom-token-actions-view token)}])}])}))
[chat-icon/custom-icon-view-list title color])
:title title
:subtitle (name sym)
:on-press #(re-frame/dispatch [:wallet.settings/toggle-visible-token (keyword sym)
(not checked?)])
:on-long-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
{:content (custom-token-actions-view token)}])}])}))
(defn- render-token-wrapper
[token]
+2 -2
View File
@@ -132,9 +132,9 @@
(catch :default _ nil)))
(defn url?
[str]
[s]
(try
(when-let [host (.getDomain ^js (goog.Uri. str))]
(when-let [host (.getDomain ^js (goog.Uri. s))]
(not (string/blank? host)))
(catch :default _ nil)))
+10 -8
View File
@@ -191,12 +191,14 @@
(PersistentPriorityMap. (sorted-map) {} {} identity nil))
(defn- pm-empty-by
[comparator]
(PersistentPriorityMap. (sorted-map-by comparator) {} {} identity nil))
[f-comparator]
(PersistentPriorityMap. (sorted-map-by f-comparator) {} {} identity nil))
(defn- pm-empty-keyfn
([keyfn] (PersistentPriorityMap. (sorted-map) {} {} keyfn nil))
([keyfn comparator] (PersistentPriorityMap. (sorted-map-by comparator) {} {} keyfn nil)))
([keyfn]
(PersistentPriorityMap. (sorted-map) {} {} keyfn nil))
([keyfn f-comparator]
(PersistentPriorityMap. (sorted-map-by f-comparator) {} {} keyfn nil)))
(defn- read-priority-map
[elems]
@@ -221,9 +223,9 @@
"keyval => key val
Returns a new priority map with supplied
mappings, using the supplied comparator."
([comparator & keyvals]
([f-comparator & keyvals]
(loop [in (seq keyvals)
out (pm-empty-by comparator)]
out (pm-empty-by f-comparator)]
(if in
(recur (nnext in) (assoc out (first in) (second in)))
out))))
@@ -243,9 +245,9 @@
"keyval => key val
Returns a new priority map with supplied
mappings, using the supplied keyfn and comparator."
([keyfn comparator & keyvals]
([keyfn f-comparator & keyvals]
(loop [in (seq keyvals)
out (pm-empty-keyfn keyfn comparator)]
out (pm-empty-keyfn keyfn f-comparator)]
(if in
(recur (nnext in) (assoc out (first in) (second in)))
out))))
+1 -1
View File
@@ -120,7 +120,7 @@
(fn [address] (.checkAddressChecksum native-status address))
:sha3
(fn [str] (.sha3 native-status str))
(fn [s] (.sha3 native-status s))
:toChecksumAddress
(fn [address] (.toChecksumAddress native-status address))
+16 -10
View File
@@ -53,8 +53,14 @@
(defn- fill-prepare-transaction-details
[db
{:keys [address name value symbol gas gasPrice gasLimit]
:or {symbol :ETH}}
{address :address
name :name
value :value
sym :symbol
gas :gas
gas-price :gasPrice
gas-limit :gasLimit
:or {sym :ETH}}
all-tokens]
(assoc db
:wallet/prepare-transaction
@@ -62,14 +68,14 @@
:to-name (or name (find-address-name db address))
:from (ethereum/get-default-account
(get db :profile/wallet-accounts))}
gas (assoc :gas (money/bignumber gas))
gasLimit (assoc :gas (money/bignumber gasLimit))
gasPrice (assoc :gasPrice (money/bignumber gasPrice))
value (assoc :amount-text
(if (= :ETH symbol)
(str (money/internal->formatted value symbol (get all-tokens symbol)))
(str value)))
symbol (assoc :symbol symbol))))
gas (assoc :gas (money/bignumber gas))
gas-limit (assoc :gas (money/bignumber gas-limit))
gas-price (assoc :gasPrice (money/bignumber gas-price))
value (assoc :amount-text
(if (= :ETH sym)
(str (money/internal->formatted value sym (get all-tokens sym)))
(str value)))
sym (assoc :symbol sym))))
(rf/defn request-uri-parsed
{:events [:wallet/request-uri-parsed]}
+4 -4
View File
@@ -987,15 +987,15 @@
{::get-pending-transactions nil})
(defn normalize-transaction
[db {:keys [symbol gasPrice gasLimit value from to] :as transaction}]
(let [symbol (keyword symbol)
token (tokens/symbol->token (:wallet/all-tokens db) symbol)]
[db {:keys [gasPrice gasLimit value from to] :as transaction}]
(let [sym (-> transaction :symbol keyword)
token (tokens/symbol->token (:wallet/all-tokens db) sym)]
(-> transaction
(select-keys [:timestamp :hash :data])
(assoc :from (eip55/address->checksum from)
:to (eip55/address->checksum to)
:type :pending
:symbol symbol
:symbol sym
:token token
:value (money/bignumber value)
:gas-price (money/bignumber gasPrice)
+7 -5
View File
@@ -12,13 +12,15 @@
;; some sidechains have different names for this native currency, which we handle with `symbol-display`
;; override.
(defn display-symbol
[{:keys [symbol-display symbol]}]
(when-let [name (or symbol-display symbol)]
(clojure.core/name name)))
[m]
(when-let [some-symbol (or (:symbol-display m) (:symbol m))]
(name some-symbol)))
;;NOTE(goranjovic) - in addition to custom symbol display, some sidechain native currencies are listed
;;under a different
;; ticker on exchange networks. We handle that with `symbol-exchange` override.
(defn exchange-symbol
[{:keys [symbol-exchange symbol-display symbol]}]
(clojure.core/name (or symbol-exchange symbol-display symbol)))
[m]
(name (or (:symbol-exchange m)
(:symbol-display m)
(:symbol m))))
@@ -4,17 +4,17 @@
[status-im.utils.platform :as platform]))
(defn handle
[override-theme]
[theme]
{:width 32
:height 4
:background-color (colors/theme-colors colors/neutral-100 colors/white override-theme)
:opacity (theme/theme-value 0.05 0.1)
:background-color (colors/theme-colors colors/neutral-100 colors/white theme)
:opacity (theme/theme-value 0.05 0.1 theme)
:border-radius 100
:align-self :center
:margin-vertical 8})
(defn sheet
[{:keys [top bottom]} window-height override-theme padding-bottom-override shell?]
[{:keys [top bottom]} window-height theme padding-bottom-override shell?]
{:position :absolute
:max-height (- window-height top)
:z-index 1
@@ -28,7 +28,7 @@
:padding-bottom (or padding-bottom-override (+ bottom 8))
:background-color (if shell?
:transparent
(colors/theme-colors colors/white colors/neutral-90 override-theme))})
(colors/theme-colors colors/white colors/neutral-95 theme))})
(def shell-bg
{:position :absolute
@@ -39,7 +39,7 @@
:bottom 0})
(defn selected-item
[override-theme window-height sheet-height {:keys [top]}]
[theme window-height sheet-height {:keys [top]}]
{:position :absolute
:bottom 10
:max-height (- window-height sheet-height top)
@@ -48,4 +48,4 @@
:right 0
:border-radius 12
:margin-horizontal 8
:background-color (colors/theme-colors colors/white colors/neutral-90 override-theme)})
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)})
+13 -6
View File
@@ -1,6 +1,7 @@
(ns status-im2.common.bottom-sheet.view
(:require [oops.core :as oops]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.blur :as blur]
[react-native.core :as rn]
[react-native.gesture :as gesture]
@@ -52,11 +53,11 @@
(show translate-y bg-opacity)
(hide translate-y bg-opacity window-height on-close))))))
(defn f-view
(defn- f-view
[_ _]
(let [sheet-height (reagent/atom 0)]
(fn [{:keys [hide? insets]}
{:keys [content override-theme selected-item padding-bottom-override on-close shell?]}]
(fn [{:keys [hide? insets theme]}
{:keys [content selected-item padding-bottom-override on-close shell?]}]
(let [{window-height :height} (rn/get-window)
bg-opacity (reanimated/use-shared-value 0)
translate-y (reanimated/use-shared-value window-height)
@@ -85,7 +86,7 @@
{:transform [{:translateY translate-y}]}
(style/sheet insets
window-height
override-theme
theme
padding-bottom-override
shell?))
:on-layout #(reset! sheet-height (oops/oget % "nativeEvent" "layout" "height"))}
@@ -93,10 +94,16 @@
[blur/ios-view {:style style/shell-bg}])
(when selected-item
[rn/view
[rn/view {:style (style/selected-item override-theme window-height @sheet-height insets)}
[rn/view {:style (style/selected-item theme window-height @sheet-height insets)}
[selected-item]]])
;; handle
[rn/view {:style (style/handle override-theme)}]
[rn/view {:style (style/handle theme)}]
;; content
[content]]]]))))
(defn- internal-view
[args sheet]
[:f> f-view args sheet])
(def view (theme/with-theme internal-view))
@@ -0,0 +1,18 @@
(ns status-im2.common.device-permissions
(:require
[quo2.foundations.colors :as colors]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn camera
[on-allowed]
(rf/dispatch
[:request-permissions
{:permissions [:camera]
:on-allowed on-allowed
:on-denied #(rf/dispatch
[:toasts/upsert
{:icon :i/info
:icon-color colors/danger-50
:theme :dark
:text (i18n/label :t/camera-permission-denied)}])}]))
+12 -10
View File
@@ -8,8 +8,8 @@
[status-im2.contexts.contacts.drawers.nickname-drawer.view :as nickname-drawer]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[status-im2.common.mute-chat-drawer.view :as mute-chat-drawer]
[utils.datetime :as datetime]))
[status-im2.common.mute-drawer.view :as mute-drawer]
[status-im2.common.muting.helpers :refer [format-mute-till]]))
(defn- entry
[{:keys [icon label on-press danger? sub-label chevron? add-divider? accessibility-label]}]
@@ -53,11 +53,15 @@
:accessibility-label :edit-nickname}])}]))
(defn mute-chat-action
[chat-id chat-type]
[chat-id chat-type muted?]
(hide-sheet-and-dispatch [:show-bottom-sheet
{:content (fn []
[mute-chat-drawer/mute-chat-drawer chat-id
:mute-chat-for-duration chat-type])}]))
[mute-drawer/mute-drawer
{:id chat-id
:community? false
:muted? (not muted?)
:chat-type chat-type
:accessibility-label :mute-community-title}])}]))
(defn unmute-chat-action
[chat-id]
@@ -131,12 +135,10 @@
:unmute-chat
:mute-chat))
:sub-label (when (and muted? (some? muted-till))
(str (i18n/label :t/muted-until)
" "
(datetime/format-mute-till muted-till)))
(i18n/label :t/muted-until {:duration (format-mute-till muted-till)}))
:on-press (if muted?
#(unmute-chat-action chat-id)
#(mute-chat-action chat-id chat-type))
#(mute-chat-action chat-id chat-type muted?))
:danger? false
:accessibility-label :mute-chat
:chevron? (not muted?)})))
@@ -215,7 +217,7 @@
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch [:toasts/upsert
{:id :remove-nickname
:icon :correct
:icon :i/correct
:icon-color (colors/theme-colors colors/success-60
colors/success-50)
:text (i18n/label
@@ -1,76 +0,0 @@
(ns status-im2.common.mute-chat-drawer.view
(:require [utils.i18n :as i18n]
[quo2.core :as quo]
[react-native.core :as rn]
[status-im2.constants :as constants]
[utils.re-frame :as rf]
[status-im2.common.mute-chat-drawer.style :as style]))
(defn not-community-chat?
[chat-type]
(contains? #{constants/public-chat-type
constants/private-group-chat-type
constants/one-to-one-chat-type}
chat-type))
(defn hide-sheet-and-dispatch
[event]
(rf/dispatch [:hide-bottom-sheet])
(rf/dispatch event))
(defn mute-chat-drawer
[chat-id accessibility-label chat-type]
[rn/view {:accessibility-label accessibility-label}
[quo/text
{:weight :medium
:size :paragraph-2
:style (style/header-text)}
(i18n/label
(if (not-community-chat? chat-type)
:t/mute-chat-capitialized
:t/mute-channel))]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-for-15-mins)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
constants/mute-for-15-mins-type]))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-for-1-hour)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
constants/mute-for-1-hour-type]))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-for-8-hours)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
constants/mute-for-8-hours-type]))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-for-1-week)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
constants/mute-for-1-week]))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-till-unmute)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch [:chat.ui/mute chat-id true
constants/mute-till-unmuted]))}]])
@@ -1,4 +1,4 @@
(ns status-im2.common.mute-chat-drawer.style
(ns status-im2.common.mute-drawer.style
(:require [quo2.foundations.colors :as colors]))
(defn header-text
+100
View File
@@ -0,0 +1,100 @@
(ns status-im2.common.mute-drawer.view
(:require [utils.i18n :as i18n]
[quo2.core :as quo]
[react-native.core :as rn]
[status-im2.constants :as constants]
[utils.re-frame :as rf]
[status-im2.common.mute-drawer.style :as style]))
(defn not-community-chat?
[chat-type]
(contains? #{constants/public-chat-type
constants/private-group-chat-type
constants/one-to-one-chat-type}
chat-type))
(defn hide-sheet-and-dispatch
[{:keys [id community? muted? muted-type]}]
(rf/dispatch [:hide-bottom-sheet])
(if community?
(rf/dispatch [:community/set-muted id muted? muted-type])
(rf/dispatch [:chat.ui/mute id muted? muted-type])))
(defn mute-drawer
[{:keys [id accessibility-label muted? chat-type community?]}]
[rn/view {:accessibility-label accessibility-label}
[quo/text
{:weight :medium
:size :paragraph-2
:style (style/header-text)}
(i18n/label
(if community?
:t/mute-community
(if (not-community-chat? chat-type)
:t/mute-chat-capitialized
:t/mute-channel)))]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-for-15-mins)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch
{:id id
:chat-type chat-type
:muted? muted?
:community? community?
:muted-type constants/mute-for-15-mins-type}))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-for-1-hour)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch
{:id id
:chat-type chat-type
:muted? muted?
:community? community?
:muted-type constants/mute-for-1-hour-type}))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-for-8-hours)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch
{:id id
:chat-type chat-type
:muted? muted?
:community? community?
:muted-type constants/mute-for-8-hours-type}))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-for-1-week)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch
{:id id
:chat-type chat-type
:muted? muted?
:community? community?
:muted-type constants/mute-for-1-week}))}]
[quo/menu-item
{:type :transparent
:title (i18n/label :t/mute-till-unmute)
:icon-bg-color :transparent
:container-padding-vertical 12
:title-column-style {:margin-left 2}
:on-press (fn []
(hide-sheet-and-dispatch
{:id id
:chat-type chat-type
:muted? muted?
:community? community?
:muted-type constants/mute-till-unmuted}))}]])
+39
View File
@@ -0,0 +1,39 @@
(ns status-im2.common.muting.helpers
(:require [cljs-time.core :as t]
[utils.i18n :as i18n]
[utils.datetime :refer
[go-default-time int->weekday months
time-zone-offset today? tomorrow?]])
(:require [cljs-time.format :as t.format]))
(defn- add-leading-zero
[input-string]
(if (> 10 input-string)
(str "0" input-string)
input-string))
(defn format-mute-till
[muted-till-string]
(let [parsed-time (t.format/parse (t.format/formatters :date-time-no-ms) muted-till-string)
hours-and-minutes (str (add-leading-zero (t/hour (t/plus parsed-time time-zone-offset)))
":"
(add-leading-zero (t/minute parsed-time)))
when-to-unmute (cond (= go-default-time
muted-till-string) (i18n/label :t/until-you-turn-it-back-on)
(today? parsed-time) (str hours-and-minutes " today")
(tomorrow? parsed-time) (str hours-and-minutes " tomorrow")
:else (str hours-and-minutes
" "
(i18n/label
(keyword "t"
(get int->weekday
(t/day-of-week
parsed-time))))
" "
(t/day parsed-time)
" "
(i18n/label
(keyword "t"
(get months
(t/month parsed-time))))))]
when-to-unmute))

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