Compare commits
40
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
41cf687b3f | ||
|
|
a8303dbe50 | ||
|
|
43cba161d6 | ||
|
|
ce08131c01 | ||
|
|
4f044765e1 | ||
|
|
7cd9f76043 | ||
|
|
238e35a281 | ||
|
|
57c538e9d0 | ||
|
|
e49a3ab5cd | ||
|
|
1721b40b3f | ||
|
|
ec6800216b | ||
|
|
15add24cd7 | ||
|
|
28f790b436 | ||
|
|
9aafe61f5f | ||
|
|
02d45fa06f | ||
|
|
99dc79842d | ||
|
|
2a8e6cb304 | ||
|
|
eb3de978ce | ||
|
|
e672bf9163 | ||
|
|
e33c877989 | ||
|
|
c5a486622d | ||
|
|
00f39225ea | ||
|
|
0ac6817488 | ||
|
|
33d41dc5d5 | ||
|
|
76eea91ba2 | ||
|
|
1b2ad33926 | ||
|
|
9731e7039c | ||
|
|
b14757b120 | ||
|
|
2317e856bf | ||
|
|
32f18c3d3c | ||
|
|
e99f6de434 | ||
|
|
bb3b3061c6 | ||
|
|
0067468d57 | ||
|
|
b2cbed444c | ||
|
|
1d0186a12e | ||
|
|
c0e4653129 | ||
|
|
60f18fc6fb | ||
|
|
b531dadf96 | ||
|
|
2b0ea01710 | ||
|
|
9f5e7ce3f9 |
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: Bug Report
|
||||
name: MVPBug Report
|
||||
about: MVPBug Report
|
||||
title: ''
|
||||
labels: bug
|
||||
labels: 'E:Mobile Bugfixes MVP'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
@@ -22,8 +22,7 @@ assignees: ''
|
||||
|
||||
### Reproduction
|
||||
|
||||
1) Open Status
|
||||
2)
|
||||
1.
|
||||
|
||||
### Additional Information
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
[](https://www.browserstack.com/automate/public-build/SFBWQ3k5R2tnT2t6UGsxU1h1U0g3VFlCNnoxVTRHYWNoTDhsb1laaTJZWT0tLUZMUm5sSVFBSU9qSWM1RUJvK1I3Z3c9PQ==--ad15ae7992b432b33743749d40318952415bd98f)
|
||||
|
||||
+2
-2
@@ -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
@@ -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 |
@@ -0,0 +1,55 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Please provide the full branch URL as an argument."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$2" ]; then
|
||||
echo "Please provide the full pull request URL as second argument."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Extract PR number from the URL
|
||||
PR_URL="$2"
|
||||
PR_NUMBER=$(echo "$PR_URL" | awk -F '/' '{print $NF}')
|
||||
|
||||
# Fetch PR Info
|
||||
PR_TITLE=$(gh pr view "$PR_NUMBER" --json title -q '.title')
|
||||
PR_DESCRIPTION=$(gh pr view "$PR_NUMBER" --json body -q '.body')
|
||||
BRANCH_NAME=$(gh pr view "$PR_NUMBER" --json headRefName -q '.headRefName')
|
||||
|
||||
# Extracting the repo URL and branch name
|
||||
FULL_URL="$1"
|
||||
REPO_URL=$(echo "$FULL_URL" | awk -F "/tree/" '{print $1}')
|
||||
REPO_NAME=$(basename "$REPO_URL")
|
||||
NEW_REMOTE_URL="https://github.com/status-im/status-mobile"
|
||||
|
||||
# Clone the repo if not already cloned
|
||||
if [ ! -d "$REPO_NAME" ]; then
|
||||
git clone "$REPO_URL"
|
||||
cd "$REPO_NAME" || exit
|
||||
gh repo set-default "$REPO_URL"
|
||||
else
|
||||
cd "$REPO_NAME" || exit
|
||||
gh repo set-default "$REPO_URL"
|
||||
git fetch
|
||||
fi
|
||||
|
||||
# Check if branch already exists
|
||||
BRANCH_EXISTS=$(git show-ref refs/heads/"$BRANCH_NAME" 2>/dev/null)
|
||||
|
||||
if [ -z "$BRANCH_EXISTS" ]; then
|
||||
# New Import
|
||||
git checkout -b "$BRANCH_NAME" "origin/$BRANCH_NAME"
|
||||
git remote add source "$REPO_URL"
|
||||
git remote set-url origin $NEW_REMOTE_URL
|
||||
git push -u origin "$BRANCH_NAME"
|
||||
gh pr create --base develop --head "$BRANCH_NAME" --title "[IMPORTED] $PR_TITLE" --body "$PR_DESCRIPTION"
|
||||
else
|
||||
# Sync Existing Import
|
||||
git checkout "$BRANCH_NAME"
|
||||
git fetch source "$BRANCH_NAME"
|
||||
git rebase source/"$BRANCH_NAME" # Rebase instead of merge
|
||||
git push origin "$BRANCH_NAME" # Push updates to your imported branch
|
||||
fi
|
||||
@@ -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
@@ -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
@@ -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?)))
|
||||
@@ -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
|
||||
|
||||
@@ -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)))))])
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
:margin-bottom (+ (safe-area/get-bottom) 8)})
|
||||
|
||||
(defn title
|
||||
[shell?]
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-100
|
||||
colors/white
|
||||
(when shell? :dark))})
|
||||
theme)})
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
[quo2.components.drawers.documentation-drawers.style :as style]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]))
|
||||
[react-native.gesture :as gesture]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn view
|
||||
(defn- view-internal
|
||||
"Options
|
||||
- `title` Title text
|
||||
- `show-button?` Show button
|
||||
@@ -15,7 +16,7 @@
|
||||
- `shell?` use shell theme
|
||||
`content` Content of the drawer
|
||||
"
|
||||
[{:keys [title show-button? on-press-button button-label button-icon shell?]} content]
|
||||
[{:keys [title show-button? on-press-button button-label button-icon theme shell?]} content]
|
||||
[gesture/scroll-view
|
||||
{:style style/outer-container
|
||||
:always-bounce-vertical false
|
||||
@@ -24,18 +25,18 @@
|
||||
[text/text
|
||||
{:size :heading-2
|
||||
:accessibility-label :documentation-drawer-title
|
||||
:style (style/title shell?)
|
||||
:style (style/title theme)
|
||||
:weight :semi-bold}
|
||||
title]
|
||||
[rn/view {:style style/content :accessibility-label :documentation-drawer-content}
|
||||
content]
|
||||
(when show-button?
|
||||
[button/button
|
||||
(cond-> {:size 24
|
||||
:type (if shell? :blur-bg-outline :outline)
|
||||
:on-press on-press-button
|
||||
:accessibility-label :documentation-drawer-button
|
||||
:after button-icon}
|
||||
shell? (assoc :override-theme :dark))
|
||||
{:size 24
|
||||
:type (if shell? :blur-bg-outline :outline)
|
||||
:on-press on-press-button
|
||||
:accessibility-label :documentation-drawer-button
|
||||
:after button-icon}
|
||||
button-label])]])
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -35,4 +35,5 @@
|
||||
(get-icons 16)
|
||||
(get-icons 20)
|
||||
(get-icons 24)
|
||||
(get-icons 32)))
|
||||
(get-icons 32)
|
||||
(get-icons 48)))
|
||||
|
||||
@@ -3,62 +3,62 @@
|
||||
[quo2.foundations.colors :as colors]))
|
||||
|
||||
(defn variants-colors
|
||||
[blur? override-theme]
|
||||
[blur? theme]
|
||||
(if blur?
|
||||
{:label (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 override-theme)
|
||||
:icon (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 override-theme)
|
||||
:button-border (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
|
||||
:password-icon (colors/theme-colors colors/neutral-100 colors/white-opa-70 override-theme)
|
||||
:clear-icon (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 override-theme)
|
||||
{:label (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:icon (colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70 theme)
|
||||
:button-border (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 theme)
|
||||
:password-icon (colors/theme-colors colors/neutral-100 colors/white-opa-70 theme)
|
||||
:clear-icon (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-10 theme)
|
||||
:cursor (colors/theme-colors (colors/custom-color :blue 50)
|
||||
colors/white
|
||||
override-theme)}
|
||||
{:label (colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)
|
||||
:icon (colors/theme-colors colors/neutral-50 colors/neutral-40 override-theme)
|
||||
:button-border (colors/theme-colors colors/neutral-30 colors/neutral-70 override-theme)
|
||||
:clear-icon (colors/theme-colors colors/neutral-40 colors/neutral-60 override-theme)
|
||||
:password-icon (colors/theme-colors colors/neutral-50 colors/white override-theme)
|
||||
theme)}
|
||||
{:label (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:icon (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:button-border (colors/theme-colors colors/neutral-30 colors/neutral-70 theme)
|
||||
:clear-icon (colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
:password-icon (colors/theme-colors colors/neutral-50 colors/white theme)
|
||||
:cursor (colors/theme-colors (colors/custom-color :blue 50)
|
||||
(colors/custom-color :blue 60)
|
||||
override-theme)}))
|
||||
theme)}))
|
||||
|
||||
(defn status-colors
|
||||
[status blur? override-theme]
|
||||
[status blur? theme]
|
||||
(if blur?
|
||||
(case status
|
||||
:focus
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-40 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)}
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-40 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:error
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)}
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:disabled
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-20 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-20 override-theme)}
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-20 theme)
|
||||
:text (colors/theme-colors colors/neutral-80-opa-30 colors/white-opa-20 theme)}
|
||||
;; :default
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)})
|
||||
{:border-color (colors/theme-colors colors/neutral-80-opa-10 colors/white-opa-10 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)})
|
||||
(case status
|
||||
:focus
|
||||
{:border-color (colors/theme-colors colors/neutral-40 colors/neutral-60 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-30 colors/neutral-60 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)}
|
||||
{:border-color (colors/theme-colors colors/neutral-40 colors/neutral-60 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:error
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/white-opa-40 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)}
|
||||
{:border-color (colors/theme-colors colors/danger-opa-40 colors/danger-opa-40 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/white-opa-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)}
|
||||
:disabled
|
||||
{:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/neutral-40 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-40 colors/neutral-40 override-theme)}
|
||||
{:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/neutral-40 theme)
|
||||
:text (colors/theme-colors colors/neutral-40 colors/neutral-40 theme)}
|
||||
;; :default
|
||||
{:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 override-theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white override-theme)})))
|
||||
{:border-color (colors/theme-colors colors/neutral-20 colors/neutral-80 theme)
|
||||
:placeholder (colors/theme-colors colors/neutral-40 colors/neutral-50 theme)
|
||||
:text (colors/theme-colors colors/neutral-100 colors/white theme)})))
|
||||
|
||||
(defn input-container
|
||||
[colors-by-status small? disabled?]
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
[quo2.components.markdown.text :as text]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.theme :as theme]))
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(defn- label-&-counter
|
||||
[{:keys [label current-chars char-limit variant-colors]}]
|
||||
@@ -54,7 +54,7 @@
|
||||
|
||||
(def ^:private custom-props
|
||||
"Custom properties that must be removed from properties map passed to InputText."
|
||||
[:type :blur? :override-theme :error? :right-icon :left-icon :disabled? :small? :button
|
||||
[:type :blur? :theme :error? :right-icon :left-icon :disabled? :small? :button
|
||||
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur])
|
||||
|
||||
(defn- base-input
|
||||
@@ -74,15 +74,15 @@
|
||||
(reset! char-count amount-chars)
|
||||
(when (>= amount-chars char-limit)
|
||||
(on-char-limit-reach amount-chars))))]
|
||||
(fn [{:keys [blur? override-theme error? right-icon left-icon disabled? small? button
|
||||
(fn [{:keys [blur? theme error? right-icon left-icon disabled? small? button
|
||||
label char-limit multiline? clearable? on-focus on-blur]
|
||||
:as props}]
|
||||
(let [status-kw (cond
|
||||
disabled? :disabled
|
||||
error? :error
|
||||
:else @status)
|
||||
colors-by-status (style/status-colors status-kw blur? override-theme)
|
||||
variant-colors (style/variants-colors blur? override-theme)
|
||||
colors-by-status (style/status-colors status-kw blur? theme)
|
||||
variant-colors (style/variants-colors blur? theme)
|
||||
clean-props (apply dissoc props custom-props)]
|
||||
[:<>
|
||||
(when (or label char-limit)
|
||||
@@ -101,7 +101,7 @@
|
||||
(cond-> {:style (style/input colors-by-status small? @multiple-lines?)
|
||||
:accessibility-label :input
|
||||
:placeholder-text-color (:placeholder colors-by-status)
|
||||
:keyboard-appearance (theme/theme-value :light :dark override-theme)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:cursor-color (:cursor variant-colors)
|
||||
:editable (not disabled?)
|
||||
:on-focus (fn []
|
||||
@@ -148,11 +148,11 @@
|
||||
:icon-name (if @password-shown? :i/hide :i/reveal)
|
||||
:on-press #(swap! password-shown? not)})])))
|
||||
|
||||
(defn input
|
||||
(defn input-internal
|
||||
"This input supports the following properties:
|
||||
- :type - Can be `:text`(default) or `:password`.
|
||||
- :blur? - Boolean to set the blur color variant.
|
||||
- :override-theme - Can be `light` or `:dark`.
|
||||
- :theme - Can be `light` or `:dark`.
|
||||
- :small? - Boolean to specify if this input is rendered in its small version.
|
||||
- :multiline? - Boolean to specify if this input support multiple lines.
|
||||
- :icon-name - The name of an icon to display at the left of the input.
|
||||
@@ -188,3 +188,5 @@
|
||||
(if (= type :password)
|
||||
[password-input base-props]
|
||||
[base-input base-props])))
|
||||
|
||||
(def input (quo.theme/with-theme input-internal))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -17,29 +17,29 @@
|
||||
:text-align-vertical :top))
|
||||
|
||||
(defn placeholder-color
|
||||
[input-state override-theme blur?]
|
||||
[input-state theme blur?]
|
||||
(cond
|
||||
(and (= input-state :focused) blur?)
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 override-theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-20 colors/white-opa-20 theme)
|
||||
|
||||
(= input-state :focused) ; Not blur
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 override-theme)
|
||||
(colors/theme-colors colors/neutral-30 colors/neutral-60 theme)
|
||||
|
||||
blur? ; :default & blur
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 override-theme)
|
||||
(colors/theme-colors colors/neutral-80-opa-40 colors/white-opa-30 theme)
|
||||
|
||||
:else ; :default & not blur
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 override-theme)))
|
||||
(colors/theme-colors colors/neutral-40 colors/neutral-50 theme)))
|
||||
|
||||
(defn cursor-color
|
||||
[customization-color override-theme]
|
||||
[customization-color theme]
|
||||
(colors/theme-colors (colors/custom-color customization-color 50)
|
||||
(colors/custom-color customization-color 60)
|
||||
override-theme))
|
||||
theme))
|
||||
|
||||
(defn error-word
|
||||
[]
|
||||
[theme]
|
||||
{:height 22
|
||||
:padding-horizontal 20
|
||||
:background-color colors/danger-50-opa-10
|
||||
:color (colors/theme-colors colors/danger-50 colors/danger-60)})
|
||||
:color (colors/theme-colors colors/danger-50 colors/danger-60 theme)})
|
||||
|
||||
@@ -3,19 +3,19 @@
|
||||
[quo2.components.inputs.recovery-phrase.style :as style]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[quo2.theme :as theme]))
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def ^:private custom-props
|
||||
[:customization-color :override-theme :blur? :cursor-color :multiline :on-focus :on-blur
|
||||
[:customization-color :theme :blur? :cursor-color :multiline :on-focus :on-blur
|
||||
:placeholder-text-color :mark-errors? :error-pred :word-limit])
|
||||
|
||||
(defn- error-word
|
||||
[text]
|
||||
[rn/text {:style (style/error-word)}
|
||||
[text theme]
|
||||
[rn/text {:style (style/error-word theme)}
|
||||
text])
|
||||
|
||||
(defn- mark-error-words
|
||||
[pred-last-word pred-previous-words text word-limit]
|
||||
[{:keys [pred-last-word pred-previous-words text word-limit theme]}]
|
||||
(let [last-index (dec (count (string/split text #"\s+")))
|
||||
words (map #(apply str %)
|
||||
(partition-by #(= " " %) text))]
|
||||
@@ -31,18 +31,18 @@
|
||||
:always (update :result
|
||||
conj
|
||||
(if invalid-word?
|
||||
[error-word word]
|
||||
[error-word word theme]
|
||||
word)))))
|
||||
{:result [:<>]
|
||||
:idx 0})
|
||||
:result)))
|
||||
|
||||
(defn recovery-phrase-input
|
||||
(defn recovery-phrase-input-internal
|
||||
[_ _]
|
||||
(let [state (reagent/atom :default)
|
||||
set-focused #(reset! state :focused)
|
||||
set-default #(reset! state :default)]
|
||||
(fn [{:keys [customization-color override-theme blur? on-focus on-blur mark-errors?
|
||||
(fn [{:keys [customization-color theme blur? on-focus on-blur mark-errors?
|
||||
error-pred-current-word error-pred-written-words word-limit]
|
||||
:or {customization-color :blue
|
||||
word-limit ##Inf
|
||||
@@ -55,9 +55,9 @@
|
||||
[rn/text-input
|
||||
(merge {:accessibility-label :recovery-phrase-input
|
||||
:style (style/input)
|
||||
:placeholder-text-color (style/placeholder-color @state override-theme blur?)
|
||||
:cursor-color (style/cursor-color customization-color override-theme)
|
||||
:keyboard-appearance (theme/theme-value :light :dark override-theme)
|
||||
:placeholder-text-color (style/placeholder-color @state theme blur?)
|
||||
:cursor-color (style/cursor-color customization-color theme)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
:multiline true
|
||||
:on-focus (fn []
|
||||
(set-focused)
|
||||
@@ -67,5 +67,11 @@
|
||||
(when on-blur (on-blur)))}
|
||||
extra-props)
|
||||
(if mark-errors?
|
||||
(mark-error-words error-pred-current-word error-pred-written-words text word-limit)
|
||||
(mark-error-words {:pred-last-word error-pred-current-word
|
||||
:pred-previous-words error-pred-written-words
|
||||
:text text
|
||||
:word-limit word-limit
|
||||
:theme theme})
|
||||
text)]]))))
|
||||
|
||||
(def recovery-phrase-input (quo.theme/with-theme recovery-phrase-input-internal))
|
||||
|
||||
@@ -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)}))
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
[quo2.foundations.colors :as colors]
|
||||
[react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]
|
||||
[react-native.hole-view :as hole-view]))
|
||||
[react-native.hole-view :as hole-view]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def params
|
||||
{32 {:border-radius {:circular 16 :rounded 10}
|
||||
@@ -61,13 +62,13 @@
|
||||
[avatar item type size border-radius]]))
|
||||
|
||||
(defn get-overflow-color
|
||||
[transparent? transparent-color light-color dark-color override-theme]
|
||||
[transparent? transparent-color light-color dark-color theme]
|
||||
(if transparent?
|
||||
transparent-color
|
||||
(colors/theme-colors light-color dark-color override-theme)))
|
||||
(colors/theme-colors light-color dark-color theme)))
|
||||
|
||||
(defn overflow-label
|
||||
[label size transparent? border-radius margin-left override-theme more-than-99-label]
|
||||
[{:keys [label size transparent? border-radius margin-left theme more-than-99-label]}]
|
||||
[rn/view
|
||||
{:style {:width size
|
||||
:height size
|
||||
@@ -80,7 +81,7 @@
|
||||
colors/white-opa-10
|
||||
colors/neutral-20
|
||||
colors/neutral-70
|
||||
override-theme)}}
|
||||
theme)}}
|
||||
(if (= size 16)
|
||||
[quo2.icons/icon :i/more
|
||||
{:size 12
|
||||
@@ -89,7 +90,7 @@
|
||||
colors/white-opa-70
|
||||
colors/neutral-50
|
||||
colors/neutral-40
|
||||
override-theme)}]
|
||||
theme)}]
|
||||
[quo2.text/text
|
||||
{:size (if (= size 32) :paragraph-2 :label)
|
||||
:weight :medium
|
||||
@@ -98,7 +99,7 @@
|
||||
colors/white-opa-70
|
||||
colors/neutral-60
|
||||
colors/neutral-40
|
||||
override-theme)
|
||||
theme)
|
||||
:margin-left -2}}
|
||||
;; If overflow label is below 100, show label as +label (ex. +30), else just show 99+
|
||||
(if (< label 100)
|
||||
@@ -111,7 +112,7 @@
|
||||
(:account :collectible :photo) :rounded
|
||||
:circular))
|
||||
|
||||
(defn preview-list
|
||||
(defn- preview-list-internal
|
||||
"[preview-list opts items]
|
||||
opts
|
||||
{:type :user/:community/:account/:token/:collectible/:dapp
|
||||
@@ -120,7 +121,7 @@
|
||||
:transparent? overflow-label transparent?}
|
||||
items preview list items (only 4 items is required for preview)
|
||||
"
|
||||
[{:keys [type size list-size transparent? override-theme more-than-99-label]} items]
|
||||
[{:keys [type size list-size transparent? theme more-than-99-label]} items]
|
||||
(let [items-arr (into [] items)
|
||||
list-size (or list-size (count items))
|
||||
margin-left (get-in params [size :margin-left])
|
||||
@@ -135,5 +136,13 @@
|
||||
[list-item index type size (get items-arr index) list-size
|
||||
margin-left hole-size hole-radius hole-x hole-y border-radius])
|
||||
(when (> list-size 4)
|
||||
[overflow-label (- list-size 3) size transparent? border-radius margin-left override-theme
|
||||
more-than-99-label])]))
|
||||
[overflow-label
|
||||
{:label (- list-size 3)
|
||||
:size size
|
||||
:transparent? transparent?
|
||||
:border-radius border-radius
|
||||
:margin-left margin-left
|
||||
:theme theme
|
||||
:more-than-99-label more-than-99-label}])]))
|
||||
|
||||
(def preview-list (quo.theme/with-theme preview-list-internal))
|
||||
|
||||
@@ -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)))
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -10,8 +10,8 @@
|
||||
:padding 6})
|
||||
|
||||
(defn container-border-color
|
||||
[pressed? blur? override-theme]
|
||||
(let [dark? (= :dark override-theme)]
|
||||
[pressed? blur? theme]
|
||||
(let [dark? (= :dark theme)]
|
||||
(cond
|
||||
(and (not pressed?) (not dark?) (not blur?))
|
||||
colors/neutral-20
|
||||
@@ -35,26 +35,24 @@
|
||||
nil)))
|
||||
|
||||
(defn container-background-color
|
||||
[pressed? override-theme]
|
||||
[pressed? theme]
|
||||
(when pressed?
|
||||
(if (= :dark override-theme)
|
||||
colors/primary-60
|
||||
colors/primary-50)))
|
||||
(colors/theme-colors colors/primary-50 colors/primary-60 theme)))
|
||||
|
||||
(defn container-outer
|
||||
[pressed? override-theme]
|
||||
[pressed? theme]
|
||||
(merge container-default
|
||||
{:background-color (container-background-color pressed? override-theme)}))
|
||||
{:background-color (container-background-color pressed? theme)}))
|
||||
|
||||
(defn container-inner
|
||||
[pressed? blur? override-theme]
|
||||
[pressed? blur? theme]
|
||||
(merge container-default
|
||||
{:border-width 1
|
||||
:border-color (container-border-color pressed? blur? override-theme)}))
|
||||
:border-color (container-border-color pressed? blur? theme)}))
|
||||
|
||||
(defn icon-color
|
||||
[pressed? override-theme]
|
||||
[pressed? theme]
|
||||
(if (and (not pressed?)
|
||||
(= :light override-theme))
|
||||
(= :light theme))
|
||||
colors/neutral-100
|
||||
colors/white))
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
(ns quo2.components.selectors.filter.view
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.components.selectors.filter.style :as style]
|
||||
[quo2.theme :as theme]
|
||||
[quo2.theme :as quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
|
||||
(defn view
|
||||
(defn view-internal
|
||||
[initial-props]
|
||||
(let [pressed? (reagent/atom (:pressed? initial-props))]
|
||||
(fn [{:keys [blur? override-theme on-press-out]
|
||||
:or {override-theme (theme/get-theme)}}]
|
||||
(fn [{:keys [blur? theme on-press-out]}]
|
||||
[rn/touchable-without-feedback
|
||||
{:accessibility-label :selector-filter
|
||||
:on-press-out (fn []
|
||||
(swap! pressed? not)
|
||||
(when on-press-out
|
||||
(on-press-out @pressed?)))}
|
||||
[rn/view {:style (style/container-outer @pressed? override-theme)}
|
||||
[rn/view {:style (style/container-inner @pressed? blur? override-theme)}
|
||||
[rn/view {:style (style/container-outer @pressed? theme)}
|
||||
[rn/view {:style (style/container-inner @pressed? blur? theme)}
|
||||
[icon/icon :i/unread
|
||||
{:color (style/icon-color @pressed? override-theme)
|
||||
{:color (style/icon-color @pressed? theme)
|
||||
:size 20}]]]])))
|
||||
|
||||
(def view (quo.theme/with-theme view-internal))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
(ns quo2.components.tabs.segmented-tab
|
||||
(:require [quo2.components.tabs.tab.view :as tab]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as theme]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]))
|
||||
[reagent.core :as reagent]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def themes-for-blur
|
||||
{:light {:background-color colors/neutral-80-opa-5}
|
||||
@@ -13,17 +13,17 @@
|
||||
{:light {:background-color colors/neutral-10}
|
||||
:dark {:background-color colors/neutral-90}})
|
||||
|
||||
(defn segmented-control
|
||||
(defn- segmented-control-internal
|
||||
[{:keys [default-active on-change]}]
|
||||
(let [active-tab-id (reagent/atom default-active)]
|
||||
(fn [{:keys [data size override-theme blur? container-style item-container-style
|
||||
(fn [{:keys [data size theme blur? container-style item-container-style
|
||||
active-item-container-style]}]
|
||||
(let [active-id @active-tab-id]
|
||||
[rn/view
|
||||
(merge
|
||||
{:flex-direction :row
|
||||
:background-color (get-in (if blur? themes-for-blur themes)
|
||||
[(or override-theme (theme/get-theme)) :background-color])
|
||||
[theme :background-color])
|
||||
:border-radius (case size
|
||||
32 10
|
||||
28 8
|
||||
@@ -42,7 +42,6 @@
|
||||
:item-container-style item-container-style
|
||||
:segmented? true
|
||||
:size size
|
||||
:override-theme override-theme
|
||||
:blur? blur?
|
||||
:active (= id active-id)
|
||||
:on-press (fn [tab-id]
|
||||
@@ -50,3 +49,5 @@
|
||||
(when on-change
|
||||
(on-change tab-id)))}
|
||||
label]])]))))
|
||||
|
||||
(def segmented-control (quo.theme/with-theme segmented-control-internal))
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
(:require [quo2.components.icon :as icon]
|
||||
[quo2.components.markdown.text :as text]
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.theme :as quo2.theme]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[quo2.theme :as quo.theme]))
|
||||
|
||||
(def default-container-style
|
||||
{:border-radius 20
|
||||
@@ -81,7 +81,7 @@
|
||||
:border-color colors/danger-50-opa-20
|
||||
:label label
|
||||
;; The negative tag uses the same color for `dark` and `dark blur` variant
|
||||
:text-color (if (= theme :light) colors/danger-50 colors/danger-60)}])
|
||||
:text-color (colors/theme-colors colors/danger-50 colors/danger-60 theme)}])
|
||||
|
||||
(defn- pending
|
||||
[size theme label blur? no-icon?]
|
||||
@@ -104,8 +104,8 @@
|
||||
colors/white-opa-70
|
||||
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}])
|
||||
|
||||
(defn status-tag
|
||||
[{:keys [status size override-theme label blur? no-icon?]}]
|
||||
(defn- status-tag-internal
|
||||
[{:keys [status size theme label blur? no-icon?]}]
|
||||
(when status
|
||||
(when-let [status-component (case (:type status)
|
||||
:positive positive
|
||||
@@ -114,7 +114,9 @@
|
||||
nil)]
|
||||
[status-component
|
||||
size
|
||||
(or override-theme (quo2.theme/get-theme))
|
||||
theme
|
||||
label
|
||||
blur?
|
||||
no-icon?])))
|
||||
|
||||
(def status-tag (quo.theme/with-theme status-tag-internal))
|
||||
|
||||
@@ -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)])))
|
||||
|
||||
+41
-23
@@ -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
|
||||
@@ -95,30 +98,7 @@
|
||||
quo2.components.tags.token-tag
|
||||
quo2.components.text-combinations.title.view))
|
||||
|
||||
(def icon quo2.components.icon/icon)
|
||||
(def separator quo2.components.common.separator.view/separator)
|
||||
(def header quo2.components.header/header)
|
||||
(def dropdown quo2.components.dropdowns.dropdown/dropdown)
|
||||
(def info-message quo2.components.info.info-message/info-message)
|
||||
(def information-box quo2.components.info.information-box.view/view)
|
||||
(def gap quo2.components.messages.gap/gap)
|
||||
(def system-message quo2.components.messages.system-message/system-message)
|
||||
(def reaction quo2.components.reactions.reaction/reaction)
|
||||
(def add-reaction quo2.components.reactions.reaction/add-reaction)
|
||||
(def user-avatar-tag quo2.components.tags.context-tag.view/user-avatar-tag)
|
||||
(def context-tag quo2.components.tags.context-tag.view/context-tag)
|
||||
(def group-avatar-tag quo2.components.tags.context-tag.view/group-avatar-tag)
|
||||
(def audio-tag quo2.components.tags.context-tag.view/audio-tag)
|
||||
(def community-tag quo2.components.tags.context-tag.view/community-tag)
|
||||
|
||||
|
||||
(def disclaimer quo2.components.selectors.disclaimer.view/view)
|
||||
(def checkbox quo2.components.selectors.selectors.view/checkbox)
|
||||
(def filter quo2.components.selectors.filter.view/view)
|
||||
(def author quo2.components.messages.author.view/author)
|
||||
|
||||
;;;; SELECTORS
|
||||
(def reactions quo2.components.selectors.reactions.view/view)
|
||||
|
||||
;;;; AVATAR
|
||||
(def account-avatar quo2.components.avatars.account-avatar/account-avatar)
|
||||
@@ -137,6 +117,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)
|
||||
|
||||
@@ -178,9 +161,22 @@
|
||||
(def drawer-buttons quo2.components.drawers.drawer-buttons.view/view)
|
||||
(def permission-context quo2.components.drawers.permission-context.view/view)
|
||||
|
||||
;;;; DROPDOWNS
|
||||
(def dropdown quo2.components.dropdowns.dropdown/dropdown)
|
||||
|
||||
;;;; EMPTY STATE
|
||||
(def empty-state quo2.components.empty-state.empty-state.view/empty-state)
|
||||
|
||||
;;;; HEADER
|
||||
(def header quo2.components.header/header)
|
||||
|
||||
;;;; ICON
|
||||
(def icon quo2.components.icon/icon)
|
||||
|
||||
;;;; INFO
|
||||
(def info-message quo2.components.info.info-message/info-message)
|
||||
(def information-box quo2.components.info.information-box.view/view)
|
||||
|
||||
;;;; INPUTS
|
||||
(def input quo2.components.inputs.input.view/input)
|
||||
(def profile-input quo2.components.inputs.profile-input.view/profile-input)
|
||||
@@ -207,8 +203,13 @@
|
||||
(def markdown-list quo2.components.markdown.list.view/view)
|
||||
(def text quo2.components.markdown.text/text)
|
||||
|
||||
;;;; MESSAGES
|
||||
(def gap quo2.components.messages.gap/gap)
|
||||
(def system-message quo2.components.messages.system-message/system-message)
|
||||
|
||||
;;;; 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)
|
||||
@@ -222,15 +223,27 @@
|
||||
(def profile-card quo2.components.profile.profile-card.view/profile-card)
|
||||
(def select-profile quo2.components.profile.select-profile.view/view)
|
||||
|
||||
;;;; REACTIONS
|
||||
(def reaction quo2.components.reactions.reaction/reaction)
|
||||
(def add-reaction quo2.components.reactions.reaction/add-reaction)
|
||||
|
||||
;;;; RECORD AUDIO
|
||||
(def record-audio quo2.components.record-audio.record-audio.view/record-audio)
|
||||
(def soundtrack quo2.components.record-audio.soundtrack.view/f-soundtrack)
|
||||
|
||||
;;;; SELECTORS
|
||||
(def author quo2.components.messages.author.view/author)
|
||||
(def disclaimer quo2.components.selectors.disclaimer.view/view)
|
||||
(def filter quo2.components.selectors.filter.view/view)
|
||||
(def reactions quo2.components.selectors.reactions.view/view)
|
||||
(def checkbox quo2.components.selectors.selectors.view/checkbox)
|
||||
|
||||
;;;; SETTINGS
|
||||
(def privacy-option quo2.components.settings.privacy-option/card)
|
||||
(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)
|
||||
@@ -247,6 +260,11 @@
|
||||
(def permission-tag quo2.components.tags.permission-tag/tag)
|
||||
(def status-tag quo2.components.tags.status-tags/status-tag)
|
||||
(def token-tag quo2.components.tags.token-tag/tag)
|
||||
(def user-avatar-tag quo2.components.tags.context-tag.view/user-avatar-tag)
|
||||
(def context-tag quo2.components.tags.context-tag.view/context-tag)
|
||||
(def group-avatar-tag quo2.components.tags.context-tag.view/group-avatar-tag)
|
||||
(def audio-tag quo2.components.tags.context-tag.view/audio-tag)
|
||||
(def community-tag quo2.components.tags.context-tag.view/community-tag)
|
||||
|
||||
;;;; TITLE
|
||||
(def title quo2.components.text-combinations.title.view/title)
|
||||
|
||||
@@ -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]))
|
||||
|
||||
@@ -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)}])
|
||||
@@ -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 %}))))
|
||||
|
||||
@@ -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)])
|
||||
@@ -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))})))
|
||||
|
||||
@@ -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})))
|
||||
|
||||
@@ -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]}
|
||||
|
||||
@@ -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? %])}]}))
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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))))
|
||||
|
||||
@@ -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]))))
|
||||
|
||||
@@ -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]}]
|
||||
|
||||
@@ -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.")))))))
|
||||
|
||||
@@ -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))))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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]
|
||||
|
||||
@@ -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)))
|
||||
|
||||
|
||||
@@ -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))))
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user