Compare commits

..
Author SHA1 Message Date
Volodymyr Kozieiev 09e922fd05 fx namespaces removed in favor of utils.re-frame 2022-12-16 15:03:55 +00:00
917 changed files with 33050 additions and 46555 deletions
+20 -23
View File
@@ -1,23 +1,20 @@
{:lint-as {status-im.utils.views/defview clojure.core/defn
status-im.utils.views/letsubs clojure.core/let
reagent.core/with-let clojure.core/let
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
quo.react/with-deps-check clojure.core/fn
quo.previews.preview/list-comp clojure.core/for
status-im.utils.styles/def clojure.core/def
status-im.utils.styles/defn clojure.core/defn
test-helpers.unit/deftest-sub clojure.core/defn
taoensso.tufte/defnp clojure.core/defn}
:linters {:consistent-alias {:level :error
:aliases {clojure.string string
clojure.set set
clojure.walk walk
taoensso.timbre log}}
: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
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
number
status-im.test-helpers/restore-app-db]}}
:config-in-ns {mocks.js-dependencies {:linters {:clojure-lsp/unused-public-var {:level :off}}}}}
{:lint-as {status-im.utils.views/defview clojure.core/defn
status-im.utils.views/letsubs clojure.core/let
reagent.core/with-let clojure.core/let
status-im.utils.fx/defn clj-kondo.lint-as/def-catch-all
utils.re-frame/defn clj-kondo.lint-as/def-catch-all
quo.react/with-deps-check clojure.core/fn
quo.previews.preview/list-comp clojure.core/for
status-im.utils.styles/def clojure.core/def
status-im.utils.styles/defn clojure.core/defn
status-im.test-helpers/deftest-sub clojure.core/defn
taoensso.tufte/defnp clojure.core/defn}
:linters {:consistent-alias {:level :error
:aliases {clojure.string string
taoensso.timbre log}}
: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
:unresolved-symbol {:exclude [PersistentPriorityMap.EMPTY
number
status-im.test-helpers/restore-app-db]}}}
-48
View File
@@ -1,48 +0,0 @@
;; -*- mode: clojure -*-
;; vi: ft=clojure
{:width 105
:style [;; community style
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#community
:community
;; no comma in map
:no-comma
:custom-justify
;; respect all newlines
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-nl
:respect-nl
;; respect blank line
;; https://github.com/kkinnear/zprint/blob/main/doc/reference.md#respect-bl
:respect-bl]
:fn-map
{"reg-sub" :arg1-pair
"h/describe" :arg1-body
"h/test" :arg1-body
"global.describe" :arg1-body
"global.test" :arg1-body
"list-comp" :binding
"defview" :arg1-body
"letsubs" :binding
"testing" :arg1-body
"deftest-sub" :arg1-body
"wait-for" :arg1-body
"with-deps-check" :arg1-body
"->" [:noarg1-body
{:list {:constant-pair? false :force-nl? false}
:next-inner-restore [[:list :constant-pair?]]}]
"set!" "reset!"
"assoc-when" "assoc"
"assoc-some" "assoc"
"conj-when" "conj"
"conj-some" "conj"}
:remove {:fn-force-nl #{:noarg1-body}}
:style-map
{:no-comma {:map {:comma? false}}
:custom-justify
{:doc "Justify everything using pre-1.1.2 approach"
:binding {:justify? true :justify {:max-variance 1000}}
:map {:justify? true :justify {:max-variance 1000}}
:pair {:justify? true :justify {:max-variance 1000}}}}}
+6 -17
View File
@@ -285,19 +285,16 @@ endif
# Tests
#--------------
lint: export TARGET := default
lint: export TARGET := clojure
lint: ##@test Run code style checks
sh scripts/lint-re-frame-in-quo-components.sh && \
clj-kondo --config .clj-kondo/config.edn --cache false --lint src && \
ALL_CLOJURE_FILE=$$(git ls-files | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn$$) && \
zprint '{:search-config? true}' -sfc $$ALL_CLOJURE_FILE
TARGETS=$$(git diff --diff-filter=d --cached --name-only src && echo src) && \
clojure -Scp "$$CLASS_PATH" -m cljfmt.main check --indents indentation.edn $$TARGETS
lint-fix: export TARGET := default
lint-fix: export TARGET := clojure
lint-fix: ##@test Run code style checks and fix issues
ALL_CLOJURE_FILE=$$(git ls-files | grep -e \.clj$$ -e \.cljs$$ -e \.cljc$$ -e \.edn$$) && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILE && \
zprint '{:search-config? true}' -sw $$ALL_CLOJURE_FILE
clojure -Scp "$$CLASS_PATH" -m cljfmt.main fix src --indents indentation.edn
shadow-server: export TARGET := clojure
shadow-server:##@ Start shadow-cljs in server mode for watching
@@ -308,14 +305,6 @@ test-watch: ##@ Watch tests and re-run no changes to cljs files
yarn install
nodemon --exec 'yarn shadow-cljs compile mocks && yarn shadow-cljs compile test && node --require ./test-resources/override.js target/test/test.js' -e cljs
test-watch-for-repl: export TARGET := clojure
test-watch-for-repl: ##@ Watch tests and support REPL connections
yarn install
rm -f target/test/test.js
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
'yarn shadow-cljs compile mocks && yarn shadow-cljs watch test --verbose' \
'until [ -f ./target/test/test.js ] ; do sleep 1 ; done ; node --require ./test-resources/override.js ./target/test/test.js --repl'
test: export TARGET := clojure
test: ##@test Run tests once in NodeJS
# Here we create the gyp bindings for nodejs
@@ -330,7 +319,7 @@ run-visual-test-ios: XCODE_DERIVED_DATA := $(HOME)/Library/Developer/Xcode/Deriv
run-visual-test-ios: APPLICATION_NAME := StatusIm-brfnruzfrkkycpbndmdoeyrigthc
run-visual-test-ios: export TEST_BINARY_PATH := $(XCODE_DERIVED_DATA)/$(APPLICATION_NAME)/Build/Products/Debug-iphonesimulator/StatusIm.app
run-visual-test-ios: ##@test Run tests once in NodeJS
detox test --configuration ios.sim.debug
detox test --configuration ios.sim.debug
component-test-watch: export TARGET := clojure
component-test-watch: export COMPONENT_TEST := true
@@ -20,8 +20,6 @@ printed out by mistake in a log entry (see https://github.com/status-im/status-m
To minimize the risk of leaking passwords through logs, we should not pass
passwords as strings in our codebase. We introduced a new type `MaskedData` in
`status-im.utils.security`.
update (16-Dec-2022) `status-im.utils.security` is now moved over to `utils.security.core`
We use `(security/mask-data <data to hide>` to wrap sensitive data into this
type and then use `(security/unmask <masked-data>)` to get the plaintext back.
+12 -28
View File
@@ -364,7 +364,7 @@ actually subscribing to them, so reframe's signal graph gets validated too.
(is (= expected (recipes [current-user all-recipes location]))))))
;; good
(require '[test-helpers.unit :as h])
(require '[status-im.test-helpers :as h])
(re-frame/reg-sub
:user/recipes
@@ -399,15 +399,13 @@ src
├── react_native
│ ├── gesture.cljs
│ └── platform.cljs
├── status_im/
├── status_im2
├── status_im
│ ├── common
│ │ └── components
│ │ └── bottom_sheet.cljs
│ ├── contexts/
│ ├── setup/
│ └── subs/
├── test_helpers/
└── utils.cljs
```
@@ -416,23 +414,17 @@ src
- `src/quo2/`: The component library for Status Mobile.
- `src/react_native/`: Contains only low-level constructs to help React Native
work in tandem with Clojure(Script).
- `src/status_im2/`: Directory where we try to be as strict as possible about
our guidelines and where we prefer to write code for the new, redesigned
mobile app.
- `src/status_im/`: Directory containing what we call "old code", not yet
migrated to new guidelines for the new mobile app.
- `src/status_im2/common/`: Directories named `common` can appear at any level
of the directory tree. Just like directories named `utils`, their directory
- `src/status_im/common/`: Directories named `common` can appear at any level of
the directory tree. Just like directories named `utils`, their directory
nesting level communicates their applicable limits.
- `src/status_im2/common/components/`: Contains reusable components that are not
- `src/status_im/common/components/`: Contains reusable components that are not
part of the design system (quo2).
- `src/status_im2/contexts/`: Contains [bounded contexts](#glossary), like
- `src/status_im/contexts/`: Contains [bounded contexts](#glossary), like
`browser/`, `messaging/`, etc. As much as possible, _bounded contexts_ should
not directly require each other's namespaces.
- `src/status_im2/setup/`: Contains namespaces that are mostly used to
initialize the application, configure test runners, etc. In general, such
namespaces should not be required from the outside.
- `src/test_helpers/`: Reusable utilities for writing all kinds of tests.
- `src/status_im/setup/`: Contains namespaces that are mostly used to initialize
the application, configure test runners, etc. In general, such namespaces
should not be required from the outside.
- `src/status_im/subs/`: All subscriptions should live inside it.
Directories named `utils/` can appear at any level of the directory tree. The
@@ -493,26 +485,18 @@ src
[Unit tests](#glossary) should be created alongside their respective source
implementation. We prefer them colocated with the source and not like most
Clojure (JVM) codebases which mirror the sources in a top-level test directory.
Component tests should be created in a separate directory `__tests__`. Example:
```
├── models
│ ├── message.cljs
│ └── message_test.cljs
├── __tests__
│ └── input_bla_test.cljs
├── models.cljs
└── models_test.cljs
```
Component tests should be created in a separate directory `__tests__`, colocated
with the source. When the entire component implementation is isolated under a
single directory, create a test file named `component_spec.cljs` instead.
```
└── filter
├── component_spec.cljs
├── style.cljs
└── view.cljs
```
There's no hard rule on how integration test namespaces should be split, but
we're at least striving to define them under appropriate bounded contexts that
mirror the source code.
+1
View File
@@ -0,0 +1 @@
{letsubs [[:inner 0]]}
@@ -19,11 +19,6 @@ def getStatusGoSHA1 = { ->
android {
compileSdkVersion rootProject.ext.compileSdkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
@@ -59,12 +59,8 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.function.Function;
import java.util.function.Supplier;
import java.util.Map;
import java.util.Stack;
import java.util.zip.ZipEntry;
@@ -531,33 +527,45 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
StatusThreadPoolExecutor.getInstance().execute(r);
}
private void executeRunnableStatusGoMethod(Supplier<String> method, Callback callback) throws JSONException {
@ReactMethod
public void verify(final String address, final String password, final Callback callback) {
Log.d(TAG, "verify");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable runnableTask = () -> {
String res = method.get();
callback.invoke(res);
};
StatusThreadPoolExecutor.getInstance().execute(runnableTask);
}
@ReactMethod
public void verify(final String address, final String password, final Callback callback) throws JSONException {
Activity currentActivity = getCurrentActivity();
final String absRootDirPath = this.getNoBackupDirectory();
final String newKeystoreDir = pathCombine(absRootDirPath, "keystore");
executeRunnableStatusGoMethod(() -> Statusgo.verifyAccountPassword(newKeystoreDir, address, password), callback);
Runnable r = new Runnable() {
@Override
public void run() {
String result = Statusgo.verifyAccountPassword(newKeystoreDir, address, password);
callback.invoke(result);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void verifyDatabasePassword(final String keyUID, final String password, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.verifyDatabasePassword(keyUID, password), callback);
public void verifyDatabasePassword(final String keyUID, final String password, final Callback callback) {
Log.d(TAG, "verifyDatabasePassword");
Runnable r = new Runnable() {
@Override
public void run() {
String result = Statusgo.verifyDatabasePassword(keyUID, password);
callback.invoke(result);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
public String getKeyStorePath(String keyUID) {
@@ -727,59 +735,209 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void addPeer(final String enode, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.addPeer(enode), callback);
public void addPeer(final String enode, final Callback callback) {
Log.d(TAG, "addPeer");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.addPeer(enode);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountStoreAccount(final String json, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.multiAccountStoreAccount(json), callback);
public void multiAccountStoreAccount(final String json, final Callback callback) {
Log.d(TAG, "multiAccountStoreAccount");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiAccountStoreAccount(json);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountLoadAccount(final String json, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.multiAccountLoadAccount(json), callback);
public void multiAccountLoadAccount(final String json, final Callback callback) {
Log.d(TAG, "multiAccountLoadAccount");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiAccountLoadAccount(json);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountReset(final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.multiAccountReset(), callback);
public void multiAccountReset(final Callback callback) {
Log.d(TAG, "multiAccountReset");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiAccountReset();
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountDeriveAddresses(final String json, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.multiAccountDeriveAddresses(json), callback);
public void multiAccountDeriveAddresses(final String json, final Callback callback) {
Log.d(TAG, "multiAccountDeriveAddresses");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiAccountDeriveAddresses(json);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountGenerateAndDeriveAddresses(final String json, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.multiAccountGenerateAndDeriveAddresses(json), callback);
public void multiAccountGenerateAndDeriveAddresses(final String json, final Callback callback) {
Log.d(TAG, "multiAccountGenerateAndDeriveAddresses");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiAccountGenerateAndDeriveAddresses(json);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountStoreDerived(final String json, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.multiAccountStoreDerivedAccounts(json), callback);
public void multiAccountStoreDerived(final String json, final Callback callback) {
Log.d(TAG, "multiAccountStoreDerived");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiAccountStoreDerivedAccounts(json);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountImportMnemonic(final String json, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.multiAccountImportMnemonic(json), callback);
public void multiAccountImportMnemonic(final String json, final Callback callback) {
Log.d(TAG, "multiAccountImportMnemonic");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiAccountImportMnemonic(json);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void multiAccountImportPrivateKey(final String json, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.multiAccountImportPrivateKey(json), callback);
public void multiAccountImportPrivateKey(final String json, final Callback callback) {
Log.d(TAG, "multiAccountImportPrivateKey");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiAccountImportPrivateKey(json);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void hashTransaction(final String txArgsJSON, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.hashTransaction(txArgsJSON), callback);
public void hashTransaction(final String txArgsJSON, final Callback callback) {
Log.d(TAG, "hashTransaction");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.hashTransaction(txArgsJSON);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void hashMessage(final String message, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.hashMessage(message), callback);
public void hashMessage(final String message, final Callback callback) {
Log.d(TAG, "hashMessage");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.hashMessage(message);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
@@ -789,7 +947,20 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
final String keyStorePath = this.getKeyStorePath(keyUID);
jsonConfig.put("keystorePath", keyStorePath);
executeRunnableStatusGoMethod(() -> Statusgo.getConnectionStringForBootstrappingAnotherDevice(jsonConfig.toString()), callback);
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable runnableTask = new Runnable() {
@Override
public void run() {
String res = Statusgo.getConnectionStringForBootstrappingAnotherDevice(jsonConfig.toString());
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(runnableTask);
}
@ReactMethod
@@ -798,11 +969,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
final String keyStorePath = pathCombine(this.getNoBackupDirectory(), "/keystore");
jsonConfig.put("keystorePath", keyStorePath);
executeRunnableStatusGoMethod(() -> Statusgo.inputConnectionStringForBootstrapping(connectionString, jsonConfig.toString()), callback);
}
@ReactMethod
public void multiformatSerializePublicKey(final String multiCodecKey, final String base58btc, final Callback callback) throws JSONException {
if (!checkAvailability()) {
callback.invoke(false);
return;
@@ -811,7 +977,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
Runnable runnableTask = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiformatSerializePublicKey(multiCodecKey,base58btc);
String res = Statusgo.inputConnectionStringForBootstrapping(connectionString,jsonConfig.toString());
callback.invoke(res);
}
};
@@ -819,117 +985,157 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
StatusThreadPoolExecutor.getInstance().execute(runnableTask);
}
@ReactMethod
public void multiformatDeserializePublicKey(final String multiCodecKey, final String base58btc, final Callback callback) throws JSONException {
public void hashTypedData(final String data, final Callback callback) {
Log.d(TAG, "hashTypedData");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable runnableTask = new Runnable() {
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.multiformatDeserializePublicKey(multiCodecKey,base58btc);
String res = Statusgo.hashTypedData(data);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(runnableTask);
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void compressPublicKey(final String multiCodecKey, final Callback callback) throws JSONException {
public void hashTypedDataV4(final String data, final Callback callback) {
Log.d(TAG, "hashTypedDataV4");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable runnableTask = new Runnable() {
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.compressPublicKey(multiCodecKey);
String res = Statusgo.hashTypedDataV4(data);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(runnableTask);
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void decompressPublicKey(final String multiCodecKey, final Callback callback) throws JSONException {
public void sendTransactionWithSignature(final String txArgsJSON, final String signature, final Callback callback) {
Log.d(TAG, "sendTransactionWithSignature");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable runnableTask = new Runnable() {
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.decompressPublicKey(multiCodecKey);
String res = Statusgo.sendTransactionWithSignature(txArgsJSON, signature);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(runnableTask);
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void deserializeAndCompressKey(final String desktopKey, final Callback callback) throws JSONException {
public void sendTransaction(final String txArgsJSON, final String password, final Callback callback) {
Log.d(TAG, "sendTransaction");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable runnableTask = new Runnable() {
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.deserializeAndCompressKey(desktopKey);
String res = Statusgo.sendTransaction(txArgsJSON, password);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(runnableTask);
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void hashTypedData(final String data, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.hashTypedData(data), callback);
public void signMessage(final String rpcParams, final Callback callback) {
Log.d(TAG, "signMessage");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.signMessage(rpcParams);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void hashTypedDataV4(final String data, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.hashTypedDataV4(data), callback);
public void recover(final String rpcParams, final Callback callback) {
Log.d(TAG, "recover");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.recover(rpcParams);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void sendTransactionWithSignature(final String txArgsJSON, final String signature, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.sendTransactionWithSignature(txArgsJSON, signature), callback);
public void signTypedData(final String data, final String account, final String password, final Callback callback) {
Log.d(TAG, "signTypedData");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.signTypedData(data, account, password);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void sendTransaction(final String txArgsJSON, final String password, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.sendTransaction(txArgsJSON, password), callback);
}
public void signTypedDataV4(final String data, final String account, final String password, final Callback callback) {
Log.d(TAG, "signTypedDataV4");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
@ReactMethod
public void signMessage(final String rpcParams, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.signMessage(rpcParams), callback);
}
@ReactMethod
public void recover(final String rpcParams, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.recover(rpcParams), callback);
}
@ReactMethod
public void signTypedData(final String data, final String account, final String password, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.signTypedData(data, account, password), callback);
}
@ReactMethod
public void signTypedDataV4(final String data, final String account, final String password, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.signTypedDataV4(data, account, password), callback);
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.signTypedDataV4(data, account, password);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
@@ -1034,13 +1240,29 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void callRPC(final String payload, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.callRPC(payload), callback);
public void callRPC(final String payload, final Callback callback) {
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.callRPC(payload);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void callPrivateRPC(final String payload, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.callPrivateRPC(payload), callback);
public void callPrivateRPC(final String payload, final Callback callback) {
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.callPrivateRPC(payload);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
@@ -1103,30 +1325,105 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void extractGroupMembershipSignatures(final String signaturePairs, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.extractGroupMembershipSignatures(signaturePairs), callback);
public void extractGroupMembershipSignatures(final String signaturePairs, final Callback callback) {
Log.d(TAG, "extractGroupMembershipSignatures");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String result = Statusgo.extractGroupMembershipSignatures(signaturePairs);
callback.invoke(result);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void signGroupMembership(final String content, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.signGroupMembership(content), callback);
public void signGroupMembership(final String content, final Callback callback) {
Log.d(TAG, "signGroupMembership");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String result = Statusgo.signGroupMembership(content);
callback.invoke(result);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void getNodeConfig(final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.getNodeConfig(), callback);
public void getNodeConfig(final Callback callback) {
Log.d(TAG, "getNodeConfig");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String result = Statusgo.getNodeConfig();
callback.invoke(result);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void deleteMultiaccount(final String keyUID, final Callback callback) throws JSONException {
public void deleteMultiaccount(final String keyUID, final Callback callback) {
Log.d(TAG, "deleteMultiaccount");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
final String keyStoreDir = this.getKeyStorePath(keyUID);
executeRunnableStatusGoMethod(() -> Statusgo.deleteMultiaccount(keyUID, keyStoreDir), callback);
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.deleteMultiaccount(keyUID, keyStoreDir);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void deleteImportedKey(final String keyUID, final String address, final String password, final Callback callback) throws JSONException {
public void deleteImportedKey(final String keyUID, final String address, final String password, final Callback callback) {
Log.d(TAG, "deleteImportedKey");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
final String keyStoreDir = this.getKeyStorePath(keyUID);
executeRunnableStatusGoMethod(() -> Statusgo.deleteImportedKey(address, password, keyStoreDir), callback);
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.deleteImportedKey(address, password, keyStoreDir);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod(isBlockingSynchronousMethod = true)
@@ -1135,8 +1432,24 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void generateAliasAsync(final String seed, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.generateAlias(seed), callback);
public void generateAliasAsync(final String seed, final Callback callback) {
Log.d(TAG, "generateAliasAsync");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.generateAlias(seed);
Log.d(TAG, res);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod(isBlockingSynchronousMethod = true)
@@ -1200,33 +1513,47 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void identiconAsync(final String seed, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.identicon(seed), callback);
public void identiconAsync(final String seed, final Callback callback) {
Log.d(TAG, "identiconAsync");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String res = Statusgo.identicon(seed);
Log.d(TAG, res);
callback.invoke(res);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void generateAliasAndIdenticonAsync(final String seed, final Callback callback) {
Log.d(TAG, "generateAliasAndIdenticonAsync");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Log.d(TAG, "generateAliasAndIdenticonAsync");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String resIdenticon = Statusgo.identicon(seed);
String resAlias = Statusgo.generateAlias(seed);
Runnable r = new Runnable() {
@Override
public void run() {
String resIdenticon = Statusgo.identicon(seed);
String resAlias = Statusgo.generateAlias(seed);
Log.d(TAG, resIdenticon);
Log.d(TAG, resAlias);
callback.invoke(resAlias, resIdenticon);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
Log.d(TAG, resIdenticon);
Log.d(TAG, resAlias);
callback.invoke(resAlias, resIdenticon);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@Override
@@ -1248,8 +1575,24 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void validateMnemonic(final String seed, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.validateMnemonic(seed), callback);
public void validateMnemonic(final String seed, final Callback callback) {
Log.d(TAG, "validateMnemonic");
if (!checkAvailability()) {
callback.invoke(false);
return;
}
Runnable r = new Runnable() {
@Override
public void run() {
String resValidateMnemonic = Statusgo.validateMnemonic(seed);
Log.d(TAG, resValidateMnemonic);
callback.invoke(resValidateMnemonic);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
@@ -1300,14 +1643,35 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void reEncryptDbAndKeystore(final String keyUID, final String password, final String newPassword, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.changeDatabasePassword(keyUID, password, newPassword), callback);
public void reEncryptDbAndKeystore(final String keyUID, final String password, final String newPassword, final Callback callback) {
Log.d(TAG, "reEncryptDbAndKeyStore");
Runnable r = new Runnable() {
@Override
public void run() {
// changes db password and re-encrypts keystore
String result = Statusgo.changeDatabasePassword(keyUID, password, newPassword);
callback.invoke(result);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void convertToKeycardAccount(final String keyUID, final String accountData, final String options, final String password, final String newPassword, final Callback callback) throws JSONException {
public void convertToKeycardAccount(final String keyUID, final String accountData, final String options, final String password, final String newPassword, final Callback callback) {
Log.d(TAG, "convertToKeycardAccount");
final String keyStoreDir = this.getKeyStorePath(keyUID);
executeRunnableStatusGoMethod(() -> Statusgo.convertToKeycardAccount(keyStoreDir, accountData, options, password, newPassword), callback);
Runnable r = new Runnable() {
@Override
public void run() {
String result = Statusgo.convertToKeycardAccount(keyStoreDir, accountData, options, password, newPassword);
callback.invoke(result);
}
};
StatusThreadPoolExecutor.getInstance().execute(r);
}
}
@@ -90,25 +90,26 @@ static RCTBridge *bridge;
RCT_EXPORT_MODULE();
////////////////////////////////////////////////////////////////////
#pragma mark - shouldMoveToInternalStorage
//////////////////////////////////////////////////////////////////// shouldMoveToInternalStorage
RCT_EXPORT_METHOD(shouldMoveToInternalStorage:(RCTResponseSenderBlock)onResultCallback) {
// Android only
onResultCallback(@[[NSNull null]]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - moveToInternalStorage
//////////////////////////////////////////////////////////////////// moveToInternalStorage
RCT_EXPORT_METHOD(moveToInternalStorage:(RCTResponseSenderBlock)onResultCallback) {
// Android only
onResultCallback(@[[NSNull null]]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - InitKeystore method
//////////////////////////////////////////////////////////////////// StopNode
RCT_EXPORT_METHOD(initKeystore:(NSString *)keyUID
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -131,9 +132,9 @@ RCT_EXPORT_METHOD(initKeystore:(NSString *)keyUID
});
}
////////////////////////////////////////////////////////////////////
#pragma mark - SendLogs method
//////////////////////////////////////////////////////////////////// sendLogs
RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
jsLogs:(NSString *)jsLogs
callback:(RCTResponseSenderBlock)callback) {
@@ -195,6 +196,7 @@ RCT_EXPORT_METHOD(sendLogs:(NSString *)dbJson
callback(@[zipFile.absoluteString]);
}
//////////////////////////////////////////////////////////////////// addPeer
RCT_EXPORT_METHOD(exportLogs:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"exportLogs() method called");
@@ -203,6 +205,7 @@ RCT_EXPORT_METHOD(exportLogs:(RCTResponseSenderBlock)callback) {
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// addPeer
RCT_EXPORT_METHOD(addPeer:(NSString *)enode
callback:(RCTResponseSenderBlock)callback) {
NSString *result = StatusgoAddPeer(enode);
@@ -212,6 +215,7 @@ RCT_EXPORT_METHOD(addPeer:(NSString *)enode
#endif
}
//////////////////////////////////////////////////////////////////// multiAccountImportPrivateKey
RCT_EXPORT_METHOD(deleteMultiaccount:(NSString *)keyUID
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -222,6 +226,7 @@ RCT_EXPORT_METHOD(deleteMultiaccount:(NSString *)keyUID
callback(@[result]);
}
////////////////////////////////////verify//////////////////////////////// multiAccountImportPrivateKey
RCT_EXPORT_METHOD(deleteImportedKey:(NSString *)keyUID
address:(NSString *)address
password:(NSString *)password
@@ -234,6 +239,7 @@ RCT_EXPORT_METHOD(deleteImportedKey:(NSString *)keyUID
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// multiAccountGenerateAndDeriveAddresses
RCT_EXPORT_METHOD(multiAccountGenerateAndDeriveAddresses:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -243,6 +249,7 @@ RCT_EXPORT_METHOD(multiAccountGenerateAndDeriveAddresses:(NSString *)json
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// MultiAccountStoreAccount
RCT_EXPORT_METHOD(multiAccountStoreAccount:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -252,6 +259,7 @@ RCT_EXPORT_METHOD(multiAccountStoreAccount:(NSString *)json
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// MultiAccountLoadAccount
RCT_EXPORT_METHOD(multiAccountLoadAccount:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -261,6 +269,7 @@ RCT_EXPORT_METHOD(multiAccountLoadAccount:(NSString *)json
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// MultiAccountReset
RCT_EXPORT_METHOD(multiAccountReset:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"MultiAccountReset() method called");
@@ -269,6 +278,7 @@ RCT_EXPORT_METHOD(multiAccountReset:(RCTResponseSenderBlock)callback) {
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// multiAccountStoreDerived
RCT_EXPORT_METHOD(multiAccountStoreDerived:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -278,6 +288,7 @@ RCT_EXPORT_METHOD(multiAccountStoreDerived:(NSString *)json
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// multiAccountImportPrivateKey
RCT_EXPORT_METHOD(multiAccountImportPrivateKey:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -287,6 +298,7 @@ RCT_EXPORT_METHOD(multiAccountImportPrivateKey:(NSString *)json
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// hashTransaction
RCT_EXPORT_METHOD(hashTransaction:(NSString *)txArgsJSON
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -296,6 +308,7 @@ RCT_EXPORT_METHOD(hashTransaction:(NSString *)txArgsJSON
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// hashMessage
RCT_EXPORT_METHOD(hashMessage:(NSString *)message
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -305,6 +318,7 @@ RCT_EXPORT_METHOD(hashMessage:(NSString *)message
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// getConnectionStringForBootstrappingAnotherDevice
RCT_EXPORT_METHOD(getConnectionStringForBootstrappingAnotherDevice:(NSString *)configJSON
callback:(RCTResponseSenderBlock)callback) {
@@ -321,6 +335,7 @@ RCT_EXPORT_METHOD(getConnectionStringForBootstrappingAnotherDevice:(NSString *)c
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// inputConnectionStringForBootstrapping
RCT_EXPORT_METHOD(inputConnectionStringForBootstrapping:(NSString *)cs
configJSON:(NSString *)configJSON
callback:(RCTResponseSenderBlock)callback) {
@@ -339,38 +354,7 @@ RCT_EXPORT_METHOD(inputConnectionStringForBootstrapping:(NSString *)cs
callback(@[result]);
}
RCT_EXPORT_METHOD(multiformatSerializePublicKey:(NSString *)multiCodecKey
base58btc:(NSString *)base58btc
callback:(RCTResponseSenderBlock)callback) {
NSString *result = StatusgoMultiformatSerializePublicKey(multiCodecKey,base58btc);
callback(@[result]);
}
RCT_EXPORT_METHOD(multiformatDeserializePublicKey:(NSString *)multiCodecKey
base58btc:(NSString *)base58btc
callback:(RCTResponseSenderBlock)callback) {
NSString *result = StatusgoMultiformatDeserializePublicKey(multiCodecKey,base58btc);
callback(@[result]);
}
RCT_EXPORT_METHOD(decompressPublicKey:(NSString *)multiCodecKey
callback:(RCTResponseSenderBlock)callback) {
NSString *result = StatusgoDecompressPublicKey(multiCodecKey);
callback(@[result]);
}
RCT_EXPORT_METHOD(compressPublicKey:(NSString *)multiCodecKey
callback:(RCTResponseSenderBlock)callback) {
NSString *result = StatusgoCompressPublicKey(multiCodecKey);
callback(@[result]);
}
RCT_EXPORT_METHOD(deserializeAndCompressKey:(NSString *)desktopKey
callback:(RCTResponseSenderBlock)callback) {
NSString *result = StatusgoDeserializeAndCompressKey(desktopKey);
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// hashTypedData
RCT_EXPORT_METHOD(hashTypedData:(NSString *)data
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -380,6 +364,7 @@ RCT_EXPORT_METHOD(hashTypedData:(NSString *)data
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// hashTypedDataV4
RCT_EXPORT_METHOD(hashTypedDataV4:(NSString *)data
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -389,6 +374,7 @@ RCT_EXPORT_METHOD(hashTypedDataV4:(NSString *)data
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// sendTransactionWithSignature
RCT_EXPORT_METHOD(sendTransactionWithSignature:(NSString *)txArgsJSON
signature:(NSString *)signature
callback:(RCTResponseSenderBlock)callback) {
@@ -399,6 +385,7 @@ RCT_EXPORT_METHOD(sendTransactionWithSignature:(NSString *)txArgsJSON
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// multiAccountImportMnemonic
RCT_EXPORT_METHOD(multiAccountImportMnemonic:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -408,6 +395,7 @@ RCT_EXPORT_METHOD(multiAccountImportMnemonic:(NSString *)json
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// multiAccountDeriveAddresses
RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -427,6 +415,7 @@ RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
return [json valueForKey:@"key-uid"];
}
//////////////////////////////////////////////////////////////////// prepareDirAndUpdateConfig
-(NSString *) prepareDirAndUpdateConfig:(NSString *)config
withKeyUID:(NSString *)keyUID {
NSFileManager *fileManager = [NSFileManager defaultManager];
@@ -499,6 +488,7 @@ RCT_EXPORT_METHOD(multiAccountDeriveAddresses:(NSString *)json
}
//////////////////////////////////////////////////////////////////// prepareDirAndUpdateConfig
RCT_EXPORT_METHOD(prepareDirAndUpdateConfig:(NSString *)keyUID
config:(NSString *)config
callback:(RCTResponseSenderBlock)callback) {
@@ -510,6 +500,7 @@ RCT_EXPORT_METHOD(prepareDirAndUpdateConfig:(NSString *)keyUID
callback(@[updatedConfig]);
}
//////////////////////////////////////////////////////////////////// saveAccountAndLogin
RCT_EXPORT_METHOD(saveAccountAndLogin:(NSString *)multiaccountData
password:(NSString *)password
settings:(NSString *)settings
@@ -526,6 +517,7 @@ RCT_EXPORT_METHOD(saveAccountAndLogin:(NSString *)multiaccountData
NSLog(@"%@", result);
}
//////////////////////////////////////////////////////////////////// saveAccountAndLoginWithKeycard
RCT_EXPORT_METHOD(saveAccountAndLoginWithKeycard:(NSString *)multiaccountData
password:(NSString *)password
settings:(NSString *)settings
@@ -587,6 +579,7 @@ RCT_EXPORT_METHOD(saveAccountAndLoginWithKeycard:(NSString *)multiaccountData
}
}
//////////////////////////////////////////////////////////////////// login
RCT_EXPORT_METHOD(login:(NSString *)accountData
password:(NSString *)password) {
#if DEBUG
@@ -598,6 +591,7 @@ RCT_EXPORT_METHOD(login:(NSString *)accountData
NSLog(@"%@", result);
}
//////////////////////////////////////////////////////////////////// loginWithConfig
RCT_EXPORT_METHOD(loginWithConfig:(NSString *)accountData
password:(NSString *)password
configJSON:(NSString *)configJSON) {
@@ -610,6 +604,7 @@ RCT_EXPORT_METHOD(loginWithConfig:(NSString *)accountData
NSLog(@"%@", result);
}
//////////////////////////////////////////////////////////////////// loginWithKeycard
RCT_EXPORT_METHOD(loginWithKeycard:(NSString *)accountData
password:(NSString *)password
chatKey:(NSString *)chatKey) {
@@ -624,6 +619,7 @@ RCT_EXPORT_METHOD(loginWithKeycard:(NSString *)accountData
NSLog(@"%@", result);
}
//////////////////////////////////////////////////////////////////// logout
RCT_EXPORT_METHOD(logout) {
#if DEBUG
NSLog(@"Logout() method called");
@@ -633,6 +629,7 @@ RCT_EXPORT_METHOD(logout) {
NSLog(@"%@", result);
}
//////////////////////////////////////////////////////////////////// openAccounts
RCT_EXPORT_METHOD(openAccounts:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"OpenAccounts() method called");
@@ -646,6 +643,7 @@ RCT_EXPORT_METHOD(openAccounts:(RCTResponseSenderBlock)callback) {
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// verityAccountPassword
RCT_EXPORT_METHOD(verify:(NSString *)address
password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) {
@@ -662,6 +660,7 @@ RCT_EXPORT_METHOD(verify:(NSString *)address
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// verifyDatabasePassword
RCT_EXPORT_METHOD(verifyDatabasePassword:(NSString *)keyUID
password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) {
@@ -672,6 +671,7 @@ RCT_EXPORT_METHOD(verifyDatabasePassword:(NSString *)keyUID
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// changeDatabasePassword
RCT_EXPORT_METHOD(reEncryptDbAndKeystore:(NSString *)keyUID
currentPassword:(NSString *)currentPassword
newPassword:(NSString *)newPassword
@@ -684,6 +684,7 @@ RCT_EXPORT_METHOD(reEncryptDbAndKeystore:(NSString *)keyUID
callback(@[result]);
}
//////////////////////////////////////////////////////////////////// convertToKeycardAccount
RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
accountData:(NSString *)accountData
settings:(NSString *)settings
@@ -698,9 +699,9 @@ RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - SendTransaction
//////////////////////////////////////////////////////////////////// sendTransaction
RCT_EXPORT_METHOD(sendTransaction:(NSString *)txArgsJSON
password:(NSString *)password
callback:(RCTResponseSenderBlock)callback) {
@@ -711,9 +712,9 @@ RCT_EXPORT_METHOD(sendTransaction:(NSString *)txArgsJSON
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - SignMessage
//////////////////////////////////////////////////////////////////// signMessage
RCT_EXPORT_METHOD(signMessage:(NSString *)message
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -723,9 +724,9 @@ RCT_EXPORT_METHOD(signMessage:(NSString *)message
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - Recover
//////////////////////////////////////////////////////////////////// recover
RCT_EXPORT_METHOD(recover:(NSString *)message
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -735,9 +736,9 @@ RCT_EXPORT_METHOD(recover:(NSString *)message
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - SignTypedData
//////////////////////////////////////////////////////////////////// signTypedData
RCT_EXPORT_METHOD(signTypedData:(NSString *)data
account:(NSString *)account
password:(NSString *)password
@@ -749,9 +750,9 @@ RCT_EXPORT_METHOD(signTypedData:(NSString *)data
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - SignTypedDataV4
//////////////////////////////////////////////////////////////////// signTypedDataV4
RCT_EXPORT_METHOD(signTypedDataV4:(NSString *)data
account:(NSString *)account
password:(NSString *)password
@@ -763,9 +764,9 @@ RCT_EXPORT_METHOD(signTypedDataV4:(NSString *)data
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - SignGroupMembership
//////////////////////////////////////////////////////////////////// signGroupMembership
RCT_EXPORT_METHOD(signGroupMembership:(NSString *)content
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -775,9 +776,9 @@ RCT_EXPORT_METHOD(signGroupMembership:(NSString *)content
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - ExtractGroupMembershipSignatures
//////////////////////////////////////////////////////////////////// extractGroupMembershipSignatures
RCT_EXPORT_METHOD(extractGroupMembershipSignatures:(NSString *)content
callback:(RCTResponseSenderBlock)callback) {
#if DEBUG
@@ -787,9 +788,9 @@ RCT_EXPORT_METHOD(extractGroupMembershipSignatures:(NSString *)content
callback(@[result]);
}
////////////////////////////////////////////////////////////////////
#pragma mark - GetNodeConfig
//////////////////////////////////////////////////////////////////// getNodeConfig
RCT_EXPORT_METHOD(getNodeConfig:(RCTResponseSenderBlock)callback) {
#if DEBUG
NSLog(@"GetNodeConfig() method called");
@@ -799,9 +800,9 @@ RCT_EXPORT_METHOD(getNodeConfig:(RCTResponseSenderBlock)callback) {
}
////////////////////////////////////////////////////////////////////
#pragma mark - only android methods
////////////////////////////////////////////////////////////////////
RCT_EXPORT_METHOD(setAdjustResize) {
#if DEBUG
NSLog(@"setAdjustResize() works only on Android");
@@ -1030,7 +1031,7 @@ RCT_EXPORT_METHOD(deactivateKeepAwake)
});
}
#pragma mark - deviceinfo
//// deviceinfo
- (bool) is24Hour
{
+181 -259
View File
@@ -51,45 +51,6 @@
}
},
{
"path": "borkdude/edamame/0.0.11-alpha.28/edamame-0.0.11-alpha.28",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "488f403591739aab5a68ce6e7f82c0e855c23fd6",
"sha256": "1cw712kzza733g55s02ql35q630zd8j8nmnpivcczjkg240jans4"
},
"jar": {
"sha1": "371f3e232e7fdb04b7b2044825eb9822280e8f93",
"sha256": "1iyxq6jypjd875cgdyllknh27mx5fnkyjz80mr927d5i94r0ywj4"
}
},
{
"path": "borkdude/sci.impl.reflector/0.0.1/sci.impl.reflector-0.0.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "eb3aff6c7db85d91f7e05b98e06d1354a4fce36c",
"sha256": "1bvr7cvpbvqi7swypzpbfrig16zipwvmg4m47y2x5chs5czwxv15"
},
"jar": {
"sha1": "33dfc86102e0ea400498cbca47572459c1c43b00",
"sha256": "0a5gxmj8kzc01y9bn7l4x7c1v5q9wcbvw5hdr525d3ylsyl6xfkw"
}
},
{
"path": "borkdude/sci/0.2.1-alpha.1/sci-0.2.1-alpha.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "516cb8e3a8e430d59d9c3e7a51f9f859e3b249e0",
"sha256": "1nrww29m90q1avaahw7i5418c18crc3cidhbg3ml7h7vjjplsl9y"
},
"jar": {
"sha1": "96e39dcbc3fb3a41c6bf2e628303cf0f534b28a3",
"sha256": "1cjvz85ls982rmx90igv4mcfaa53fj5z29df9mf4jplyig3l9dxb"
}
},
{
"path": "cider/cider-nrepl/0.25.3/cider-nrepl-0.25.3",
"host": "https://repo.clojars.org",
@@ -117,15 +78,15 @@
},
{
"path": "clj-stacktrace/clj-stacktrace/0.2.8/clj-stacktrace-0.2.8",
"path": "cljfmt/cljfmt/0.6.7/cljfmt-0.6.7",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "c5a47e6858344c9fd42eecafc7920a7a18d6126d",
"sha256": "1az0fs9k5xvzl8bz564apd77kqc83nl8sxsrvmswmbmkamvy4hd3"
"sha1": "3d7ac9112908c9c9349adc056d1d06ae2cd33c21",
"sha256": "1q46q43mykn61f032y5734j84gcjca41pwd3iik9xghnzmphy2mn"
},
"jar": {
"sha1": "b0654b98763199ee57182526465d823492d1cc3f",
"sha256": "1029wd82qyxv6ji9pd38m32nqia56h6845lqv4ym4dsz5i201g9a"
"sha1": "91e8afa2c19db72acdef7f881aad905871ba6e69",
"sha256": "0ara83gaqnafjgr2aqz5zqmywdsmhsz483xkkxpiwbn9lfqvidmh"
}
},
@@ -143,15 +104,15 @@
},
{
"path": "cljsjs/react-dom-server/17.0.1-0/react-dom-server-17.0.1-0",
"path": "cljsjs/react/17.0.1-0/react-17.0.1-0",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "ff154f318e1f63061b5bd42d9a38fc8547360cb4",
"sha256": "166ynlrph7rx3nql0c85c37vcbcsnwbjamk71hw74rz451pgnncr"
"sha1": "d5d3681281585d981375fe7bb29362bfcd0d4449",
"sha256": "0rskh6mfq5h0l0wybs68w9v585a6zlnnfgrvsf5k3h51fk2p28da"
},
"jar": {
"sha1": "d5c53eca9f3884402c76268b82e3828223dcbf90",
"sha256": "1530hwqpxzxfjm6dy77whqwjzzx79jpnd9xvnkxy1lnk7l7lj494"
"sha1": "726da8a9305a865df90d81e9a8d58f87ff0ee8bd",
"sha256": "0bfmvw8gk98vdf9azll6041r1jaz1pmb0dyb35cfc8dr3mmr4ag7"
}
},
@@ -169,15 +130,15 @@
},
{
"path": "cljsjs/react/17.0.1-0/react-17.0.1-0",
"path": "cljsjs/react-dom-server/17.0.1-0/react-dom-server-17.0.1-0",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "d5d3681281585d981375fe7bb29362bfcd0d4449",
"sha256": "0rskh6mfq5h0l0wybs68w9v585a6zlnnfgrvsf5k3h51fk2p28da"
"sha1": "ff154f318e1f63061b5bd42d9a38fc8547360cb4",
"sha256": "166ynlrph7rx3nql0c85c37vcbcsnwbjamk71hw74rz451pgnncr"
},
"jar": {
"sha1": "726da8a9305a865df90d81e9a8d58f87ff0ee8bd",
"sha256": "0bfmvw8gk98vdf9azll6041r1jaz1pmb0dyb35cfc8dr3mmr4ag7"
"sha1": "d5c53eca9f3884402c76268b82e3828223dcbf90",
"sha256": "1530hwqpxzxfjm6dy77whqwjzzx79jpnd9xvnkxy1lnk7l7lj494"
}
},
@@ -311,6 +272,32 @@
}
},
{
"path": "com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "7d5e372ff32c90095800f96d8308c41af0285a41",
"sha256": "1dj7p0m0kwnjvy1y3kq63zb6bw0azjf79i5xbccmy3wv63b1vqrg"
},
"jar": {
"sha1": "7e060dd5b19431e6d198e91ff670644372f60fbd",
"sha256": "1hn5plp7iyl626h8mrra56sysfm2qannj1dapr1m5afwkb24vfk1"
}
},
{
"path": "com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "5e902aae26ac5c36f6420f689f43333129dd69e2",
"sha256": "10vzlnl8vbjv2jqf818wdb7kgy9c6qjka7fjmmi3vdpg1mcn6pv6"
},
"jar": {
"sha1": "c9ad4a0850ab676c5c64461a05ca524cdfff59f1",
"sha256": "170rflxnqnah0265ik2aylmxkshyqbf2zas9bp2l32xqj9l6jsaf"
}
},
{
"path": "com/google/elemental2/elemental2-core/1.0.0-RC1/elemental2-core-1.0.0-RC1",
"host": "https://repo1.maven.org/maven2",
@@ -441,19 +428,6 @@
}
},
{
"path": "com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "5e902aae26ac5c36f6420f689f43333129dd69e2",
"sha256": "10vzlnl8vbjv2jqf818wdb7kgy9c6qjka7fjmmi3vdpg1mcn6pv6"
},
"jar": {
"sha1": "c9ad4a0850ab676c5c64461a05ca524cdfff59f1",
"sha256": "170rflxnqnah0265ik2aylmxkshyqbf2zas9bp2l32xqj9l6jsaf"
}
},
{
"path": "com/ibm/icu/icu4j/66.1/icu4j-66.1",
"host": "https://repo1.maven.org/maven2",
@@ -467,6 +441,58 @@
}
},
{
"path": "commons-codec/commons-codec/1.10/commons-codec-1.10",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "44b9477418d2942d45550f7e7c66c16262062d0e",
"sha256": "1yscxabk7i59vgfjg7c1y3prj39h1d8prnwgxbisc4ni29qdpf5x"
},
"jar": {
"sha1": "4b95f4897fa13f2cd904aee711aeafc0c5295cd8",
"sha256": "0scm6321zz76dc3bs8sy2qyami755lz4lq5455gl67bi9slxyha2"
}
},
{
"path": "commons-fileupload/commons-fileupload/1.4/commons-fileupload-1.4",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "65112009d674333c1acfafb4e198ff250d710764",
"sha256": "007nyd66fqp3fbrmnsbfp1fpkhmr2lk33qmkp3salqld3xd7qlc8"
},
"jar": {
"sha1": "f95188e3d372e20e7328706c37ef366e5d7859b0",
"sha256": "1xyyl54sfxsdcwxdyq6b0azmr31b4dwqns850jjkw9a9dwrh5v54"
}
},
{
"path": "commons-io/commons-io/2.6/commons-io-2.6",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "5060835593e5b6ed18c82fc2e782f0a3c30a00b1",
"sha256": "0q4a6fp6xkyd86ikymkyv2plhf9vj8aqvggxg9d1yad2jcw8c8qc"
},
"jar": {
"sha1": "815893df5f31da2ece4040fe0a12fd44b577afaf",
"sha256": "04v5fg53jl9gbn6pyz3l7kbpxv0xjzyasnw6yd1a3hhacq2d6xzq"
}
},
{
"path": "compojure/compojure/1.5.2/compojure-1.5.2",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "9e8da477b6682094d56802cb155291a2acb829bd",
"sha256": "036z64iprypccz03iq7lqxvw99xjh4xlsfmfwbs37pmhfnfmbdnx"
},
"jar": {
"sha1": "0b5258d0616ffc5f64c2b6d95f09de56d24df439",
"sha256": "1s2k05lwnlm9a66mxnsss437i9gp70dny8y2rlfkl090s6mdqsaf"
}
},
{
"path": "com/taoensso/encore/2.105.0/encore-2.105.0",
"host": "https://repo.clojars.org",
@@ -545,58 +571,6 @@
}
},
{
"path": "commons-codec/commons-codec/1.10/commons-codec-1.10",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "44b9477418d2942d45550f7e7c66c16262062d0e",
"sha256": "1yscxabk7i59vgfjg7c1y3prj39h1d8prnwgxbisc4ni29qdpf5x"
},
"jar": {
"sha1": "4b95f4897fa13f2cd904aee711aeafc0c5295cd8",
"sha256": "0scm6321zz76dc3bs8sy2qyami755lz4lq5455gl67bi9slxyha2"
}
},
{
"path": "commons-fileupload/commons-fileupload/1.4/commons-fileupload-1.4",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "65112009d674333c1acfafb4e198ff250d710764",
"sha256": "007nyd66fqp3fbrmnsbfp1fpkhmr2lk33qmkp3salqld3xd7qlc8"
},
"jar": {
"sha1": "f95188e3d372e20e7328706c37ef366e5d7859b0",
"sha256": "1xyyl54sfxsdcwxdyq6b0azmr31b4dwqns850jjkw9a9dwrh5v54"
}
},
{
"path": "commons-io/commons-io/2.6/commons-io-2.6",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "5060835593e5b6ed18c82fc2e782f0a3c30a00b1",
"sha256": "0q4a6fp6xkyd86ikymkyv2plhf9vj8aqvggxg9d1yad2jcw8c8qc"
},
"jar": {
"sha1": "815893df5f31da2ece4040fe0a12fd44b577afaf",
"sha256": "04v5fg53jl9gbn6pyz3l7kbpxv0xjzyasnw6yd1a3hhacq2d6xzq"
}
},
{
"path": "compojure/compojure/1.5.2/compojure-1.5.2",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "9e8da477b6682094d56802cb155291a2acb829bd",
"sha256": "036z64iprypccz03iq7lqxvw99xjh4xlsfmfwbs37pmhfnfmbdnx"
},
"jar": {
"sha1": "0b5258d0616ffc5f64c2b6d95f09de56d24df439",
"sha256": "1s2k05lwnlm9a66mxnsss437i9gp70dny8y2rlfkl090s6mdqsaf"
}
},
{
"path": "crypto-equality/crypto-equality/1.0.0/crypto-equality-1.0.0",
"host": "https://repo.clojars.org",
@@ -675,19 +649,6 @@
}
},
{
"path": "hashp/hashp/0.2.1/hashp-0.2.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "32530b9106a64fd5442d2aa27c6da4175d1f1440",
"sha256": "1z94k8c52r87rq3nhc0mqazcxff6d4phi8gy1bgndhiz4nq1mia7"
},
"jar": {
"sha1": "fb501db2eb4a028c1875382d58c17c381aec47b8",
"sha256": "1lwirzb60zvksvkb3arpwi4fk1xnp0x5ljmrca5vf7dq25lmwmsd"
}
},
{
"path": "hiccup/hiccup/1.0.5/hiccup-1.0.5",
"host": "https://repo.clojars.org",
@@ -818,32 +779,6 @@
}
},
{
"path": "mvxcvi/arrangement/1.2.0/arrangement-1.2.0",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "4f19bd291595870162eadd35456a0b2e76444a64",
"sha256": "1qqnl05nwcjnzhlgplcsbckrp8pqvf8n6bf8kr8rz7lz2q4px3vb"
},
"jar": {
"sha1": "036e640bb9e14c2aa95589a45a018eb8358ce3f6",
"sha256": "1m3v1rkpdmv7aym5vq2swh0mf9mg7xppdr3vrl4g6qm3s42c24b7"
}
},
{
"path": "mvxcvi/puget/1.3.1/puget-1.3.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "07104dc20a13c7e255fffee4f16de9a6873c187f",
"sha256": "1129rb3qksg7n85j03k6d3sr6868g724097vxids1r4wqj2phxkf"
},
"jar": {
"sha1": "a4f7dcf71ccd8d69d4ecd2b19f3d671dfc169308",
"sha256": "029znh7p8f1h91gri4jhzwqsa0rnn3i34yr3kav55npym2sw5sfp"
}
},
{
"path": "net/cgrand/macrovich/0.2.1/macrovich-0.2.1",
"host": "https://repo.clojars.org",
@@ -949,15 +884,15 @@
},
{
"path": "org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2",
"path": "org/clojure/core.rrb-vector/0.1.1/core.rrb-vector-0.1.1",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "e9336ac820c5a7e07fe0aa431df981cbab6db3e3",
"sha256": "07q9qmxc7ggaxh27imgs34svn4j269rhslbnrs63ahrqzk5bmqlf"
"sha1": "3231642aa1dcf628c864a5f208cd293fbd6a385a",
"sha256": "18kk5sds5lg8r2kidhz9qpgyrvggkj8j4sgfdsmyyl93w3f16lnp"
},
"jar": {
"sha1": "0404feea925608b921b56acd11d3b187a0d33fe4",
"sha256": "13hkx1285f2imqlj6wbgyxki2yg8rmfr49iq1zijxm1cgfx8xyai"
"sha1": "aafb7677ec1e9f344fc834bbbdb91e8ba02af474",
"sha256": "0cqyy1vqrhilgwrdxsibd7360ch3hhwjnbbnzsak38v6i6mg66xl"
}
},
@@ -1000,19 +935,6 @@
}
},
{
"path": "org/clojure/google-closure-library-third-party/0.0-20191016-6ae1f72f/google-closure-library-third-party-0.0-20191016-6ae1f72f",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "1aa0b32fd70e6644dcb06b88b55630d6bbb6f188",
"sha256": "1wq6gvhlvy3mdhj1cb0w62kclqd7x42dqd0275l40rlla5q5h1z1"
},
"jar": {
"sha1": "4fc15daa4fd1b150e8c6d32755796634446dd86a",
"sha256": "1ykw162gng0lcbxn2f387vv1l4d7hfwyayhxgzqqgi9jx211fzw5"
}
},
{
"path": "org/clojure/google-closure-library/0.0-20191016-6ae1f72f/google-closure-library-0.0-20191016-6ae1f72f",
"host": "https://repo1.maven.org/maven2",
@@ -1026,6 +948,19 @@
}
},
{
"path": "org/clojure/google-closure-library-third-party/0.0-20191016-6ae1f72f/google-closure-library-third-party-0.0-20191016-6ae1f72f",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "1aa0b32fd70e6644dcb06b88b55630d6bbb6f188",
"sha256": "1wq6gvhlvy3mdhj1cb0w62kclqd7x42dqd0275l40rlla5q5h1z1"
},
"jar": {
"sha1": "4fc15daa4fd1b150e8c6d32755796634446dd86a",
"sha256": "1ykw162gng0lcbxn2f387vv1l4d7hfwyayhxgzqqgi9jx211fzw5"
}
},
{
"path": "org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176",
"host": "https://repo1.maven.org/maven2",
@@ -1052,19 +987,6 @@
}
},
{
"path": "org/clojure/tools.analyzer.jvm/1.1.0/tools.analyzer.jvm-1.1.0",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "3f21bdbd549557232eb0bf0965b2beea34004d52",
"sha256": "0cyyhf82pn4mjw4whr4sx3cnxrgsk862dq92gn79yawxr6842i51"
},
"jar": {
"sha1": "027d2ebe594eb5f46d6bcea62593e184937b3011",
"sha256": "0kcfcn12dmyrm7sk1jkrlcb7ws8kazfqziv62mfid62xc095gayz"
}
},
{
"path": "org/clojure/tools.analyzer/1.0.0/tools.analyzer-1.0.0",
"host": "https://repo1.maven.org/maven2",
@@ -1078,6 +1000,19 @@
}
},
{
"path": "org/clojure/tools.analyzer.jvm/1.1.0/tools.analyzer.jvm-1.1.0",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "3f21bdbd549557232eb0bf0965b2beea34004d52",
"sha256": "0cyyhf82pn4mjw4whr4sx3cnxrgsk862dq92gn79yawxr6842i51"
},
"jar": {
"sha1": "027d2ebe594eb5f46d6bcea62593e184937b3011",
"sha256": "0kcfcn12dmyrm7sk1jkrlcb7ws8kazfqziv62mfid62xc095gayz"
}
},
{
"path": "org/clojure/tools.cli/1.0.194/tools.cli-1.0.194",
"host": "https://repo1.maven.org/maven2",
@@ -1143,19 +1078,6 @@
}
},
{
"path": "org/graalvm/js/js-scriptengine/20.1.0/js-scriptengine-20.1.0",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "020bac4e8232f0b051e3e6b8033f67653cf9c685",
"sha256": "1avd7kmwh0i6nkcirwl358a6lkpqwara0f5a7qiw1fjivc81qmzq"
},
"jar": {
"sha1": "a4accb1ced82da8d61bd2928f435de8af548dc2b",
"sha256": "03001wa3xs08lw2rz27w5s0fyspyhkiiarqsrq9yf8gfysmnik2s"
}
},
{
"path": "org/graalvm/js/js/20.1.0/js-20.1.0",
"host": "https://repo1.maven.org/maven2",
@@ -1169,6 +1091,19 @@
}
},
{
"path": "org/graalvm/js/js-scriptengine/20.1.0/js-scriptengine-20.1.0",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "020bac4e8232f0b051e3e6b8033f67653cf9c685",
"sha256": "1avd7kmwh0i6nkcirwl358a6lkpqwara0f5a7qiw1fjivc81qmzq"
},
"jar": {
"sha1": "a4accb1ced82da8d61bd2928f435de8af548dc2b",
"sha256": "03001wa3xs08lw2rz27w5s0fyspyhkiiarqsrq9yf8gfysmnik2s"
}
},
{
"path": "org/graalvm/regex/regex/20.1.0/regex-20.1.0",
"host": "https://repo1.maven.org/maven2",
@@ -1299,6 +1234,19 @@
}
},
{
"path": "org/ow2/asm/asm/7.1/asm-7.1",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "7e40eb6619fd20bd7d98bf775bfdd810aec87ac7",
"sha256": "101i3pyrq082kjyz413hfqwkjjsyfnk9kx3rqr38ln56mlp78a8g"
},
"jar": {
"sha1": "fa29aa438674ff19d5e1386d2c3527a0267f291e",
"sha256": "1pnlb1ick32bihpzc599xl9ppd07qhls6pm0xaqwrj9cdlmzmcja"
}
},
{
"path": "org/ow2/asm/asm-analysis/7.1/asm-analysis-7.1",
"host": "https://repo1.maven.org/maven2",
@@ -1351,19 +1299,6 @@
}
},
{
"path": "org/ow2/asm/asm/7.1/asm-7.1",
"host": "https://repo1.maven.org/maven2",
"pom": {
"sha1": "7e40eb6619fd20bd7d98bf775bfdd810aec87ac7",
"sha256": "101i3pyrq082kjyz413hfqwkjjsyfnk9kx3rqr38ln56mlp78a8g"
},
"jar": {
"sha1": "fa29aa438674ff19d5e1386d2c3527a0267f291e",
"sha256": "1pnlb1ick32bihpzc599xl9ppd07qhls6pm0xaqwrj9cdlmzmcja"
}
},
{
"path": "org/wildfly/client/wildfly-client-config/1.0.1.Final/wildfly-client-config-1.0.1.Final",
"host": "https://repo1.maven.org/maven2",
@@ -1416,6 +1351,19 @@
}
},
{
"path": "reagent/reagent/1.0.0/reagent-1.0.0",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "93ad5ccb0101108fb0843a3f2c50da28f8fd8336",
"sha256": "1l4xzgc4wbd8b29mhj5j336cf8w1zccaia0w413zf3bnj6jf5m38"
},
"jar": {
"sha1": "a1dd4d40425bb2e1afad0fe72780b43ff394ccfa",
"sha256": "1g607s1ymns85923bvhwrsj0y5czyqqq1jmxx0a58fnsm1b318fa"
}
},
{
"path": "re-com/re-com/2.8.0/re-com-2.8.0",
"host": "https://repo.clojars.org",
@@ -1429,6 +1377,19 @@
}
},
{
"path": "refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "0bce30b420249ba7e4b90cbb3e046b4bb5416389",
"sha256": "0zmg5qc8d55pry7832isiwd2q237znfjqjpxchd2hvlpalh5qnva"
},
"jar": {
"sha1": "6bc3441afc94f7ca024e41a864ca75e05df7e207",
"sha256": "0w8hax99y98l53mixxzx2ja0vcnhjv8dnsaz1zj3vqk775ns5w6i"
}
},
{
"path": "re-frame/re-frame/0.12.0/re-frame-0.12.0",
"host": "https://repo.clojars.org",
@@ -1468,32 +1429,6 @@
}
},
{
"path": "reagent/reagent/1.0.0/reagent-1.0.0",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "93ad5ccb0101108fb0843a3f2c50da28f8fd8336",
"sha256": "1l4xzgc4wbd8b29mhj5j336cf8w1zccaia0w413zf3bnj6jf5m38"
},
"jar": {
"sha1": "a1dd4d40425bb2e1afad0fe72780b43ff394ccfa",
"sha256": "1g607s1ymns85923bvhwrsj0y5czyqqq1jmxx0a58fnsm1b318fa"
}
},
{
"path": "refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "0bce30b420249ba7e4b90cbb3e046b4bb5416389",
"sha256": "0zmg5qc8d55pry7832isiwd2q237znfjqjpxchd2hvlpalh5qnva"
},
"jar": {
"sha1": "6bc3441afc94f7ca024e41a864ca75e05df7e207",
"sha256": "0w8hax99y98l53mixxzx2ja0vcnhjv8dnsaz1zj3vqk775ns5w6i"
}
},
{
"path": "rewrite-clj/rewrite-clj/0.6.1/rewrite-clj-0.6.1",
"host": "https://repo.clojars.org",
@@ -1508,15 +1443,15 @@
},
{
"path": "rewrite-cljs/rewrite-cljs/0.4.5/rewrite-cljs-0.4.5",
"path": "rewrite-cljs/rewrite-cljs/0.4.4/rewrite-cljs-0.4.4",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "378cd53218027b9a93640dcf64c040665f6c9c6b",
"sha256": "1qrhrgzhqdyqizh0ngnr4zgj9xkfzq0qhsws4pxxra3qc9ikl9cq"
"sha1": "4e7a2542517a5b0231631305461603605bea1592",
"sha256": "050imgkzw5q7200klwrkd4v32xxy1f4aghs8g4ma5dbg4rl4pgcd"
},
"jar": {
"sha1": "c35be115c39dadc71a4de3f584aa8ca295e11257",
"sha256": "1dnw0jhr1hhqz80w3z5d8qdbaqdvgzg4fyhv6lffa51c9ca1dsr1"
"sha1": "dd14a371d0d09eedccb39f01e3edabefb2d1e64f",
"sha256": "0hb07wg71i2bjn8wzs8q6w1nb3jb2s36nhr9kv9mc0gyrr6im244"
}
},
@@ -1648,18 +1583,5 @@
"sha1": "09af0b348e6253dcf9fd567d0d22ffebdea46176",
"sha256": "1qg2iyblykfkzmplc2c46916b9m0h5ad6lxmvrk5qn3pdxqr8vw0"
}
},
{
"path": "zprint/zprint/1.1.1/zprint-1.1.1",
"host": "https://repo.clojars.org",
"pom": {
"sha1": "d7225bdc4978d3a8eac8613187cddd2efb9e39d2",
"sha256": "0yyy31h88zww238c2v4zi9va3pjp7ii76zjggglakd3wm1fdbnck"
},
"jar": {
"sha1": "3bd9bbedb188a66ccf72c1e22819e8e423a6757a",
"sha256": "1bvrarxw0dqvxlhj6gdwrv6mklzh4p79537g293fqlm07f2knfph"
}
}
]
+17 -23
View File
@@ -2,16 +2,13 @@ args4j/args4j/2.0.26/args4j-2.0.26.jar
bidi/bidi/2.1.6/bidi-2.1.6.jar
binaryage/env-config/0.2.2/env-config-0.2.2.jar
binaryage/oops/0.7.0/oops-0.7.0.jar
borkdude/edamame/0.0.11-alpha.28/edamame-0.0.11-alpha.28.jar
borkdude/sci.impl.reflector/0.0.1/sci.impl.reflector-0.0.1.jar
borkdude/sci/0.2.1-alpha.1/sci-0.2.1-alpha.1.jar
cider/cider-nrepl/0.25.3/cider-nrepl-0.25.3.jar
cider/piggieback/0.4.1/piggieback-0.4.1.jar
clj-stacktrace/clj-stacktrace/0.2.8/clj-stacktrace-0.2.8.jar
cljfmt/cljfmt/0.6.7/cljfmt-0.6.7.jar
cljs-bean/cljs-bean/1.3.0/cljs-bean-1.3.0.jar
cljsjs/react-dom-server/17.0.1-0/react-dom-server-17.0.1-0.jar
cljsjs/react-dom/17.0.1-0/react-dom-17.0.1-0.jar
cljsjs/react/17.0.1-0/react-17.0.1-0.jar
cljsjs/react-dom/17.0.1-0/react-dom-17.0.1-0.jar
cljsjs/react-dom-server/17.0.1-0/react-dom-server-17.0.1-0.jar
clout/clout/2.1.2/clout-2.1.2.jar
com/andrewmcveigh/cljs-time/0.5.2/cljs-time-0.5.2.jar
com/bhauman/cljs-test-display/0.1.1/cljs-test-display-0.1.1.jar
@@ -22,6 +19,8 @@ com/cognitect/transit-js/0.8.846/transit-js-0.8.846.jar
com/fasterxml/jackson/core/jackson-core/2.8.7/jackson-core-2.8.7.jar
com/google/code/findbugs/jsr305/3.0.1/jsr305-3.0.1.jar
com/google/code/gson/gson/2.7/gson-2.7.jar
com/googlecode/java-diff-utils/diffutils/1.3.0/diffutils-1.3.0.jar
com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar
com/google/elemental2/elemental2-core/1.0.0-RC1/elemental2-core-1.0.0-RC1.jar
com/google/errorprone/error_prone_annotations/2.3.1/error_prone_annotations-2.3.1.jar
com/google/guava/guava/25.1-jre/guava-25.1-jre.jar
@@ -32,25 +31,23 @@ com/google/jsinterop/base/1.0.0/base-1.0.0.jar
com/google/jsinterop/jsinterop-annotations/1.0.2/jsinterop-annotations-1.0.2.jar
com/google/protobuf/protobuf-java/3.11.1/protobuf-java-3.11.1.jar
com/google/re2j/re2j/1.3/re2j-1.3.jar
com/googlecode/json-simple/json-simple/1.1.1/json-simple-1.1.1.jar
com/ibm/icu/icu4j/66.1/icu4j-66.1.jar
commons-codec/commons-codec/1.10/commons-codec-1.10.jar
commons-fileupload/commons-fileupload/1.4/commons-fileupload-1.4.jar
commons-io/commons-io/2.6/commons-io-2.6.jar
compojure/compojure/1.5.2/compojure-1.5.2.jar
com/taoensso/encore/2.105.0/encore-2.105.0.jar
com/taoensso/timbre/4.10.0/timbre-4.10.0.jar
com/taoensso/truss/1.5.0/truss-1.5.0.jar
com/taoensso/tufte/2.1.0/tufte-2.1.0.jar
com/wsscode/pathom/2.2.31/pathom-2.2.31.jar
com/wsscode/spec-inspec/1.0.0-alpha2/spec-inspec-1.0.0-alpha2.jar
commons-codec/commons-codec/1.10/commons-codec-1.10.jar
commons-fileupload/commons-fileupload/1.4/commons-fileupload-1.4.jar
commons-io/commons-io/2.6/commons-io-2.6.jar
compojure/compojure/1.5.2/compojure-1.5.2.jar
crypto-equality/crypto-equality/1.0.0/crypto-equality-1.0.0.jar
crypto-random/crypto-random/1.2.0/crypto-random-1.2.0.jar
day8/re-frame/test/0.1.5/test-0.1.5.jar
edn-query-language/eql/0.0.9/eql-0.0.9.jar
expound/expound/0.8.5/expound-0.8.5.jar
fipp/fipp/0.6.23/fipp-0.6.23.jar
hashp/hashp/0.2.1/hashp-0.2.1.jar
hiccup/hiccup/1.0.5/hiccup-1.0.5.jar
hickory/hickory/0.7.1/hickory-0.7.1.jar
http-kit/http-kit/2.2.0/http-kit-2.2.0.jar
@@ -61,8 +58,6 @@ javax/servlet/servlet-api/2.5/servlet-api-2.5.jar
javax/xml/bind/jaxb-api/2.3.0/jaxb-api-2.3.0.jar
medley/medley/0.8.2/medley-0.8.2.jar
mvxcvi/alphabase/1.0.0/alphabase-1.0.0.jar
mvxcvi/arrangement/1.2.0/arrangement-1.2.0.jar
mvxcvi/puget/1.3.1/puget-1.3.1.jar
net/cgrand/macrovich/0.2.1/macrovich-0.2.1.jar
nrepl/nrepl/0.7.0/nrepl-0.7.0.jar
org/checkerframework/checker-qual/2.0.0/checker-qual-2.0.0.jar
@@ -71,23 +66,23 @@ org/clojure/clojurescript/1.10.773/clojurescript-1.10.773.jar
org/clojure/core.async/1.3.610/core.async-1.3.610.jar
org/clojure/core.cache/1.0.207/core.cache-1.0.207.jar
org/clojure/core.memoize/1.0.236/core.memoize-1.0.236.jar
org/clojure/core.rrb-vector/0.1.2/core.rrb-vector-0.1.2.jar
org/clojure/core.rrb-vector/0.1.1/core.rrb-vector-0.1.1.jar
org/clojure/core.specs.alpha/0.2.44/core.specs.alpha-0.2.44.jar
org/clojure/data.json/1.0.0/data.json-1.0.0.jar
org/clojure/data.priority-map/1.0.0/data.priority-map-1.0.0.jar
org/clojure/google-closure-library-third-party/0.0-20191016-6ae1f72f/google-closure-library-third-party-0.0-20191016-6ae1f72f.jar
org/clojure/google-closure-library/0.0-20191016-6ae1f72f/google-closure-library-0.0-20191016-6ae1f72f.jar
org/clojure/google-closure-library-third-party/0.0-20191016-6ae1f72f/google-closure-library-third-party-0.0-20191016-6ae1f72f.jar
org/clojure/spec.alpha/0.2.176/spec.alpha-0.2.176.jar
org/clojure/test.check/1.1.0/test.check-1.1.0.jar
org/clojure/tools.analyzer.jvm/1.1.0/tools.analyzer.jvm-1.1.0.jar
org/clojure/tools.analyzer/1.0.0/tools.analyzer-1.0.0.jar
org/clojure/tools.analyzer.jvm/1.1.0/tools.analyzer.jvm-1.1.0.jar
org/clojure/tools.cli/1.0.194/tools.cli-1.0.194.jar
org/clojure/tools.logging/0.4.1/tools.logging-0.4.1.jar
org/clojure/tools.macro/0.1.5/tools.macro-0.1.5.jar
org/clojure/tools.reader/1.3.3/tools.reader-1.3.3.jar
org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar
org/graalvm/js/js-scriptengine/20.1.0/js-scriptengine-20.1.0.jar
org/graalvm/js/js/20.1.0/js-20.1.0.jar
org/graalvm/js/js-scriptengine/20.1.0/js-scriptengine-20.1.0.jar
org/graalvm/regex/regex/20.1.0/regex-20.1.0.jar
org/graalvm/sdk/graal-sdk/20.1.0/graal-sdk-20.1.0.jar
org/graalvm/truffle/truffle-api/20.1.0/truffle-api-20.1.0.jar
@@ -98,23 +93,23 @@ org/jboss/xnio/xnio-api/3.8.0.Final/xnio-api-3.8.0.Final.jar
org/jboss/xnio/xnio-nio/3.8.0.Final/xnio-nio-3.8.0.Final.jar
org/jsoup/jsoup/1.9.2/jsoup-1.9.2.jar
org/msgpack/msgpack/0.6.12/msgpack-0.6.12.jar
org/ow2/asm/asm/7.1/asm-7.1.jar
org/ow2/asm/asm-analysis/7.1/asm-analysis-7.1.jar
org/ow2/asm/asm-commons/7.1/asm-commons-7.1.jar
org/ow2/asm/asm-tree/7.1/asm-tree-7.1.jar
org/ow2/asm/asm-util/7.1/asm-util-7.1.jar
org/ow2/asm/asm/7.1/asm-7.1.jar
org/wildfly/client/wildfly-client-config/1.0.1.Final/wildfly-client-config-1.0.1.Final.jar
org/wildfly/common/wildfly-common/1.5.2.Final/wildfly-common-1.5.2.Final.jar
prismatic/schema/1.1.7/schema-1.1.7.jar
quoin/quoin/0.1.2/quoin-0.1.2.jar
reagent/reagent/1.0.0/reagent-1.0.0.jar
re-com/re-com/2.8.0/re-com-2.8.0.jar
refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0.jar
re-frame/re-frame/0.12.0/re-frame-0.12.0.jar
re-frisk-remote/re-frisk-remote/1.6.0/re-frisk-remote-1.6.0.jar
re-frisk/sente/1.15.0/sente-1.15.0.jar
reagent/reagent/1.0.0/reagent-1.0.0.jar
refactor-nrepl/refactor-nrepl/2.5.0/refactor-nrepl-2.5.0.jar
rewrite-clj/rewrite-clj/0.6.1/rewrite-clj-0.6.1.jar
rewrite-cljs/rewrite-cljs/0.4.5/rewrite-cljs-0.4.5.jar
rewrite-cljs/rewrite-cljs/0.4.4/rewrite-cljs-0.4.4.jar
ring-cors/ring-cors/0.1.8/ring-cors-0.1.8.jar
ring/ring-codec/1.1.2/ring-codec-1.1.2.jar
ring/ring-core/1.8.1/ring-core-1.8.1.jar
@@ -125,4 +120,3 @@ thheller/shadow-cljs/2.11.16/shadow-cljs-2.11.16-aot.jar
thheller/shadow-cljsjs/0.0.21/shadow-cljsjs-0.0.21.jar
thheller/shadow-util/0.7.0/shadow-util-0.7.0.jar
viebel/codox-klipse-theme/0.0.1/codox-klipse-theme-0.0.1.jar
zprint/zprint/1.1.1/zprint-1.1.1.jar
-2
View File
@@ -17,8 +17,6 @@ in mkShell {
lsof # used in start-react-native.sh
# build specific utilities
clojure maven watchman
# lint specific utilities
clj-kondo zprint
# other nice to have stuff
yarn nodejs python27
] # and some special cases
+1 -1
View File
@@ -23,7 +23,7 @@ let
# for calling clojure targets in CI or Makefile
clojure = mkShell {
buildInputs = with pkgs; [ clojure flock maven openjdk ];
buildInputs = with pkgs; [ clojure flock maven openjdk clj-kondo ];
inputsFrom = [ nodejs-sh ];
# CLASSPATH from clojure deps with 'src' appended to find local sources.
shellHook = with pkgs; ''
-1
View File
@@ -89,7 +89,6 @@
"@testing-library/jest-native": "^5.0.0",
"@testing-library/react-native": "^11.2.0",
"@types/jest": "^28.1.6",
"concurrently": "^7.6.0",
"detox": "^19.9.1",
"jest": "^25.1.0",
"jest-circus": "^26.0.0",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 878 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

+106 -111
View File
@@ -1,121 +1,116 @@
;; shadow-cljs configuration
{:source-paths ["src" "test/cljs"]
{:source-paths ["src" "test/cljs"]
:dependencies [[reagent "1.0.0"]
[re-frame "0.12.0"]
[binaryage/oops "0.7.0"]
[com.andrewmcveigh/cljs-time "0.5.2"]
[status-im/timbre "4.10.0-2-status"]
[com.taoensso/encore "2.105.0"]
[hickory "0.7.1"]
[cljs-bean "1.3.0"]
[com.cognitect/transit-cljs "0.8.248"]
[mvxcvi/alphabase "1.0.0"]
;; dev dependencies
[refactor-nrepl "2.5.0"]
[cider/cider-nrepl "0.25.3"]
[cider/piggieback "0.4.1"]
[re-frisk-remote "1.6.0"]
;; routing
[bidi "2.1.6"]
;; test dependencies
[camel-snake-kebab "0.4.3"]
[day8.re-frame/test "0.1.5"]
[com.taoensso/tufte "2.1.0"]]
:dependencies [[reagent "1.0.0"]
[re-frame "0.12.0"]
[binaryage/oops "0.7.0"]
[com.andrewmcveigh/cljs-time "0.5.2"]
[status-im/timbre "4.10.0-2-status"]
[com.taoensso/encore "2.105.0"]
[hickory "0.7.1"]
[cljs-bean "1.3.0"]
[com.cognitect/transit-cljs "0.8.248"]
[mvxcvi/alphabase "1.0.0"]
;; dev dependencies
[refactor-nrepl "2.5.0"]
[cider/cider-nrepl "0.25.3"]
[cider/piggieback "0.4.1"]
[re-frisk-remote "1.6.0"]
;; routing
[bidi "2.1.6"]
;; test dependencies
[day8.re-frame/test "0.1.5"]
[com.taoensso/tufte "2.1.0"]
;; linting
[cljfmt/cljfmt "0.6.7"]]
;; port and middleware for repl in development
:nrepl {:port 7888
:middleware [cider.piggieback/wrap-cljs-repl
refactor-nrepl.middleware/wrap-refactor]}
:nrepl {:port 7888
:middleware [cider.piggieback/wrap-cljs-repl
refactor-nrepl.middleware/wrap-refactor]}
;; shadow-cljs web interface
:http {:port 3449
:host "0.0.0.0"}
:http {:port 3449
:host "0.0.0.0"}
:cache-blockers #{status-im.utils.js-resources status-im.ui.components.icons.icons}
:builds
{:mobile
{:target :react-native
:output-dir "app"
:init-fn status-im2.setup.core/init
;; When false, the Shadow-CLJS watcher won't automatically refresh
;; the target files (a.k.a hot reload). When false, you can manually
;; reload by calling `shadow.cljs.devtools.api/watch-compile-all!`.
:devtools {:autobuild #shadow/env ["SHADOW_AUTOBUILD_ENABLED" :default true :as :bool]}
:dev {:devtools {:after-load status-im2.setup.hot-reload/reload
:build-notify status-im2.setup.hot-reload/build-notify
:preloads [re-frisk-remote.preload]}
:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options {:output-feature-set :es5
:closure-defines
{re-frame.trace/trace-enabled? true}
:source-map false
:infer-externs true}
;; if you want to use a real device, set your local ip
;; in the SHADOW_HOST env variable to make sure that
;; it will use the right interface
:local-ip #shadow/env "SHADOW_HOST"}
:chunks {:fleets status-im.fleet.default-fleet/default-fleets
:chats status-im.chat.default-chats/default-chats}
:release
{:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options {:output-feature-set :es6
;;disable for android build as there
;;is an intermittent warning with deftype
:warnings-as-errors false
:infer-externs :auto
:static-fns true
:fn-invoke-direct true
:optimizations :advanced
:js-options {:js-provider :closure}}}}
;; the tests are ran with node, react-native dependencies are mocked
;; by using node --require override.js, which uses the node-library
;; produced by the target :mocks below and redefines node require
;; function to use the mocks instead of the rn libraries
:test
{:output-to "target/test/test.js"
:output-dir "target/test"
:optimizations :simple
:target :node-test
;; When running tests without a REPL you can uncomment below line to `make test-watch` a specific file
;;:ns-regexp "status-im2.subs.subs-test$"
:main
status-im.test-runner/main
;; set :ui-driven to true to let shadow-cljs inject node-repl
:ui-driven
true
:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options
{;; needed because we override require and it
;; messes with source-map which reports callstack
;; exceeded exceptions instead of real issues
:source-map false
;; needed because we use deref in tests
:static-fns false
:optimizations :simple
:infer-externs true}}
:builds {:mobile
{:target :react-native
:output-dir "app"
:init-fn status-im2.setup.core/init
;; When false, the Shadow-CLJS watcher won't automatically refresh
;; the target files (a.k.a hot reload). When false, you can manually
;; reload by calling `shadow.cljs.devtools.api/watch-compile-all!`.
:devtools {:autobuild #shadow/env ["SHADOW_AUTOBUILD_ENABLED" :default true :as :bool]}
:dev {:devtools {:after-load status-im2.setup.hot-reload/reload
:build-notify status-im2.setup.hot-reload/build-notify
:preloads [re-frisk-remote.preload]}
:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options {:output-feature-set :es5
:closure-defines
{re-frame.trace/trace-enabled? true}
:source-map false
:infer-externs true}
;; if you want to use a real device, set your local ip
;; in the SHADOW_HOST env variable to make sure that
;; it will use the right interface
:local-ip #shadow/env "SHADOW_HOST"}
:chunks {:fleets status-im.fleet.default-fleet/default-fleets
:chats status-im.chat.default-chats/default-chats}
:release
{:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options {:output-feature-set :es6
;;disable for android build as there
;;is an intermittent warning with deftype
:warnings-as-errors false
:infer-externs :auto
:static-fns true
:fn-invoke-direct true
:optimizations :advanced
:js-options {:js-provider :closure}}}}
;; the tests are ran with node, react-native dependencies are mocked
;; by using node --require override.js, which uses the node-library
;; produced by the target :mocks below and redefines node require
;; function to use the mocks instead of the rn libraries
:test
{:output-to "target/test/test.js"
:output-dir "target/test"
:optimizations :simple
:target :node-test
:main status-im.test-runner/main
;; set :ui-driven to true to let shadow-cljs inject node-repl
:ui-driven true
:closure-defines
{status-im.utils.config/POKT_TOKEN #shadow/env "POKT_TOKEN"
status-im.utils.config/OPENSEA_API_KEY #shadow/env "OPENSEA_API_KEY"}
:compiler-options {;; needed because we override require and it
;; messes with source-map which reports callstack
;; exceeded exceptions instead of real issues
:source-map false
;; needed because we use deref in tests
:static-fns false
:optimizations :simple
:infer-externs true}}
;; mock.js-dependencies is mocking the react-native libraries
;; we build it as a node library so that it can be required by
;; override.js
:mocks
{:target :node-library
:exports {:mocks mocks.js-dependencies/mock}
:output-to "target/mocks/mocks.js"
:output-dir "target/mocks"
:compiler-options {:optimizations :simple
:source-map false}}
:component-test {:target :npm-module
:entries [quo2.core-spec]
:ns-regexp "-component-spec$"
:output-dir "component-spec"
:compiler-options {:warnings-as-errors false
:static-fns false
:infer-externs true}}}}
;; mock.js-dependencies is mocking the react-native libraries
;; we build it as a node library so that it can be required by
;; override.js
:mocks
{:target :node-library
:exports {:mocks mocks.js-dependencies/mock}
:output-to "target/mocks/mocks.js"
:output-dir "target/mocks"
:compiler-options {:optimizations :simple
:source-map false}}
:component-test {:target :npm-module
:entries [quo2.core-spec]
:ns-regexp "-component-spec$"
:output-dir "component-spec"
:compiler-options {:warnings-as-errors false
:static-fns false
:infer-externs true}}}}
+11 -17
View File
@@ -1,25 +1,22 @@
(ns i18n.i18n
(:require ["i18n-js" :as i18n]
[clojure.string :as string]
[status-im.goog.i18n :as goog.i18n]))
(:require
["i18n-js" :as i18n]
[clojure.string :as string]
[status-im.goog.i18n :as goog.i18n]))
(defn setup
[default-device-language translations-by-locale]
(defn init [default-device-language translations-by-locale]
(set! (.-fallbacks i18n) true)
(set! (.-defaultSeparator i18n) "/")
(set! (.-locale i18n) default-device-language)
(set! (.-translations i18n) translations-by-locale))
(defn get-translations
[]
(defn get-translations []
(.-translations i18n))
(defn set-language
[lang]
(defn set-language [lang]
(set! (.-locale i18n) lang))
;;:zh, :zh-hans-xx, :zh-hant-xx have been added until this bug will be fixed
;;https://github.com/fnando/i18n-js/issues/460
;;:zh, :zh-hans-xx, :zh-hant-xx have been added until this bug will be fixed https://github.com/fnando/i18n-js/issues/460
(def delimeters
"This function is a hack: mobile Safari doesn't support toLocaleString(), so we need to pass
@@ -32,8 +29,7 @@
{:delimiter ""
:separator (subs n 4 5)})))
(defn label-number
[number]
(defn label-number [number]
(when number
(let [{:keys [delimiter separator]} delimeters]
(.toNumber i18n
@@ -45,8 +41,7 @@
(def default-option-value "<no value>")
(defn label-options
[options]
(defn label-options [options]
;; i18n ignores nil value, leading to misleading messages
(into {} (for [[k v] options] [k (or v default-option-value)])))
@@ -60,8 +55,7 @@
(def label (memoize label-fn))
(defn label-pluralize
[count path & options]
(defn label-pluralize [count path & options]
(if (exists? (.t i18n))
(.p i18n count (name path) (clj->js options))
(name path)))
-15
View File
@@ -1,15 +0,0 @@
import {useDerivedValue, runOnJS as reaRunOnJS, runOnJS} from "react-native-reanimated";
export function useTranslateY(initialTranslationY, bottomSheetDy, panY) {
return useDerivedValue(() => {
return initialTranslationY - (bottomSheetDy.value - panY.value)
})
}
export function useBackgroundOpacity(translateY, backgroundHeight, windowHeight) {
return useDerivedValue(() => {
const opacity = ((translateY.value - windowHeight) / -backgroundHeight) * 0.5
return Math.max(Math.min(opacity, 0.5), 0)
})
}
-18
View File
@@ -1,18 +0,0 @@
import { useDerivedValue } from 'react-native-reanimated';
const MAX_SCALE = 1.8;
export function ringScale(scale, subtract) {
return useDerivedValue(
function () {
'worklet'
const value = scale.value;
const maxDelta = MAX_SCALE - 1;
const maxDeltaDiff = 1 - maxDelta;
const maxVirtualScale = MAX_SCALE + maxDelta;
const decimals = value - Math.floor(value);
const normalizedValue = value >= maxVirtualScale ? (decimals + ((parseInt(value) - 1) * maxDeltaDiff) + 1) : value;
return (((normalizedValue - subtract) > MAX_SCALE ? normalizedValue - maxDelta : normalizedValue) - subtract);
}
);
}
-11
View File
@@ -1,5 +1,3 @@
import { useDerivedValue, interpolate } from 'react-native-reanimated';
// Generic Worklets
export function applyAnimationsToStyle(animations, style) {
@@ -29,12 +27,3 @@ export function applyAnimationsToStyle(animations, style) {
return Object.assign(animatedStyle, style);
};
};
export function interpolateValue(sharedValue, inputRange, outputRange) {
return useDerivedValue(
function () {
'worklet'
return interpolate(sharedValue.value, inputRange, outputRange);
}
);
}
+224 -288
View File
@@ -4,40 +4,24 @@
(:require [status-im.utils.test :as utils.test])
(:require [status-im.chat.default-chats :refer (default-chats)]))
;; to generate a js Proxy at js/__STATUS_MOBILE_JS_IDENTITY_PROXY__ that accept any (.xxx) call and
;; return itself
;; For the convenience to mock eg.
;; (-> reanimated/slide-out-up-animation .springify (.damping 20) (.stiffness 300))
;; (-> reanimated/slide-out-up-animation (.damping 20) .springify (.stiffness 300))
(js/eval
"
var globalThis
if (typeof window === \"undefined\") {
globalThis = global
} else {
globalThis = window
}
globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return () => globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__}})
")
(def action-button #js {:default #js {:Item #js {}}})
(def config #js {:default #js {}})
(def camera #js {:RNCamera #js {:Constants #js {}}})
(def dialogs #js {})
(def dismiss-keyboard #js {})
(def emoji-picker #js {:default #js {}})
(def fs #js {})
(def i18n #js {:locale "en"})
(def image-crop-picker #js {})
(def image-resizer #js {})
(def qr-code #js {})
(def svg #js {})
(def action-button #js {:default #js {:Item #js {}}})
(def config #js {:default #js {}})
(def camera #js {:RNCamera #js {:Constants #js {}}})
(def dialogs #js {})
(def dismiss-keyboard #js {})
(def emoji-picker #js {:default #js {}})
(def fs #js {})
(def i18n #js {:locale "en"})
(def image-crop-picker #js {})
(def image-resizer #js {})
(def qr-code #js {})
(def svg #js {})
(def react-native
(clj->js {:NativeModules {:RNGestureHandlerModule {:Direction (fn [])}
:PushNotifications {}
:Status utils.test/status
:ReanimatedModule {:configureProps (fn [])}}
(clj->js {:NativeModules {:RNGestureHandlerModule {:Direction (fn [])}
:PushNotifications {}
:Status utils.test/status
:ReanimatedModule {:configureProps (fn [])}}
:View {}
:RefreshControl {}
@@ -80,10 +64,9 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
:Platform {:select (fn [])}
:I18nManager {:isRTL ""}
:NativeEventEmitter (fn [])
:LayoutAnimation {:Presets #js
{:easeInEaseOut nil
:linear nil
:spring nil}
:LayoutAnimation {:Presets #js {:easeInEaseOut nil
:linear nil
:spring nil}
:Types #js {}
:Properties #{}
:create (fn [])
@@ -94,199 +77,163 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
(set! js/ReactNative react-native)
(def reanimated-bottom-sheet #js {:default #js {}})
(def reanimated-bottom-sheet #js {:default #js {}})
(def icons #js {:default #js {}})
(def webview #js {:WebView #js {}})
(def status-keycard
#js
{:default #js
{:nfcIsSupported (fn [] #js {:then identity})
:nfcIsEnabled (fn [] #js {:then identity})}})
(def icons #js {:default #js {}})
(def webview #js {:WebView #js {}})
(def status-keycard #js {:default #js {:nfcIsSupported (fn [] #js {:then identity})
:nfcIsEnabled (fn [] #js {:then identity})}})
(def snoopy #js {:default #js {}})
(def snoopy-filter #js {:default #js {}})
(def snoopy-bars #js {:default #js {}})
(def snoopy-buffer #js {:default #js {}})
(def fetch #js {})
(def snoopy #js {:default #js {}})
(def snoopy-filter #js {:default #js {}})
(def snoopy-bars #js {:default #js {}})
(def snoopy-buffer #js {:default #js {}})
(def fetch #js {})
(def async-storage-atom (atom {}))
(def async-storage
#js
{:default #js
{:setItem #(js/Promise.resolve)
:multiGet #(js/Promise.resolve)
:getItem #(js/Promise.resolve)}})
(def async-storage #js {:default #js {:setItem #(js/Promise.resolve)
:multiGet #(js/Promise.resolve)
:getItem #(js/Promise.resolve)}})
(def background-timer
(clj->js {:default {:setTimeout js/setTimeout
:setInterval js/setInterval
:clearTimeout js/clearTimeout
:clearInterval js/clearInterval}}))
(def background-timer (clj->js {:default {:setTimeout js/setTimeout
:setInterval js/setInterval
:clearTimeout js/clearTimeout
:clearInterval js/clearInterval}}))
(def keychain
#js
{:setGenericPassword (constantly (.resolve js/Promise true))
:setInternetCredentials #(js/Promise.resolve)
:resetInternetCredentials #(js/Promise.resolve)
"ACCESSIBLE" {}
"ACCESS_CONTROL" {}})
(def keychain #js {:setGenericPassword (constantly (.resolve js/Promise true))
:setInternetCredentials #(js/Promise.resolve)
:resetInternetCredentials #(js/Promise.resolve)
"ACCESSIBLE" {}
"ACCESS_CONTROL" {}})
(def react-native-mail #js {:mail #js {}})
(def react-native-screens #js {})
(def react-native-shake #js {})
(def react-native-screens #js {})
(def react-native-shake #js {})
(def react-native-share #js {:default {}})
(def react-native-svg
#js
{:SvgUri #js {:render identity}
:SvgXml #js {:render identity}
:default #js {:render identity}
:Path #js {:render identity}})
(def react-native-svg #js {:SvgUri #js {:render identity}
:SvgXml #js {:render identity}})
(def react-native-webview #js {:default {}})
(def react-native-audio-toolkit #js {:MediaStates {}})
(def net-info #js {})
(def touchid #js {})
(def net-info #js {})
(def touchid #js {})
(def react-native-image-viewing #js {:default {}})
(def safe-area-context
(clj->js {:SafeAreaProvider {:_reactNativeIphoneXHelper {:getStatusBarHeight (fn [])}}
:SafeAreaInsetsContext {:Consumer (fn [])}
:SafeAreaView {}}))
(def safe-area-context (clj->js {:SafeAreaProvider {:_reactNativeIphoneXHelper {:getStatusBarHeight (fn [])}}
:SafeAreaInsetsContext {:Consumer (fn [])}
:SafeAreaView {}}))
(def back-handler
#js
{:addEventListener identity
:removeEventListener identity})
(def react
#js
{:useCallback nil
:useEffect nil
:useRef nil
:createRef nil
:Fragment identity})
(def react-navigation-native
#js
{:NavigationContainer #js {}
:useFocusEffect identity
:CommonActions #js {}
:StackActions #js {}})
(def back-handler #js {:addEventListener identity
:removeEventListener identity})
(def react #js {:useCallback nil
:useEffect nil
:useRef nil
:createRef nil
:Fragment identity})
(def react-navigation-native #js {:NavigationContainer #js {}
:useFocusEffect identity
:CommonActions #js {}
:StackActions #js {}})
(def react-native-navigation
#js
{:Navigation #js
{:constants (fn [] #js {:then identity})
:setDefaultOptions identity
:setRoot identity
:dismissOverlay #(js/Promise.resolve)
:showOverlay identity
:setLazyComponentRegistrator identity
:pop identity
:push identity
:mergeOptions identity
:popToRoot identity
:showModal identity
:dismissModal identity
:registerComponent identity
:events
(fn []
#js
{:registerModalDismissedListener identity
:registerAppLaunchedListener identity
:registerBottomTabSelectedListener identity
:registerComponentDidDisappearListener identity
:registerComponentDidAppearListener identity
:registerNavigationButtonPressedListener identity})}})
(def react-native-navigation #js {:Navigation #js {:constants (fn [] #js {:then identity})
:setDefaultOptions identity
:setRoot identity
:dismissOverlay #(js/Promise.resolve)
:showOverlay identity
:setLazyComponentRegistrator identity
:pop identity
:push identity
:mergeOptions identity
:popToRoot identity
:showModal identity
:dismissModal identity
:registerComponent identity
:events
(fn []
#js {:registerModalDismissedListener identity
:registerAppLaunchedListener identity
:registerBottomTabSelectedListener identity
:registerComponentDidDisappearListener identity
:registerComponentDidAppearListener identity
:registerNavigationButtonPressedListener identity})}})
(def react-navigation-stack
#js
{:createStackNavigator identity
:TransitionPresets #js {:ModalPresentationIOS #js {}}})
(def react-navigation-stack #js {:createStackNavigator identity
:TransitionPresets #js {:ModalPresentationIOS #js {}}})
(def react-navigation-bottom-tabs #js {:createBottomTabNavigator identity})
(def react-native-haptic-feedback #js {:default #js {:trigger nil}})
(def react-native-reanimated
#js
{:default #js
{:createAnimatedComponent identity
:eq nil
:greaterOrEq nil
:greaterThan nil
:lessThan nil
:lessOrEq nil
:add nil
:diff nil
:divide nil
:sub nil
:multiply nil
:abs nil
:min nil
:max nil
:neq nil
:and nil
:or nil
:not nil
:set nil
:startClock nil
:stopClock nil
:Value nil
:Clock nil
:debug nil
:log nil
:event nil
:cond nil
:block nil
:interpolateNode nil
:call nil
:timing nil
:onChange nil
:View #js {}
:Image #js {}
:ScrollView #js {}
:Text #js {}
:Extrapolate #js {:CLAMP nil}
:Code #js {}}
:EasingNode #js
{:bezier identity
:linear identity}
:clockRunning nil
:useSharedValue (fn [])
:useAnimatedStyle (fn [])
:withTiming (fn [])
:withDelay (fn [])
:Easing #js {:bezier identity}
:Keyframe (fn [])
:SlideOutUp js/__STATUS_MOBILE_JS_IDENTITY_PROXY__
:SlideInUp js/__STATUS_MOBILE_JS_IDENTITY_PROXY__
:LinearTransition js/__STATUS_MOBILE_JS_IDENTITY_PROXY__})
(def react-native-gesture-handler
#js
{:default #js {}
:State #js
{:BEGAN nil
:ACTIVE nil
:CANCELLED nil
:END nil
:FAILED nil
:UNDETERMINED nil}
:PureNativeButton #js {}
:TapGestureHandler #js {}
:PanGestureHandler #js {}
:TouchableHighlight #js {}
:LongPressGestureHandler #js {}
:TouchableWithoutFeedback #js {}
:NativeViewGestureHandler #js {}
:FlatList #js {}
:ScrollView #js {}
:TouchableOpacity #js {}
:GestureDetector #js {}
:Gesture #js {:Pan nil}
:createNativeWrapper identity})
(def react-native-reanimated #js {:default #js {:createAnimatedComponent identity
:eq nil
:greaterOrEq nil
:greaterThan nil
:lessThan nil
:lessOrEq nil
:add nil
:diff nil
:divide nil
:sub nil
:multiply nil
:abs nil
:min nil
:max nil
:neq nil
:and nil
:or nil
:not nil
:set nil
:startClock nil
:stopClock nil
:Value nil
:Clock nil
:debug nil
:log nil
:event nil
:cond nil
:block nil
:interpolateNode nil
:call nil
:timing nil
:onChange nil
:View #js {}
:Image #js {}
:ScrollView #js {}
:Text #js {}
:Extrapolate #js {:CLAMP nil}
:Code #js {}}
:EasingNode #js {:bezier identity
:linear identity}
:clockRunning nil
:useSharedValue (fn [])
:useAnimatedStyle (fn [])
:withTiming (fn [])
:withDelay (fn [])
:Easing #js {:bezier identity}
:Keyframe (fn [])})
(def react-native-gesture-handler #js {:default #js {}
:State #js {:BEGAN nil
:ACTIVE nil
:CANCELLED nil
:END nil
:FAILED nil
:UNDETERMINED nil}
:PureNativeButton #js {}
:TapGestureHandler #js {}
:PanGestureHandler #js {}
:TouchableHighlight #js {}
:LongPressGestureHandler #js {}
:TouchableWithoutFeedback #js {}
:NativeViewGestureHandler #js {}
:FlatList #js {}
:ScrollView #js {}
:TouchableOpacity #js {}
:GestureDetector #js {}
:Gesture #js {:Pan nil}
:createNativeWrapper identity})
(def react-native-redash #js {:clamp nil})
(def react-native-languages
(clj->js {:default {:language "en"
:addEventListener (fn [])
(clj->js {:default {:language "en",
:addEventListener (fn []),
:removeEventListener (fn [])}}))
(def react-native-device-info
@@ -296,9 +243,8 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
#js {:CameraKitCamera #js {}})
(def react-native-push-notification
#js
{:localNotification identity
:requestPermission identity})
#js {:localNotification identity
:requestPermission identity})
(def react-native-gradien #js {:default #js {}})
@@ -326,92 +272,82 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
(def react-native-camera-roll
(clj->js {:default #js {}}))
(def wallet-connect-client
#js
{:default #js {}
:CLIENT_EVENTS #js
{:session #js
{:request nil
:created nil
:deleted nil
:proposal nil
:updated nil}}})
(def wallet-connect-client #js {:default #js {}
:CLIENT_EVENTS #js {:session #js {:request nil
:created nil
:deleted nil
:proposal nil
:updated nil}}})
(def worklet-factory
#js {:applyAnimationsToStyle (fn [])})
(def shell-worklets #js {})
(def bottom-sheet #js {})
(def record-audio-worklets #js {})
;; Update i18n_resources.cljs
(defn mock
[module]
(defn mock [module]
(case module
"react-native-languages" react-native-languages
"react-native-background-timer" background-timer
"react-native-image-crop-picker" image-crop-picker
"react-native-gesture-handler" react-native-gesture-handler
"react-native-safe-area-context" safe-area-context
"react-native-config" config
"react-native-iphone-x-helper" (clj->js {:getStatusBarHeight (fn [])
:getBottomSpace (fn [])})
"react-native-screens" (clj->js {})
"react-native-reanimated" react-native-reanimated
"react-native-redash/lib/module/v1" react-native-redash
"react-native-fetch-polyfill" fetch
"react-native-status-keycard" status-keycard
"react-native-keychain" keychain
"react-native-touch-id" touchid
"@react-native-community/netinfo" net-info
"react-native-dialogs" dialogs
"react-native" react-native
"react-native-fs" fs
"react-native-mail" react-native-mail
"react-native-image-resizer" image-resizer
"react-native-haptic-feedback" react-native-haptic-feedback
"react-native-device-info" react-native-device-info
"react-native-push-notification" react-native-push-notification
"react-native-linear-gradient" react-native-gradien
"@react-native-community/masked-view" masked-view
"react-native-blob-util" react-native-blob-util
"react-native-navigation" react-native-navigation
"react-native-languages" react-native-languages
"react-native-background-timer" background-timer
"react-native-image-crop-picker" image-crop-picker
"react-native-gesture-handler" react-native-gesture-handler
"react-native-safe-area-context" safe-area-context
"react-native-config" config
"react-native-iphone-x-helper" (clj->js {:getStatusBarHeight (fn [])
:getBottomSpace (fn [])})
"react-native-screens" (clj->js {})
"react-native-reanimated" react-native-reanimated
"react-native-redash/lib/module/v1" react-native-redash
"react-native-fetch-polyfill" fetch
"react-native-status-keycard" status-keycard
"react-native-keychain" keychain
"react-native-touch-id" touchid
"@react-native-community/netinfo" net-info
"react-native-dialogs" dialogs
"react-native" react-native
"react-native-fs" fs
"react-native-mail" react-native-mail
"react-native-image-resizer" image-resizer
"react-native-haptic-feedback" react-native-haptic-feedback
"react-native-device-info" react-native-device-info
"react-native-push-notification" react-native-push-notification
"react-native-linear-gradient" react-native-gradien
"@react-native-community/masked-view" masked-view
"react-native-blob-util" react-native-blob-util
"react-native-navigation" react-native-navigation
"@react-native-community/push-notification-ios" push-notification-ios
"@react-native-community/blur" react-native-blur
"@react-native-community/cameraroll" react-native-camera-roll
"react-native-camera-kit" react-native-camera-kit
"react-native-permissions" react-native-permissions
"rn-emoji-keyboard" rn-emoji-keyboard
"react-native-hole-view" react-native-hole-view
"react-native-draggable-flatlist" react-native-draggable-flatlist
"react-native-webview" react-native-webview
"@react-native-community/audio-toolkit" react-native-audio-toolkit
"react-native-image-viewing" react-native-image-viewing
"react-native-share" react-native-share
"@react-native-async-storage/async-storage" async-storage
"react-native-svg" react-native-svg
"../src/js/worklet_factory.js" worklet-factory
"../src/js/shell_worklets.js" shell-worklets
"../src/js/bottom_sheet.js" bottom-sheet
"../src/js/record_audio_worklets.js" record-audio-worklets
"./fleets.js" default-fleets
"./chats.js" default-chats
"@walletconnect/client" wallet-connect-client
"../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json"))
"../translations/de.json" (js/JSON.parse (slurp "./translations/de.json"))
"../translations/en.json" (js/JSON.parse (slurp "./translations/en.json"))
"../translations/es.json" (js/JSON.parse (slurp "./translations/es.json"))
"../translations/es_419.json" (js/JSON.parse (slurp "./translations/es_419.json"))
"../translations/fil.json" (js/JSON.parse (slurp "./translations/fil.json"))
"../translations/fr.json" (js/JSON.parse (slurp "./translations/fr.json"))
"../translations/id.json" (js/JSON.parse (slurp "./translations/id.json"))
"../translations/it.json" (js/JSON.parse (slurp "./translations/it.json"))
"../translations/ko.json" (js/JSON.parse (slurp "./translations/ko.json"))
"../translations/pt_BR.json" (js/JSON.parse (slurp "./translations/pt_BR.json"))
"../translations/ru.json" (js/JSON.parse (slurp "./translations/ru.json"))
"../translations/tr.json" (js/JSON.parse (slurp "./translations/tr.json"))
"../translations/zh.json" (js/JSON.parse (slurp "./translations/zh.json"))
"../translations/zh_hant.json" (js/JSON.parse (slurp "./translations/zh_hant.json"))
"../translations/zh_TW.json" (js/JSON.parse (slurp "./translations/zh_TW.json"))
"@react-native-community/blur" react-native-blur
"@react-native-community/cameraroll" react-native-camera-roll
"react-native-camera-kit" react-native-camera-kit
"react-native-permissions" react-native-permissions
"rn-emoji-keyboard" rn-emoji-keyboard
"react-native-hole-view" react-native-hole-view
"react-native-draggable-flatlist" react-native-draggable-flatlist
"react-native-webview" react-native-webview
"@react-native-community/audio-toolkit" react-native-audio-toolkit
"react-native-image-viewing" react-native-image-viewing
"react-native-share" react-native-share
"@react-native-async-storage/async-storage" async-storage
"react-native-svg" react-native-svg
"../src/js/worklet_factory.js" worklet-factory
"../src/js/shell_worklets.js" shell-worklets
"./fleets.js" default-fleets
"./chats.js" default-chats
"@walletconnect/client" wallet-connect-client
"../translations/ar.json" (js/JSON.parse (slurp "./translations/ar.json"))
"../translations/de.json" (js/JSON.parse (slurp "./translations/de.json"))
"../translations/en.json" (js/JSON.parse (slurp "./translations/en.json"))
"../translations/es.json" (js/JSON.parse (slurp "./translations/es.json"))
"../translations/es_419.json" (js/JSON.parse (slurp "./translations/es_419.json"))
"../translations/fil.json" (js/JSON.parse (slurp "./translations/fil.json"))
"../translations/fr.json" (js/JSON.parse (slurp "./translations/fr.json"))
"../translations/id.json" (js/JSON.parse (slurp "./translations/id.json"))
"../translations/it.json" (js/JSON.parse (slurp "./translations/it.json"))
"../translations/ko.json" (js/JSON.parse (slurp "./translations/ko.json"))
"../translations/pt_BR.json" (js/JSON.parse (slurp "./translations/pt_BR.json"))
"../translations/ru.json" (js/JSON.parse (slurp "./translations/ru.json"))
"../translations/tr.json" (js/JSON.parse (slurp "./translations/tr.json"))
"../translations/zh.json" (js/JSON.parse (slurp "./translations/zh.json"))
"../translations/zh_hant.json" (js/JSON.parse (slurp "./translations/zh_hant.json"))
"../translations/zh_TW.json" (js/JSON.parse (slurp "./translations/zh_TW.json"))
nil))
+58 -88
View File
@@ -1,12 +1,12 @@
(ns quo.animated
(:refer-clojure :exclude [abs set delay divide])
(:require ["react-native-reanimated" :default animated :refer (clockRunning EasingNode)]
["react-native-redash/lib/module/v1" :as redash]
[oops.core :refer [ocall oget]]
[quo.gesture-handler :as gh]
quo.react
(:require [reagent.core :as reagent]
[quo.react-native :as rn]
[reagent.core :as reagent])
[quo.gesture-handler :as gh]
[oops.core :refer [oget ocall]]
["react-native-reanimated" :default animated :refer (clockRunning EasingNode)]
["react-native-redash/lib/module/v1" :as redash]
quo.react)
(:require-macros [quo.react :refer [maybe-js-deps]]))
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent animated)))
@@ -15,10 +15,9 @@
(def text (reagent/adapt-react-class (.-Text animated)))
(def scroll-view (reagent/adapt-react-class (.-ScrollView animated)))
(def code (reagent/adapt-react-class (.-Code animated)))
(def animated-flat-list (create-animated-component gh/flat-list-raw))
(def animated-flat-list (create-animated-component gh/flat-list-raw))
(defn flat-list
[props]
(defn flat-list [props]
[animated-flat-list (rn/base-list-props props)])
(def useCode (.-useCode animated))
@@ -59,42 +58,37 @@
(def bezier (.-bezier ^js EasingNode))
(def linear (.-linear ^js EasingNode))
(def easings
{:linear linear
:ease-in (bezier 0.42 0 1 1)
:ease-out (bezier 0 0 0.58 1)
:ease-in-out (bezier 0.42 0 0.58 1)
:cubic (bezier 0.55 0.055 0.675 0.19)
:keyboard (bezier 0.17 0.59 0.4 0.77)})
(def easings {:linear linear
:ease-in (bezier 0.42 0 1 1)
:ease-out (bezier 0 0 0.58 1)
:ease-in-out (bezier 0.42 0 0.58 1)
:cubic (bezier 0.55 0.055 0.675 0.19)
:keyboard (bezier 0.17 0.59 0.4 0.77)})
(def springs
{:lazy {:damping 50
:mass 0.3
:stiffness 120
:overshootClamping true
:bouncyFactor 1}
:jump {:damping 13
:mass 0.5
:stiffness 170
:overshootClamping false
:bouncyFactor 1
:restSpeedThreshold 0.001
:restDisplacementThreshold 0.001}})
(def springs {:lazy {:damping 50
:mass 0.3
:stiffness 120
:overshootClamping true
:bouncyFactor 1}
:jump {:damping 13
:mass 0.5
:stiffness 170
:overshootClamping false
:bouncyFactor 1
:restSpeedThreshold 0.001
:restDisplacementThreshold 0.001}})
(defn set-value
[anim val]
(defn set-value [anim val]
(ocall anim "setValue" val))
(def Value (oget animated "Value"))
(defn value
[x]
(defn value [x]
(new Value x))
(def Clock (oget animated "Clock"))
(defn clock
[]
(defn clock []
(new Clock))
(def debug (oget animated "debug"))
@@ -106,10 +100,8 @@
([config options]
(ocall animated "event" (clj->js config) (clj->js options))))
(defn on-change
[state node]
(ocall animated
"onChange"
(defn on-change [state node]
(ocall animated "onChange"
state
(if (vector? node)
(clj->js node)
@@ -132,31 +124,24 @@
(clj->js else-node)
else-node))))
(defn block
[opts]
(defn block [opts]
(.block ^js animated (to-array opts)))
(defn interpolate
[anim-value config]
(defn interpolate [anim-value config]
(.interpolateNode ^js animated anim-value (clj->js config)))
(defn call*
[args callback]
(defn call* [args callback]
(.call ^js animated (to-array args) callback))
(defn timing
[clock-value opts config]
(defn timing [clock-value opts config]
(.timing ^js animated
clock-value
(clj->js opts)
(clj->js config)))
(defn spring
[clock-value opts config]
(.spring ^js animated
clock-value
(clj->js opts)
(clj->js config)))
(defn spring [clock-value opts config]
(.spring ^js animated clock-value
(clj->js opts) (clj->js config)))
(def extrapolate {:clamp (oget animated "Extrapolate" "CLAMP")})
@@ -165,48 +150,37 @@
(def clamp (oget redash "clamp"))
(def diff-clamp (.-diffClamp ^js redash))
(defn with-spring
[config]
(defn with-spring [config]
(ocall redash "withSpring" (clj->js config)))
(defn with-decay
[config]
(defn with-decay [config]
(.withDecay ^js redash (clj->js config)))
(defn with-offset
[config]
(defn with-offset [config]
(.withOffset ^js redash (clj->js config)))
(defn with-spring-transition
[val config]
(defn with-spring-transition [val config]
(.withSpringTransition ^js redash val (clj->js config)))
(defn with-timing-transition
[val config]
(defn with-timing-transition [val config]
(.withTimingTransition ^js redash val (clj->js config)))
(defn use-spring-transition
[val config]
(defn use-spring-transition [val config]
(.useSpringTransition ^js redash val (clj->js config)))
(defn use-timing-transition
[val config]
(defn use-timing-transition [val config]
(.useTimingTransition ^js redash val (clj->js config)))
(defn re-timing
[config]
(defn re-timing [config]
(.timing ^js redash (clj->js config)))
(defn re-spring
[config]
(defn re-spring [config]
(.spring ^js redash (clj->js config)))
(defn on-scroll
[opts]
(defn on-scroll [opts]
(ocall redash "onScrollEvent" (clj->js opts)))
(defn on-gesture
[opts]
(defn on-gesture [opts]
(let [gesture-event (event #js [#js {:nativeEvent (clj->js opts)}])]
{:onHandlerStateChange gesture-event
:onGestureEvent gesture-event}))
@@ -217,22 +191,19 @@
(def delay (.-delay ^js redash))
(defn loop*
[opts]
(defn loop* [opts]
(ocall redash "loop" (clj->js opts)))
(def use-value (.-useValue ^js redash))
(def use-clock (.-useClock ^js redash))
(defn use-gesture
[opts]
(defn use-gesture [opts]
(let [gesture (.useGestureHandler ^js redash (clj->js opts))]
{:onHandlerStateChange (.-onHandlerStateChange ^js gesture)
:onGestureEvent (.-onGestureEvent ^js gesture)}))
(defn snap-point
[value velocity snap-points]
(defn snap-point [value velocity snap-points]
(.snapPoint ^js redash value velocity (to-array snap-points)))
(defn cancelable-loop
@@ -285,13 +256,12 @@
(set position (add offset val))])
(cond* (and* (eq state (:end gh/states))
(not* animation-over))
[(set position
(re-timing
{:clock c
:easing easing
:duration duration
:from position
:to to}))
[(set position (re-timing
{:clock c
:easing easing
:duration duration
:from position
:to to}))
(cond* (not* (clock-running c))
finish-animation)])
position])))
+29 -33
View File
@@ -1,9 +1,9 @@
(ns quo.components.animated.pressable
(:require [cljs-bean.core :as bean]
[quo.animated :as animated]
[quo.gesture-handler :as gesture-handler]
(:require [quo.animated :as animated]
[quo.react :as react]
[reagent.core :as reagent]))
[reagent.core :as reagent]
[cljs-bean.core :as bean]
[quo.gesture-handler :as gesture-handler]))
(def long-press-duration 500)
(def scale-down-small 0.95)
@@ -54,8 +54,7 @@
:right 0
:position :absolute})
(defn pressable-hooks
[props]
(defn pressable-hooks [props]
(let [{background-color :bgColor
border-radius :borderRadius
border-color :borderColor
@@ -70,24 +69,23 @@
:or {border-radius 0
type "primary"}}
(bean/bean props)
long-press-ref (react/create-ref)
state (animated/use-value (:undetermined gesture-handler/states))
active (animated/eq state (:began gesture-handler/states))
gesture-handler (animated/use-gesture {:state state})
animation (react/use-memo
(fn []
(animated/with-timing-transition active
{:duration (animated/cond* active time-in time-out)
:easing (:ease-in animated/easings)}))
[])
long-press-ref (react/create-ref)
state (animated/use-value (:undetermined gesture-handler/states))
active (animated/eq state (:began gesture-handler/states))
gesture-handler (animated/use-gesture {:state state})
animation (react/use-memo
(fn []
(animated/with-timing-transition active
{:duration (animated/cond* active time-in time-out)
:easing (:ease-in animated/easings)}))
[])
{:keys [background
foreground]}
(react/use-memo
(fn []
(type->animation {:type (keyword type)
:animation animation}))
[type])
handle-press (fn [] (when on-press (on-press)))
foreground]} (react/use-memo
(fn []
(type->animation {:type (keyword type)
:animation animation}))
[type])
handle-press (fn [] (when on-press (on-press)))
long-gesture-handler (react/callback
(fn [^js evt]
(let [gesture-state (-> evt .-nativeEvent .-state)]
@@ -113,9 +111,8 @@
:min-duration-ms long-press-duration
:max-dist 22
:ref long-press-ref}
[animated/view
{:accessible true
:accessibility-label accessibility-label}
[animated/view {:accessible true
:accessibility-label accessibility-label}
[gesture-handler/tap-gesture-handler
(merge gesture-handler
{:shouldCancelWhenOutside true
@@ -123,13 +120,12 @@
:enabled (boolean (and (or on-press on-long-press on-press-start)
(not disabled)))})
[animated/view
[animated/view
{:style (merge absolute-fill
background
{:background-color background-color
:border-radius border-radius
:border-color border-color
:border-width border-width})}]
[animated/view {:style (merge absolute-fill
background
{:background-color background-color
:border-radius border-radius
:border-color border-color
:border-width border-width})}]
(into [animated/view {:style foreground}]
(react/get-children children))]]]])))
+45 -58
View File
@@ -7,8 +7,7 @@
[quo.platform :as platform]
[reagent.core :as reagent]))
(defn header-wrapper-style
[{:keys [value offset]}]
(defn header-wrapper-style [{:keys [value offset]}]
(merge
{:background-color (:ui-background @colors/theme)}
(when (and offset platform/android?)
@@ -28,78 +27,66 @@
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})))
(defn title-style
[layout]
{:flex 1
(defn title-style [layout]
{:flex 1
:justify-content :center
:padding-right (get-in layout [:right :width])})
:padding-right (get-in layout [:right :width])})
(defn header-container
[]
(defn header-container []
(let [y (animated/value 0)
animation-value (animated/value 0)
animation (animated/with-timing-transition
animation-value
{:duration 250
:easing (:ease-in animated/easings)})
animation-value
{:duration 250
:easing (:ease-in animated/easings)})
on-scroll (animated/on-scroll {:y y})
layout (reagent/atom {})
offset (reagent/atom 0)
on-layout (fn [evt]
(reset! offset (oget evt "nativeEvent" "layout" "height")))]
(fn [{:keys [extended-header refresh-control refreshing-sub refreshing-counter] :as props} children]
[animated/view
{:flex 1
:pointer-events :box-none}
[animated/code
{:key (str @offset)
:exec (animated/cond*
(animated/and* (animated/greater-or-eq y @offset)
(animated/greater-or-eq y 1))
(animated/set animation-value 1)
(animated/set animation-value 0))}]
[animated/view
{:pointer-events :box-none
:style (header-wrapper-style {:value y
:offset @offset})}
[header/header
(merge
{:get-layout (fn [el l] (swap! layout assoc el l))
:border-bottom false
:title-component [animated/view {:style (title-style @layout)}
[extended-header
{:value y
:animation animation
:minimized true
:offset @offset}]]
:title-align :left}
(dissoc props :extended-header))]]
(into [animated/scroll-view
{:on-scroll on-scroll
:refreshControl (when refresh-control
(refresh-control
(and @refreshing-sub
@refreshing-counter)))
:style {:z-index 1}
:scrollEventThrottle 16}
[animated/view {:flex 1
:pointer-events :box-none}
[animated/code {:key (str @offset)
:exec (animated/cond*
(animated/and* (animated/greater-or-eq y @offset)
(animated/greater-or-eq y 1))
(animated/set animation-value 1)
(animated/set animation-value 0))}]
[animated/view {:pointer-events :box-none
:style (header-wrapper-style {:value y
:offset @offset})}
[header/header (merge
{:get-layout (fn [el l] (swap! layout assoc el l))
:border-bottom false
:title-component [animated/view {:style (title-style @layout)}
[extended-header {:value y
:animation animation
:minimized true
:offset @offset}]]
:title-align :left}
(dissoc props :extended-header))]]
(into [animated/scroll-view {:on-scroll on-scroll
:refreshControl (when refresh-control
(refresh-control
(and @refreshing-sub
@refreshing-counter)))
:style {:z-index 1}
:scrollEventThrottle 16}
[animated/view {:pointer-events :box-none}
[animated/view
{:pointer-events :box-none
:on-layout on-layout}
[extended-header
{:value y
:animation animation
:offset @offset}]]]]
[animated/view {:pointer-events :box-none
:on-layout on-layout}
[extended-header {:value y
:animation animation
:offset @offset}]]]]
children)])))
(defn header
[{:keys [use-insets] :as props} & children]
(defn header [{:keys [use-insets] :as props} & children]
(if use-insets
[safe-area/consumer
(fn [insets]
[header-container
(-> props
(dissoc :use-insets)
(assoc :insets insets))
[header-container (-> props
(dissoc :use-insets)
(assoc :insets insets))
children])]
[header-container props children]))
+7 -8
View File
@@ -15,14 +15,13 @@
:flex 1
:justify-content :flex-end})
(defn backdrop
[]
{:flex 1
:position :absolute
:left 0
:top 0
:right 0
:bottom 0})
(defn backdrop []
{:flex 1
:position :absolute
:left 0
:top 0
:right 0
:bottom 0})
(defn content-container
[window-height]
+110 -127
View File
@@ -1,27 +1,25 @@
(ns quo.components.bottom-sheet.view
(:require [cljs-bean.core :as bean]
(:require [reagent.core :as reagent]
[quo.animated :as animated]
[quo.components.bottom-sheet.style :as styles]
[quo.components.safe-area :as safe-area]
[quo.design-system.colors :as colors]
[quo.gesture-handler :as gesture-handler]
[quo.platform :as platform]
[quo.react :as react]
[quo.react-native :as rn]
[reagent.core :as reagent]))
[quo.react :as react]
[quo.platform :as platform]
[cljs-bean.core :as bean]
[quo.components.safe-area :as safe-area]
[quo.components.bottom-sheet.style :as styles]
[quo.gesture-handler :as gesture-handler]
[quo.design-system.colors :as colors]))
(def opacity-coeff 0.8)
(def close-duration 150)
(def spring-config
{:damping 15
:mass 0.7
:stiffness 150
:overshootClamping false
:restSpeedThreshold 0.1
:restDisplacementThreshold 0.1})
(def spring-config {:damping 15
:mass 0.7
:stiffness 150
:overshootClamping false
:restSpeedThreshold 0.1
:restDisplacementThreshold 0.1})
(defn bottom-sheet-hooks
[props]
(defn bottom-sheet-hooks [props]
(let [{on-cancel :onCancel
disable-drag? :disableDrag?
show-handle? :showHandle?
@@ -33,83 +31,77 @@
backdrop-dismiss? true
back-button-cancel true}}
(bean/bean props)
body-ref (react/create-ref)
body-ref (react/create-ref)
master-ref (react/create-ref)
height (react/state 0)
{window-height :height} (rn/use-window-dimensions)
height (react/state 0)
{window-height :height} (rn/use-window-dimensions)
{:keys [keyboard-shown
keyboard-height]}
(rn/use-keyboard)
keyboard-height-android-delta
(if (and platform/android? keyboard-shown) (+ keyboard-height 20) 0)
safe-area (safe-area/use-safe-area)
window-height (- window-height
(if platform/android?
(+ 50 keyboard-height-android-delta) ;; TODO : remove 50 when
;; react-native-navigation v8 will be
;; implemented
;; https://github.com/wix/react-native-navigation/issues/7225
0))
min-height (+ (* styles/vertical-padding 2) (:bottom safe-area))
max-height (- window-height (:top safe-area))
visible (react/state false)
keyboard-height]} (rn/use-keyboard)
keyboard-height-android-delta (if (and platform/android? keyboard-shown) (+ keyboard-height 20) 0)
safe-area (safe-area/use-safe-area)
window-height (- window-height (if platform/android?
(+ 50 keyboard-height-android-delta) ;; TODO : remove 50 when react-native-navigation v8 will be implemented https://github.com/wix/react-native-navigation/issues/7225
0))
min-height (+ (* styles/vertical-padding 2) (:bottom safe-area))
max-height (- window-height (:top safe-area))
visible (react/state false)
master-translation-y (animated/use-value 0)
master-velocity-y (animated/use-value (:undetermined gesture-handler/states))
master-state (animated/use-value (:undetermined gesture-handler/states))
tap-state (animated/use-value 0)
manual-open (animated/use-value 0)
manual-close (animated/use-value 0)
offset (animated/use-value 0)
drag-over (animated/use-value 1)
clock (animated/use-clock)
tap-gesture-handler (animated/use-gesture {:state tap-state})
on-master-event (animated/use-gesture
{:translationY master-translation-y
:state master-state
:velocityY master-velocity-y})
on-body-event on-master-event
sheet-height (min max-height
(+ styles/border-radius @height))
master-velocity-y (animated/use-value (:undetermined gesture-handler/states))
master-state (animated/use-value (:undetermined gesture-handler/states))
tap-state (animated/use-value 0)
manual-open (animated/use-value 0)
manual-close (animated/use-value 0)
offset (animated/use-value 0)
drag-over (animated/use-value 1)
clock (animated/use-clock)
tap-gesture-handler (animated/use-gesture {:state tap-state})
on-master-event (animated/use-gesture
{:translationY master-translation-y
:state master-state
:velocityY master-velocity-y})
on-body-event on-master-event
sheet-height (min max-height
(+ styles/border-radius @height))
open-snap-point (animated/use-value 0)
open-snap-point (animated/use-value 0)
close-snap-point 0
on-close (fn []
(when @visible
(reset! visible false)
(reset! height 0)
(when on-cancel
(on-cancel))))
close-sheet (fn []
(animated/set-value manual-close 1))
on-snap (fn [pos]
(when (= close-snap-point (aget pos 0))
(on-close)))
interrupted (animated/and* (animated/eq master-state (:began gesture-handler/states))
(animated/clock-running clock))
translate-y (react/use-memo
(fn []
(animated/with-easing
{:value (animated/cond* (animated/less-or-eq master-translation-y 0)
(animated/divide master-translation-y 2)
master-translation-y)
:velocity master-velocity-y
:offset offset
:state master-state
:animation-over drag-over
:snap-points [open-snap-point close-snap-point]}))
[])
opacity (react/use-memo
(fn []
(animated/cond*
open-snap-point
(animated/interpolate
translate-y
{:inputRange [(animated/multiply open-snap-point opacity-coeff) 0]
:outputRange [1 0]
:extrapolate (:clamp animated/extrapolate)})))
[])]
on-close (fn []
(when @visible
(reset! visible false)
(reset! height 0)
(when on-cancel
(on-cancel))))
close-sheet (fn []
(animated/set-value manual-close 1))
on-snap (fn [pos]
(when (= close-snap-point (aget pos 0))
(on-close)))
interrupted (animated/and* (animated/eq master-state (:began gesture-handler/states))
(animated/clock-running clock))
translate-y (react/use-memo
(fn []
(animated/with-easing
{:value (animated/cond* (animated/less-or-eq master-translation-y 0)
(animated/divide master-translation-y 2)
master-translation-y)
:velocity master-velocity-y
:offset offset
:state master-state
:animation-over drag-over
:snap-points [open-snap-point close-snap-point]}))
[])
opacity (react/use-memo
(fn []
(animated/cond*
open-snap-point
(animated/interpolate
translate-y
{:inputRange [(animated/multiply open-snap-point opacity-coeff) 0]
:outputRange [1 0]
:extrapolate (:clamp animated/extrapolate)})))
[])]
(animated/code!
(fn []
(animated/cond* (animated/and* (animated/eq master-state (:end gesture-handler/states))
@@ -185,48 +177,39 @@
(close-sheet)))
[visible?])
(reagent/as-element
[rn/view
{:style styles/container
:pointer-events :box-none}
[gesture-handler/tap-gesture-handler
(merge {:enabled backdrop-dismiss?}
tap-gesture-handler)
[animated/view
{:style (merge (styles/backdrop)
(when platform/ios?
{:opacity opacity
:background-color (:backdrop @colors/theme)}))}]]
[animated/view
{:style (merge (styles/content-container window-height)
{:transform [{:translateY (if (= sheet-height max-height)
(animated/add translate-y
keyboard-height-android-delta)
translate-y)}
{:translateY (* window-height 2)}]})}
[gesture-handler/pan-gesture-handler
(merge on-master-event
{:ref master-ref
:wait-for body-ref
:enabled (not disable-drag?)})
[animated/view {:style styles/content-header}
[rn/view {:style styles/container
:pointer-events :box-none}
[gesture-handler/tap-gesture-handler (merge {:enabled backdrop-dismiss?}
tap-gesture-handler)
[animated/view {:style (merge (styles/backdrop)
(when platform/ios?
{:opacity opacity
:background-color (:backdrop @colors/theme)}))}]]
[animated/view {:style (merge (styles/content-container window-height)
{:transform [{:translateY (if (= sheet-height max-height)
(animated/add translate-y keyboard-height-android-delta)
translate-y)}
{:translateY (* window-height 2)}]})}
[gesture-handler/pan-gesture-handler (merge on-master-event
{:ref master-ref
:wait-for body-ref
:enabled (not disable-drag?)})
[animated/view {:style styles/content-header}
(when show-handle?
[rn/view {:style styles/handle}])]]
[gesture-handler/pan-gesture-handler
(merge on-body-event
{:ref body-ref
:wait-for master-ref
:enabled (and (not disable-drag?)
(not= sheet-height max-height))})
[animated/view
{:height sheet-height
:flex 1}
[animated/view
{:style {:padding-top styles/vertical-padding
:padding-bottom (+ styles/vertical-padding
(if (and platform/ios? keyboard-shown)
keyboard-height
(:bottom safe-area)))}
:on-layout #(reset! height (.-nativeEvent.layout.height ^js %))}
[gesture-handler/pan-gesture-handler (merge on-body-event
{:ref body-ref
:wait-for master-ref
:enabled (and (not disable-drag?)
(not= sheet-height max-height))})
[animated/view {:height sheet-height
:flex 1}
[animated/view {:style {:padding-top styles/vertical-padding
:padding-bottom (+ styles/vertical-padding
(if (and platform/ios? keyboard-shown)
keyboard-height
(:bottom safe-area)))}
:on-layout #(reset! height (.-nativeEvent.layout.height ^js %))}
(into [:<>]
(react/get-children children))]]]]])))
+48 -54
View File
@@ -1,14 +1,14 @@
(ns quo.components.button.view
(:require [quo.components.animated.pressable :as animation]
[quo.components.text :as text] ;; FIXME:
[quo.react-native :as rn]
[quo.haptic :as haptic]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.haptic :as haptic]
[quo.react-native :as rn]
[quo.components.text :as text]
;; FIXME:
[status-im.ui.components.icons.icons :as icons]))
(defn style-container
[type]
(defn style-container [type]
(merge {:height 44
:align-items :center
:justify-content :center
@@ -19,16 +19,14 @@
:icon {}
nil)))
(defn content-style
[type]
(defn content-style [type]
(case type
:primary (:base spacing/padding-horizontal)
:secondary (:x-tiny spacing/padding-horizontal)
:icon (:tiny spacing/padding-horizontal)
nil))
(defn themes
[theme]
(defn themes [theme]
(case theme
:main {:icon-color (:icon-04 @colors/theme)
:background-color (:interactive-02 @colors/theme)
@@ -56,46 +54,44 @@
:text-color (:text-01 @colors/theme)
:border-color (:ui-01 @colors/theme)}))
(defn button
[{:keys [on-press disabled type theme before after
haptic-feedback haptic-type on-long-press on-press-start
accessibility-label loading border-radius style test-ID]
:or {theme :main
type :primary
haptic-feedback true
border-radius 8
haptic-type :selection}}
children]
(let [theme' (cond
disabled :disabled
:else theme)
(defn button [{:keys [on-press disabled type theme before after
haptic-feedback haptic-type on-long-press on-press-start
accessibility-label loading border-radius style test-ID]
:or {theme :main
type :primary
haptic-feedback true
border-radius 8
haptic-type :selection}}
children]
(let [theme' (cond
disabled :disabled
:else theme)
{:keys [icon-color background-color text-color border-color]}
(themes theme')
optional-haptic (fn []
(when haptic-feedback
(haptic/trigger haptic-type)))]
[animation/pressable
(merge {:bg-color background-color
:border-radius border-radius
:type type
:disabled disabled
:accessibility-label accessibility-label}
(when border-color
{:border-color border-color
:border-width 1})
(when on-press
{:on-press (fn []
(optional-haptic)
(on-press))})
(when on-long-press
{:on-long-press (fn []
(optional-haptic)
(on-long-press))})
(when on-press-start
{:on-press-start (fn []
(optional-haptic)
(on-press-start))}))
optional-haptic (fn []
(when haptic-feedback
(haptic/trigger haptic-type)))]
[animation/pressable (merge {:bg-color background-color
:border-radius border-radius
:type type
:disabled disabled
:accessibility-label accessibility-label}
(when border-color
{:border-color border-color
:border-width 1})
(when on-press
{:on-press (fn []
(optional-haptic)
(on-press))})
(when on-long-press
{:on-long-press (fn []
(optional-haptic)
(on-long-press))})
(when on-press-start
{:on-press-start (fn []
(optional-haptic)
(on-press-start))}))
[rn/view {:test-ID test-ID :style (merge (style-container type) style)}
(when before
[rn/view
@@ -103,19 +99,17 @@
(when loading
[rn/view {:style {:position :absolute}}
[rn/activity-indicator]])
[rn/view
{:style (merge (content-style type)
(when loading
{:opacity 0}))}
[rn/view {:style (merge (content-style type)
(when loading
{:opacity 0}))}
(cond
(= type :icon)
[icons/icon children {:color icon-color}]
(string? children)
[text/text
{:weight :medium
:number-of-lines 1
:style {:color text-color}}
[text/text {:weight :medium
:number-of-lines 1
:style {:color text-color}}
children]
(vector? children)
+10 -18
View File
@@ -2,8 +2,7 @@
(:require [quo.animated :as animated]
[quo.design-system.colors :as colors]))
(defn switch-style
[state disabled]
(defn switch-style [state disabled]
{:width 52
:height 28
:border-radius 14
@@ -14,8 +13,7 @@
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme)))})
(defn switch-bullet-style
[state hold]
(defn switch-bullet-style [state hold]
{:width 20
:height 20
:border-radius 10
@@ -28,8 +26,7 @@
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn radio-style
[state disabled]
(defn radio-style [state disabled]
{:width 20
:height 20
:border-radius 10
@@ -40,8 +37,7 @@
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme)))})
(defn radio-bullet-style
[state hold]
(defn radio-bullet-style [state hold]
{:width 12
:height 12
:border-radius 6
@@ -54,8 +50,7 @@
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn animated-checkbox-style
[state disabled]
(defn animated-checkbox-style [state disabled]
{:width 18
:height 18
:border-radius 4
@@ -67,8 +62,7 @@
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme)))})
(defn checkbox-style
[value disabled]
(defn checkbox-style [value disabled]
{:width 18
:height 18
:border-radius 4
@@ -80,11 +74,9 @@
(:interactive-01 @colors/theme))
(:ui-01 @colors/theme))})
(defn animated-check-icon-style
[state hold]
{:opacity (animated/mix hold 1 0.6)
:transform [{:scale (animated/mix state 0.0001 1)}]})
(defn animated-check-icon-style [state hold]
{:opacity (animated/mix hold 1 0.6)
:transform [{:scale (animated/mix state 0.0001 1)}]})
(defn check-icon-style
[value]
(defn check-icon-style [value]
{:opacity (if value 1 0)})
+42 -54
View File
@@ -1,37 +1,34 @@
(ns quo.components.controls.view
(:require [cljs-bean.core :as bean]
[quo.animated :as animated]
[quo.components.controls.styles :as styles]
[quo.design-system.colors :as colors]
[quo.gesture-handler :as gh]
(:require [reagent.core :as reagent]
[cljs-bean.core :as bean]
[quo.react :as react]
[quo.react-native :as rn]
[reagent.core :as reagent]
[quo.animated :as animated]
[quo.gesture-handler :as gh]
[quo.design-system.colors :as colors]
[quo.components.controls.styles :as styles]
[status-im.ui.components.icons.icons :as icons]))
(defn control-builder
[component]
(defn control-builder [component]
(fn [props]
(let [{:keys [value onChange disabled]}
(bean/bean props)
state (animated/use-value 0)
tap-state (animated/use-value (:undetermined gh/states))
tap-handler (animated/on-gesture {:state tap-state})
hold (react/use-memo
(fn []
(animated/with-timing-transition
(animated/eq tap-state (:began gh/states))
{}))
[])
transition (react/use-memo
(fn []
(animated/with-spring-transition state
(:lazy
animated/springs)))
[])
press-end (fn []
(when (and (not disabled) onChange)
(onChange (not value))))]
state (animated/use-value 0)
tap-state (animated/use-value (:undetermined gh/states))
tap-handler (animated/on-gesture {:state tap-state})
hold (react/use-memo
(fn []
(animated/with-timing-transition
(animated/eq tap-state (:began gh/states))
{}))
[])
transition (react/use-memo
(fn []
(animated/with-spring-transition state (:lazy animated/springs)))
[])
press-end (fn []
(when (and (not disabled) onChange)
(onChange (not value))))]
(animated/code!
(fn []
(animated/cond* (animated/eq tap-state (:end gh/states))
@@ -44,47 +41,38 @@
(animated/set state (if (true? value) 1 0)))
[value])
(reagent/as-element
[gh/tap-gesture-handler
(merge tap-handler
{:shouldCancelWhenOutside true
:enabled (boolean (and onChange (not disabled)))})
[gh/tap-gesture-handler (merge tap-handler
{:shouldCancelWhenOutside true
:enabled (boolean (and onChange (not disabled)))})
[animated/view
[component
{:transition transition
:hold hold
:disabled disabled}]]]))))
[component {:transition transition
:hold hold
:disabled disabled}]]]))))
(defn switch-view
[{:keys [transition hold disabled value]}]
[animated/view
{:style (styles/switch-style transition disabled)
:accessibility-label (str "switch-" (if value "on" "off"))
:accessibility-role :switch}
(defn switch-view [{:keys [transition hold disabled value]}]
[animated/view {:style (styles/switch-style transition disabled)
:accessibility-label (str "switch-" (if value "on" "off"))
:accessibility-role :switch}
[animated/view {:style (styles/switch-bullet-style transition hold)}]])
(defn radio-view
[{:keys [transition hold disabled value]}]
[animated/view
{:style (styles/radio-style transition disabled)
:accessibility-label (str "radio-" (if value "on" "off"))
:accessibility-role :radio}
(defn radio-view [{:keys [transition hold disabled value]}]
[animated/view {:style (styles/radio-style transition disabled)
:accessibility-label (str "radio-" (if value "on" "off"))
:accessibility-role :radio}
[animated/view {:style (styles/radio-bullet-style transition hold)}]])
(defn checkbox-view
[props]
(defn checkbox-view [props]
(let [{:keys [value onChange disabled]} (bean/bean props)]
(reagent/as-element
[rn/touchable-without-feedback
{:on-press (when (and onChange (not disabled)) onChange)}
[rn/view
{:style (styles/checkbox-style value disabled)
:accessibility-label (str "checkbox-" (if value "on" "off"))
:accessibility-role :checkbox}
[rn/view {:style (styles/checkbox-style value disabled)
:accessibility-label (str "checkbox-" (if value "on" "off"))
:accessibility-role :checkbox}
[rn/view {:style (styles/check-icon-style value)}
[icons/tiny-icon :tiny-icons/tiny-check {:color colors/white}]]]])))
(defn animated-checkbox-view
[{:keys [transition hold disabled value]}]
(defn animated-checkbox-view [{:keys [transition hold disabled value]}]
[animated/view
{:style (styles/animated-checkbox-style transition disabled)
:accessibility-label (str "checkbox-" (if value "on" "off"))
+93 -123
View File
@@ -10,8 +10,7 @@
(def header-height 56)
(defn header-wrapper-style
[{:keys [height border-bottom background]}]
(defn header-wrapper-style [{:keys [height border-bottom background]}]
(merge
(:x-tiny spacing/padding-horizontal)
{:background-color (:ui-background @colors/theme)
@@ -22,37 +21,32 @@
{:border-bottom-width 1
:border-bottom-color (:ui-01 @colors/theme)})))
(def absolute-fill
{:position :absolute
:top 0
:bottom 0
:left 0
:right 0})
(def absolute-fill {:position :absolute
:top 0
:bottom 0
:left 0
:right 0})
(def content
{:flex 1
:flex-direction :row
:align-items :center
:justify-content :center})
(def content {:flex 1
:flex-direction :row
:align-items :center
:justify-content :center})
(def left
{:position :absolute
:left 0
:top 0
:bottom 0
:justify-content :center
:align-items :flex-start})
(def left {:position :absolute
:left 0
:top 0
:bottom 0
:justify-content :center
:align-items :flex-start})
(def right
{:position :absolute
:right 0
:top 0
:bottom 0
:justify-content :center
:align-items :flex-end})
(def right {:position :absolute
:right 0
:top 0
:bottom 0
:justify-content :center
:align-items :flex-end})
(defn title-style
[{:keys [left right]} title-align]
(defn title-style [{:keys [left right]} title-align]
(merge
absolute-fill
(case title-align
@@ -65,75 +59,66 @@
(def header-actions-style
(merge
{:flex 1
:flex-direction :row
:align-items :center
:justify-content :center}
{:flex 1
:flex-direction :row
:align-items :center
:justify-content :center}
(:x-tiny spacing/padding-horizontal)))
(def header-action-placeholder
{:width (:base spacing/spacing)})
(def element
{:align-items :center
:justify-content :center
:flex 1})
(def element {:align-items :center
:justify-content :center
:flex 1})
(defn header-action
[{:keys [icon label on-press disabled accessibility-label]}]
[button/button
(merge {:on-press on-press
:disabled disabled}
(cond
icon {:type :icon
:theme :icon}
label {:type :secondary})
(when accessibility-label
{:accessibility-label accessibility-label}))
(defn header-action [{:keys [icon label on-press disabled accessibility-label]}]
[button/button (merge {:on-press on-press
:disabled disabled}
(cond
icon {:type :icon
:theme :icon}
label {:type :secondary})
(when accessibility-label
{:accessibility-label accessibility-label}))
(cond
icon icon
label label)])
(defn header-actions
[{:keys [accessories component]}]
(defn header-actions [{:keys [accessories component]}]
[rn/view {:style element}
(cond
(seq accessories)
(into [rn/view {:style header-actions-style}]
(map header-action accessories))
component component
component component
:else
[rn/view {:style header-action-placeholder}])])
(defn header-title
[{:keys [title subtitle component title-align]}]
(defn header-title [{:keys [title subtitle component title-align]}]
[:<>
(cond
component component
component component
(and title subtitle)
[:<>
[text/text
{:weight :medium
:number-of-lines 1}
[text/text {:weight :medium
:number-of-lines 1}
title]
[text/text
{:weight :regular
:color :secondary
:number-of-lines 1}
[text/text {:weight :regular
:color :secondary
:number-of-lines 1}
subtitle]]
title [text/text
{:weight :bold
:number-of-lines 0
:align title-align
:size :large}
title])])
title [text/text {:weight :bold
:number-of-lines 0
:align title-align
:size :large}
title])])
(defn header
[{:keys [left-width right-width]}]
(defn header [{:keys [left-width right-width]}]
(let [layout (reagent/atom {:left {:width (or left-width 8)
:height header-height}
:right {:width (or right-width 8)
@@ -145,61 +130,46 @@
(let [width (oget evt "nativeEvent" "layout" "width")
height (oget evt "nativeEvent" "layout" "height")]
(when get-layout
(get-layout el
{:width width
:height height}))
(swap! layout assoc
el
{:width width
:height height}))))]
(fn
[{:keys [left-accessories left-component border-bottom
right-accessories right-component insets get-layout
title subtitle title-component style title-align
background]
:or {title-align :center
border-bottom true}}]
(get-layout el {:width width
:height height}))
(swap! layout assoc el {:width width
:height height}))))]
(fn [{:keys [left-accessories left-component border-bottom
right-accessories right-component insets get-layout
title subtitle title-component style title-align
background]
:or {title-align :center
border-bottom true}}]
(let [status-bar-height (get insets :top 0)
height (+ header-height status-bar-height)]
[animated/view
{:style (header-wrapper-style {:height height
:background background
:border-bottom border-bottom})}
[rn/view
{:pointer-events :box-none
:height status-bar-height}]
[rn/view
{:style (merge {:height header-height}
style)
:pointer-events :box-none}
[rn/view
{:style absolute-fill
:pointer-events :box-none}
[rn/view
{:style content
:pointer-events :box-none}
[rn/view
{:style left
:on-layout (handle-layout :left get-layout)
:pointer-events :box-none}
[header-actions
{:accessories left-accessories
:component left-component}]]
[animated/view {:style (header-wrapper-style {:height height
:background background
:border-bottom border-bottom})}
[rn/view {:pointer-events :box-none
:height status-bar-height}]
[rn/view {:style (merge {:height header-height}
style)
:pointer-events :box-none}
[rn/view {:style absolute-fill
:pointer-events :box-none}
[rn/view {:style content
:pointer-events :box-none}
[rn/view {:style left
:on-layout (handle-layout :left get-layout)
:pointer-events :box-none}
[header-actions {:accessories left-accessories
:component left-component}]]
[rn/view
{:style (title-style @layout title-align)
:on-layout (handle-layout :title get-layout)
:pointer-events :box-none}
[header-title
{:title title
:subtitle subtitle
:title-align title-align
:component title-component}]]
[rn/view {:style (title-style @layout title-align)
:on-layout (handle-layout :title get-layout)
:pointer-events :box-none}
[header-title {:title title
:subtitle subtitle
:title-align title-align
:component title-component}]]
[rn/view
{:style right
:on-layout (handle-layout :right get-layout)
:pointer-events :box-none}
[header-actions
{:accessories right-accessories
:component right-component}]]]]]]))))
[rn/view {:style right
:on-layout (handle-layout :right get-layout)
:pointer-events :box-none}
[header-actions {:accessories right-accessories
:component right-component}]]]]]]))))
+7 -10
View File
@@ -1,17 +1,14 @@
(ns quo.components.list.footer
(:require [quo.components.text :as text]
(:require [quo.react-native :as rn]
[quo.design-system.spacing :as spacing]
[quo.react-native :as rn]
[quo.components.text :as text]
[reagent.core :as reagent]))
(defn footer
[]
(let [this (reagent/current-component)
(defn footer []
(let [this (reagent/current-component)
{:keys [color]
:or {color :secondary}}
(reagent/props this)]
[rn/view
{:style (merge (:base spacing/padding-horizontal)
(:small spacing/padding-vertical))}
:or {color :secondary}} (reagent/props this)]
[rn/view {:style (merge (:base spacing/padding-horizontal)
(:small spacing/padding-vertical))}
(into [text/text {:color color}]
(reagent/children this))]))
+10 -14
View File
@@ -1,19 +1,15 @@
(ns quo.components.list.header
(:require [quo.components.text :as text]
[quo.design-system.spacing :as spacing]
(:require [reagent.core :as reagent]
[quo.react-native :as rn]
[reagent.core :as reagent]))
[quo.design-system.spacing :as spacing]
[quo.components.text :as text]))
(defn header
[]
(let [this (reagent/current-component)
(defn header []
(let [this (reagent/current-component)
{:keys [color]
:or {color :secondary}}
(reagent/props this)]
[rn/view
{:style (merge (:base spacing/padding-horizontal)
(:x-tiny spacing/padding-vertical))}
(into [text/text
{:color color
:style {:margin-top 10}}]
:or {color :secondary}} (reagent/props this)]
[rn/view {:style (merge (:base spacing/padding-horizontal)
(:x-tiny spacing/padding-vertical))}
(into [text/text {:color color
:style {:margin-top 10}}]
(reagent/children this))]))
+12 -14
View File
@@ -1,18 +1,16 @@
(ns quo.components.list.index
(:require [quo.components.text :as text]
[quo.design-system.colors :as colors]
[quo.react-native :as rn]))
(:require [quo.react-native :as rn]
[quo.components.text :as text]
[quo.design-system.colors :as colors]))
(defn index
[{:keys [title]}]
(defn index [{:keys [title]}]
[rn/view {:style {:padding-right 16}}
[rn/view
{:style {:border-top-width 1
:border-bottom-width 1
:border-right-width 1
:border-color (colors/get-color :border-01)
:padding-vertical 3
:padding-horizontal 16
:border-top-right-radius 16
:border-bottom-right-radius 16}}
[rn/view {:style {:border-top-width 1
:border-bottom-width 1
:border-right-width 1
:border-color (colors/get-color :border-01)
:padding-vertical 3
:padding-horizontal 16
:border-top-right-radius 16
:border-bottom-right-radius 16}}
[text/text title]]])
+154 -186
View File
@@ -1,29 +1,28 @@
(ns quo.components.list.item
(:require [quo.components.animated.pressable :as animated]
[quo.components.controls.view :as controls]
[quo.components.text :as text]
[quo.components.tooltip :as tooltip]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.gesture-handler :as gh]
[quo.haptic :as haptic]
(:require [quo.react-native :as rn]
[quo.platform :as platform]
[quo.react-native :as rn]
[status-im.ui.components.icons.icons :as icons]))
[quo.haptic :as haptic]
[quo.gesture-handler :as gh]
[quo.design-system.spacing :as spacing]
[quo.design-system.colors :as colors]
[quo.components.text :as text]
[quo.components.controls.view :as controls]
[quo.components.tooltip :as tooltip]
[status-im.ui.components.icons.icons :as icons]
[quo.components.animated.pressable :as animated]))
(defn themes
[theme]
(defn themes [theme]
(case theme
:main {:icon-color (:icon-04 @colors/theme)
:icon-bg-color (:interactive-02 @colors/theme)
:active-background (:interactive-02 @colors/theme)
:passive-background (:ui-background @colors/theme)
:text-color (:text-01 @colors/theme)}
:accent {:icon-color (:icon-04 @colors/theme)
:icon-bg-color (:interactive-02 @colors/theme)
:active-background (:interactive-02 @colors/theme)
:passive-background (:ui-background @colors/theme)
:text-color (:text-04 @colors/theme)}
:main {:icon-color (:icon-04 @colors/theme)
:icon-bg-color (:interactive-02 @colors/theme)
:active-background (:interactive-02 @colors/theme)
:passive-background (:ui-background @colors/theme)
:text-color (:text-01 @colors/theme)}
:accent {:icon-color (:icon-04 @colors/theme)
:icon-bg-color (:interactive-02 @colors/theme)
:active-background (:interactive-02 @colors/theme)
:passive-background (:ui-background @colors/theme)
:text-color (:text-04 @colors/theme)}
:negative {:icon-color (:negative-01 @colors/theme)
:icon-bg-color (:negative-02 @colors/theme)
:active-background (:negative-02 @colors/theme)
@@ -40,34 +39,28 @@
:passive-background (:ui-background @colors/theme)
:text-color (:text-02 @colors/theme)}))
(defn size->icon-size
[size]
(defn size->icon-size [size]
(case size
:small 36
40))
(defn size->container-size
[size]
(defn size->container-size [size]
(case size
:small 52
64))
(defn size->single-title-size
[size]
(defn size->single-title-size [size]
(case size
:small :base
:large))
(defn container
[{:keys [size container-style]} & children]
(into [rn/view
{:style (merge (:tiny spacing/padding-horizontal)
{:min-height (size->container-size size)
:padding-vertical 8
:flex-direction :row
:align-items :center
:justify-content :space-between}
container-style)}]
(defn container [{:keys [size container-style]} & children]
(into [rn/view {:style (merge (:tiny spacing/padding-horizontal)
{:min-height (size->container-size size)
:padding-vertical 8
:flex-direction :row
:align-items :center
:justify-content :space-between} container-style)}]
children))
(defn icon-column
@@ -79,118 +72,103 @@
(vector? icon)
icon
(keyword? icon)
[rn/view
{:style {:width icon-size
:height icon-size
:align-items :center
:justify-content :center
:border-radius (/ icon-size 2)
:background-color icon-bg-color}}
[rn/view {:style {:width icon-size
:height icon-size
:align-items :center
:justify-content :center
:border-radius (/ icon-size 2)
:background-color icon-bg-color}}
[icons/icon icon {:color icon-color}]])])))
(defn title-column
[{:keys [title text-color subtitle subtitle-max-lines subtitle-secondary
title-accessibility-label size text-size title-text-weight
right-side-present?]}]
[rn/view
{:style (merge (:tiny spacing/padding-horizontal)
;; make left-side title grow if nothing is present on right-side
(when-not right-side-present?
{:flex 1
:justify-content :center}))}
[rn/view {:style (merge (:tiny spacing/padding-horizontal)
;; make left-side title grow if nothing is present on right-side
(when-not right-side-present?
{:flex 1
:justify-content :center}))}
(cond
(and title subtitle)
[:<>
;; FIXME(Ferossgp): ReactNative 63 will support view inside text on andrid, remove thess if when
;; migrating
;; FIXME(Ferossgp): ReactNative 63 will support view inside text on andrid, remove thess if when migrating
(if (string? title)
[text/text
{:weight (or title-text-weight :medium)
:style {:color text-color}
:accessibility-label title-accessibility-label
:ellipsize-mode :tail
:number-of-lines 1
:size text-size}
[text/text {:weight (or title-text-weight :medium)
:style {:color text-color}
:accessibility-label title-accessibility-label
:ellipsize-mode :tail
:number-of-lines 1
:size text-size}
title]
title)
(if (string? subtitle-secondary)
[rn/view {:flex-direction :row}
[text/text
{:style {:max-width "56.5%"}
:weight :regular
:color :secondary
:ellipsize-mode :tail
:number-of-lines subtitle-max-lines
:size text-size}
[text/text {:style {:max-width "56.5%"}
:weight :regular
:color :secondary
:ellipsize-mode :tail
:number-of-lines subtitle-max-lines
:size text-size}
subtitle]
[text/text
{:style {:width "7%" :text-align :center}
:weight :regular
:color :secondary
:ellipsize-mode :middle
:number-of-lines subtitle-max-lines
:size text-size}
[text/text {:style {:width "7%" :text-align :center}
:weight :regular
:color :secondary
:ellipsize-mode :middle
:number-of-lines subtitle-max-lines
:size text-size}
"•"]
[text/text
{:style {:max-width "36.5%"}
:weight :regular
:color :secondary
:ellipsize-mode :middle
:number-of-lines subtitle-max-lines
:size text-size}
[text/text {:style {:max-width "36.5%"}
:weight :regular
:color :secondary
:ellipsize-mode :middle
:number-of-lines subtitle-max-lines
:size text-size}
subtitle-secondary]]
(if (string? subtitle)
[text/text
{:weight :regular
:color :secondary
:ellipsize-mode :tail
:number-of-lines subtitle-max-lines
:size text-size}
[text/text {:weight :regular
:color :secondary
:ellipsize-mode :tail
:number-of-lines subtitle-max-lines
:size text-size}
subtitle]
subtitle))]
title
(if (string? title)
[text/text
{:weight (or title-text-weight :regular)
:number-of-lines 1
:style {:color text-color}
:title-accessibility-label title-accessibility-label
:ellipsize-mode :tail
:size (or text-size (size->single-title-size size))}
[text/text {:weight (or title-text-weight :regular)
:number-of-lines 1
:style {:color text-color}
:title-accessibility-label title-accessibility-label
:ellipsize-mode :tail
:size (or text-size (size->single-title-size size))}
title]
title))])
(defn left-side
[props]
[rn/view
{:style {:flex-direction :row
;; Occupy only content width, never grow, but shrink if need be
:flex-grow 0
:flex-shrink 1
:padding-right 16
:align-items (or (:left-side-alignment props) :center)}}
(defn left-side [props]
[rn/view {:style {:flex-direction :row
;; Occupy only content width, never grow, but shrink if need be
:flex-grow 0
:flex-shrink 1
:padding-right 16
:align-items (or (:left-side-alignment props) :center)}}
[icon-column props]
[title-column props]])
(defn right-side
[{:keys [chevron active disabled accessory accessory-text accessory-style animated-accessory?]}]
(defn right-side [{:keys [chevron active disabled accessory accessory-text accessory-style animated-accessory?]}]
(when (or chevron accessory)
[rn/view
{:style (merge {:align-items :center
:justify-content :flex-end
:flex-direction :row
;; Grow to occupy full space, shrink when need be, but always maitaining 16px left
;; gutter
:flex-grow 1
:flex-shrink 0
:margin-left 16
;; When the left-side leaves no room for right-side, the rendered element is pushed
;; out. A flex-basis ensures that there is some room reserved.
;; The number 80px was determined by trial and error.
:flex-basis 80}
accessory-style)}
[rn/view {:style (merge {:align-items :center
:justify-content :flex-end
:flex-direction :row
;; Grow to occupy full space, shrink when need be, but always maitaining 16px left gutter
:flex-grow 1
:flex-shrink 0
:margin-left 16
;; When the left-side leaves no room for right-side, the rendered element is pushed out. A flex-basis ensures that there is some room reserved.
;; The number 80px was determined by trial and error.
:flex-basis 80}
accessory-style)}
[rn/view {:style (:tiny spacing/padding-horizontal)}
(case accessory
:radio [controls/radio {:value active :disabled disabled}]
@@ -199,28 +177,25 @@
controls/checkbox)
{:value active :disabled disabled}]
:switch [controls/switch {:value active :disabled disabled}]
:text [text/text
{:color :secondary
:ellipsize-mode :middle
:number-of-lines 1}
:text [text/text {:color :secondary
:ellipsize-mode :middle
:number-of-lines 1}
accessory-text]
accessory)]
(when (and chevron platform/ios?)
[rn/view {:style {:padding-right (:tiny spacing/spacing)}}
[icons/icon :main-icons/next
{:container-style {:opacity 0.4
:align-items :center
:justify-content :center}
:resize-mode :center
:color (:icon-02 @colors/theme)}]])]))
[icons/icon :main-icons/next {:container-style {:opacity 0.4
:align-items :center
:justify-content :center}
:resize-mode :center
:color (:icon-02 @colors/theme)}]])]))
(defn list-item
[{:keys [theme accessory disabled subtitle-max-lines icon icon-container-style
left-side-alignment icon-color icon-bg-color
title subtitle subtitle-secondary active on-press on-long-press chevron size text-size
accessory-text accessibility-label title-accessibility-label accessory-style
haptic-feedback haptic-type error animated animated-accessory? title-text-weight
container-style
haptic-feedback haptic-type error animated animated-accessory? title-text-weight container-style
active-background-enabled background-color]
:or {subtitle-max-lines 1
theme :main
@@ -228,29 +203,26 @@
animated platform/ios?
active-background-enabled true
haptic-type :selection}}]
(let [theme (if disabled :disabled theme)
(let [theme (if disabled :disabled theme)
{:keys [text-color active-background passive-background]}
(themes theme)
icon-color (or icon-color
(:icon-color (themes theme)))
icon-bg-color (or icon-bg-color
(:icon-bg-color (themes theme)))
optional-haptic (fn []
(when haptic-feedback
(haptic/trigger haptic-type)))
component (cond
(and (not on-press)
(not on-long-press))
rn/view
animated animated/pressable
:else gh/touchable-highlight)]
[rn/view
{:background-color (cond (not= background-color nil)
background-color
(and (= accessory :radio) active)
active-background
:else
passive-background)}
icon-color (or icon-color (:icon-color (themes theme)))
icon-bg-color (or icon-bg-color (:icon-bg-color (themes theme)))
optional-haptic (fn []
(when haptic-feedback
(haptic/trigger haptic-type)))
component (cond
(and (not on-press)
(not on-long-press))
rn/view
animated animated/pressable
:else gh/touchable-highlight)]
[rn/view {:background-color (cond (not= background-color nil)
background-color
(and (= accessory :radio) active)
active-background
:else
passive-background)}
[component
(merge {:type :list-item
:disabled disabled
@@ -265,39 +237,35 @@
(optional-haptic)
(on-long-press))}))
[container {:size size :container-style container-style}
[left-side
{:icon-color icon-color
:text-color (if on-press
text-color
(:text-color (themes :main)))
:left-side-alignment left-side-alignment
:icon-bg-color icon-bg-color
:title-accessibility-label title-accessibility-label
:icon icon
:icon-container-style icon-container-style
:title title
:title-text-weight title-text-weight
:size size
:text-size text-size
:subtitle subtitle
:subtitle-max-lines subtitle-max-lines
:subtitle-secondary subtitle-secondary
:right-side-present? (or accessory chevron)}]
[right-side
{:chevron chevron
:active active
:disabled disabled
:on-press on-press
:accessory-text accessory-text
:animated-accessory? animated-accessory?
:accessory-style accessory-style
:accessory accessory}]]]
[left-side {:icon-color icon-color
:text-color (if on-press
text-color
(:text-color (themes :main)))
:left-side-alignment left-side-alignment
:icon-bg-color icon-bg-color
:title-accessibility-label title-accessibility-label
:icon icon
:icon-container-style icon-container-style
:title title
:title-text-weight title-text-weight
:size size
:text-size text-size
:subtitle subtitle
:subtitle-max-lines subtitle-max-lines
:subtitle-secondary subtitle-secondary
:right-side-present? (or accessory chevron)}]
[right-side {:chevron chevron
:active active
:disabled disabled
:on-press on-press
:accessory-text accessory-text
:animated-accessory? animated-accessory?
:accessory-style accessory-style
:accessory accessory}]]]
(when error
[tooltip/tooltip
(merge {:bottom-value 0}
(when accessibility-label
{:accessibility-label (str (name accessibility-label) "-error")}))
[text/text
{:color :negative
:size :small}
[tooltip/tooltip (merge {:bottom-value 0}
(when accessibility-label
{:accessibility-label (str (name accessibility-label) "-error")}))
[text/text {:color :negative
:size :small}
error]])]))
+4 -6
View File
@@ -1,21 +1,19 @@
(ns quo.components.safe-area
(:require ["react-native-safe-area-context" :as safe-area-context :refer
(SafeAreaView SafeAreaProvider SafeAreaInsetsContext useSafeAreaInsets)]
(:require ["react-native-safe-area-context" :as safe-area-context
:refer (SafeAreaView SafeAreaProvider SafeAreaInsetsContext useSafeAreaInsets)]
[reagent.core :as reagent]))
(def provider (reagent/adapt-react-class SafeAreaProvider))
(def ^:private consumer-raw (reagent/adapt-react-class (.-Consumer ^js SafeAreaInsetsContext)))
(def view (reagent/adapt-react-class SafeAreaView))
(defn consumer
[component]
(defn consumer [component]
[consumer-raw
(fn [insets]
(reagent/as-element
[component (js->clj insets :keywordize-keys true)]))])
(defn use-safe-area
[]
(defn use-safe-area []
(let [insets (useSafeAreaInsets)]
{:top (.-top ^js insets)
:bottom (.-bottom ^js insets)
+3 -4
View File
@@ -1,9 +1,8 @@
(ns quo.components.separator
(:require [quo.design-system.colors :as colors]
[quo.react-native :as react]))
(:require [quo.react-native :as react]
[quo.design-system.colors :as colors]))
(defn separator
[{:keys [color style]}]
(defn separator [{:keys [color style]}]
[react/view
{:style
(merge
+6 -10
View File
@@ -5,8 +5,7 @@
[quo.react-native :as rn]
[reagent.core :as reagent]))
(defn text-style
[{:keys [size align weight monospace color style]}]
(defn text-style [{:keys [size align weight monospace color style]}]
;; NOTE(Ferossgo): or in destructoring will keep nil as a value
(merge (if monospace
;; TODO(Ferossgp): Add all weights for monospace
@@ -39,15 +38,12 @@
{:text-align (or align :auto)}
style))
(defn text
[]
(defn text []
(let [this (reagent/current-component)
props (reagent/props this)
component (if (:animated? props) animated/text rn/text)]
(into [component
(merge {:style (text-style props)}
(dissoc props
:style :size
:weight :color
:align :animated?))]
(into [component (merge {:style (text-style props)}
(dissoc props
:style :size :weight :color
:align :animated?))]
(reagent/children this))))
+121 -160
View File
@@ -1,15 +1,16 @@
(ns quo.components.text-input
(:require [clojure.spec.alpha :as s]
[oops.core :refer [ocall]]
[quo.components.text :as text]
[quo.components.tooltip :as tooltip]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.design-system.typography :as typography]
[quo.platform :as platform]
[quo.react-native :as rn] ;; TODO(Ferossgp): Move icon component to lib
[reagent.core :as reagent]
[status-im.ui.components.icons.icons :as icons]))
[oops.core :refer [ocall]]
[quo.react-native :as rn]
;; TODO(Ferossgp): Move icon component to lib
[status-im.ui.components.icons.icons :as icons]
[quo.components.tooltip :as tooltip]
[quo.platform :as platform]
[quo.design-system.typography :as typography]
[quo.design-system.spacing :as spacing]
[quo.design-system.colors :as colors]
[quo.components.text :as text]))
;; NOTE(Ferossgp): Refactor with hooks when available
;; We track all currently mounted text input refs
@@ -21,26 +22,19 @@
(s/def ::multiline boolean?)
(s/def ::secure-text-entry boolean?)
(s/def ::show-cancel boolean?)
(s/def ::label
(s/nilable (s/or :string string?
:component vector?)))
(s/def ::label (s/nilable (s/or :string string? :component vector?)))
(s/def ::cancel-label (s/nilable string?))
(s/def ::default-value (s/nilable string?))
(s/def ::placeholder (s/nilable string?))
(s/def ::keyboard-type
(s/nilable (s/or :string string?
:keyword keyword?))) ; TODO: make set
(s/def ::accessibility-label
(s/nilable (s/or :string string?
:keyword keyword?)))
(s/def ::keyboard-type (s/nilable (s/or :string string? :keyword keyword?))) ; TODO: make set
(s/def ::accessibility-label (s/nilable (s/or :string string? :keyword keyword?)))
(s/def ::on-focus fn?)
(s/def ::on-blur fn?)
(s/def ::on-press fn?)
(s/def ::accessory
(s/keys :opt-un [::on-press
::icon
::component]))
(s/def ::accessory (s/keys :opt-un [::on-press
::icon
::component]))
(s/def ::after (s/nilable ::accessory))
(s/def ::before (s/nilable ::accessory))
@@ -48,27 +42,25 @@
(s/def ::input-style ::style)
(s/def ::container-style ::style)
(s/def ::text-input
(s/keys :opt-un
[::label
::multiline
::error
::style
::input-style
::keyboard-type
::before
::after
::cancel-label
::on-focus
::on-blur
::container-style
::show-cancel
::accessibility-label
::bottom-value
::secure-text-entry]))
(s/def ::text-input (s/keys :opt-un
[::label
::multiline
::error
::style
::input-style
::keyboard-type
::before
::after
::cancel-label
::on-focus
::on-blur
::container-style
::show-cancel
::accessibility-label
::bottom-value
::secure-text-entry]))
(defn check-spec
[spec prop]
(defn check-spec [spec prop]
(if (s/valid? spec prop)
true
(do
@@ -78,17 +70,14 @@
(def height 44) ; 22 line-height + 11*2 vertical padding
(def multiline-height 88) ; 3 * 22 three line-height + 11* vertical padding
(defn label-style
[]
(defn label-style []
{:margin-bottom (:tiny spacing/spacing)})
(defn text-input-row-style
[]
(defn text-input-row-style []
{:flex-direction :row
:align-items :center})
(defn text-input-view-style
[style]
(defn text-input-view-style [style]
(merge {:border-radius 8
:flex-direction :row
:flex 1
@@ -96,8 +85,7 @@
:background-color (:ui-01 @colors/theme)}
style))
(defn text-input-style
[multiline input-style monospace before after]
(defn text-input-style [multiline input-style monospace before after]
(merge (if monospace
typography/monospace
typography/font-regular)
@@ -119,76 +107,66 @@
:height multiline-height})
input-style))
(defn cancel-style
[]
(defn cancel-style []
{:margin-left (:tiny spacing/spacing)
:padding-left (:tiny spacing/spacing)
:justify-content :center
:align-self :stretch})
(defn accessory-style
[]
(defn accessory-style []
(merge (:base spacing/padding-horizontal)
{:flex 1
:justify-content :center}))
(defn accessory-element
[{:keys [icon component icon-opts style accessibility-label on-press]}]
(defn accessory-element [{:keys [icon component icon-opts style accessibility-label on-press]}]
(let [el (if on-press
rn/touchable-opacity
rn/view)]
[el
(merge {:style {:align-self :stretch}}
(when on-press
{:on-press on-press}))
[rn/view
(merge {:style (merge (accessory-style)
style)}
(when accessibility-label
{:accessibility-label accessibility-label}))
[el (merge {:style {:align-self :stretch}}
(when on-press
{:on-press on-press}))
[rn/view (merge {:style (merge (accessory-style)
style)}
(when accessibility-label
{:accessibility-label accessibility-label}))
(cond
icon
[icons/icon icon
(merge {:color (:icon-01 @colors/theme)}
icon-opts)]
[icons/icon icon (merge {:color (:icon-01 @colors/theme)}
icon-opts)]
component
component
:else
nil)]]))
(defn text-input-raw
[]
(defn text-input-raw []
(let [focused (reagent/atom nil)
visible (reagent/atom false)
ref (atom nil)
blur (fn []
(some-> @ref
(ocall "blur")))]
(fn
[{:keys [label multiline error style input-style keyboard-type before after
cancel-label on-focus on-blur show-cancel accessibility-label
bottom-value secure-text-entry container-style get-ref on-cancel
monospace auto-complete-type auto-correct]
:or {cancel-label "Cancel"}
:as props}]
(some-> @ref (ocall "blur")))]
(fn [{:keys [label multiline error style input-style keyboard-type before after
cancel-label on-focus on-blur show-cancel accessibility-label
bottom-value secure-text-entry container-style get-ref on-cancel
monospace auto-complete-type auto-correct]
:or {cancel-label "Cancel"}
:as props}]
{:pre [(check-spec ::text-input props)]}
(let [show-cancel (if (nil? show-cancel)
;; Enabled by default on iOs and disabled on Android
platform/ios?
show-cancel)
after (cond
(and secure-text-entry @visible)
{:icon :main-icons/hide
:on-press #(reset! visible false)}
(let [show-cancel (if (nil? show-cancel)
;; Enabled by default on iOs and disabled on Android
platform/ios?
show-cancel)
after (cond
(and secure-text-entry @visible)
{:icon :main-icons/hide
:on-press #(reset! visible false)}
(and secure-text-entry (not @visible))
{:icon :main-icons/show
:on-press #(reset! visible true)}
(and secure-text-entry (not @visible))
{:icon :main-icons/show
:on-press #(reset! visible true)}
:else after)
secure (boolean (and secure-text-entry (not @visible))) ; must be a boolean to work on
; iOS
:else after)
secure (boolean (and secure-text-entry (not @visible))) ; must be a boolean to work on iOS
auto-complete (cond
(= keyboard-type :visible-password)
:off
@@ -198,9 +176,7 @@
:else
auto-complete-type)
auto-correct (and (not= keyboard-type :visible-password)
(not secure-text-entry)
auto-correct)
auto-correct (and (not= keyboard-type :visible-password) (not secure-text-entry) auto-correct)
on-cancel (fn []
(when on-cancel
(on-cancel))
@@ -209,10 +185,8 @@
(and platform/ios? (= keyboard-type :visible-password))
:default
; the correct approach on Android would be keep secure-text-entry on set
; keyboard type
; to visible-password. But until
; https://github.com/facebook/react-native/issues/27946
; the correct approach on Android would be keep secure-text-entry on set keyboard type
; to visible-password. But until https://github.com/facebook/react-native/issues/27946
; is solved that's the second best way.
(and platform/android? secure-text-entry)
:default
@@ -224,71 +198,59 @@
[text/text {:style (label-style)}
label])
[rn/view {:style (text-input-row-style)}
[rn/view
{:style (text-input-view-style style)
:important-for-accessibility (if secure-text-entry
:no-hide-descendants
:auto)}
[rn/view {:style (text-input-view-style style)
:important-for-accessibility (if secure-text-entry
:no-hide-descendants
:auto)}
(when before
[accessory-element before])
[rn/text-input
(merge
{:style (text-input-style multiline input-style monospace before after)
:ref (fn [r]
(reset! ref r)
(when get-ref (get-ref r)))
:placeholder-text-color (:text-02 @colors/theme)
:underline-color-android :transparent
:auto-capitalize :none
:secure-text-entry secure
:auto-correct auto-correct
:auto-complete-type auto-complete
:on-focus (fn [evt]
(when on-focus (on-focus evt))
(when show-cancel
(rn/configure-next (:ease-in-ease-out
rn/layout-animation-presets)))
(reset! focused true))
:on-blur (fn [evt]
(when on-blur (on-blur evt))
(when show-cancel
(rn/configure-next (:ease-in-ease-out
rn/layout-animation-presets)))
(reset! focused false))
:keyboard-type keyboard-type}
(when (and platform/ios? (not after))
{:clear-button-mode :while-editing})
(dissoc props
:style
:keyboard-type :on-focus
:on-blur
:secure-text-entry
:ref :get-ref
:auto-correct :auto-complete-type))]
(merge {:style (text-input-style multiline input-style monospace before after)
:ref (fn [r]
(reset! ref r)
(when get-ref (get-ref r)))
:placeholder-text-color (:text-02 @colors/theme)
:underline-color-android :transparent
:auto-capitalize :none
:secure-text-entry secure
:auto-correct auto-correct
:auto-complete-type auto-complete
:on-focus (fn [evt]
(when on-focus (on-focus evt))
(when show-cancel
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets)))
(reset! focused true))
:on-blur (fn [evt]
(when on-blur (on-blur evt))
(when show-cancel
(rn/configure-next (:ease-in-ease-out rn/layout-animation-presets)))
(reset! focused false))
:keyboard-type keyboard-type}
(when (and platform/ios? (not after))
{:clear-button-mode :while-editing})
(dissoc props
:style :keyboard-type :on-focus :on-blur
:secure-text-entry :ref :get-ref :auto-correct :auto-complete-type))]
(when after
[accessory-element after])]
(when (and show-cancel
(not multiline)
@focused)
[rn/touchable-opacity
{:style (cancel-style)
:on-press on-cancel}
[rn/touchable-opacity {:style (cancel-style)
:on-press on-cancel}
[text/text {:color :link} cancel-label]])
(when error
[tooltip/tooltip
(merge {:bottom-value (if bottom-value bottom-value 0)}
(when accessibility-label
{:accessibility-label (str (name accessibility-label) "-error")}))
[text/text
{:color :negative
:align :center
:size :small}
[tooltip/tooltip (merge {:bottom-value (if bottom-value bottom-value 0)}
(when accessibility-label
{:accessibility-label (str (name accessibility-label) "-error")}))
[text/text {:color :negative
:align :center
:size :small}
error]])]]))))
;; TODO(Ferossgp): Refactor me when hooks available
(defn text-input
[{:keys [preserve-input?]
:as props}]
(defn text-input [{:keys [preserve-input?]
:as props}]
(if preserve-input?
[text-input-raw props]
(let [id (random-uuid)]
@@ -299,11 +261,10 @@
:reagent-render
(fn [{:keys [get-ref default-value]
:as props}]
[text-input-raw
(merge props
{:get-ref (fn [r]
;; Store input and its defaultValue
;; one we receive a non-nil ref
(when r
(swap! text-input-refs assoc id {:ref r :value default-value}))
(when get-ref (get-ref r)))})])}))))
[text-input-raw (merge props
{:get-ref (fn [r]
;; Store input and its defaultValue
;; one we receive a non-nil ref
(when r
(swap! text-input-refs assoc id {:ref r :value default-value}))
(when get-ref (get-ref r)))})])}))))
+28 -36
View File
@@ -1,17 +1,17 @@
(ns quo.components.tooltip
(:require [oops.core :refer [oget]]
(:require [reagent.core :as reagent]
[oops.core :refer [oget]]
[quo.animated :as animated]
[quo.react-native :as rn]
[quo.design-system.colors :as colors]
[quo.design-system.spacing :as spacing]
[quo.platform :as platform] ;; FIXME(Ferossgp): Dependecy on status
[quo.react-native :as rn]
[reagent.core :as reagent]
[quo.platform :as platform]
;; FIXME(Ferossgp): Dependecy on status
[status-im.ui.components.icons.icons :as icons]))
(def ^:private initial-height 22)
(defn tooltip-style
[{:keys [bottom-value animation]}]
(defn tooltip-style [{:keys [bottom-value animation]}]
(merge
(:base spacing/padding-horizontal)
{:position :absolute
@@ -22,8 +22,7 @@
:opacity animation
:transform [{:translateY (animated/mix animation 10 0)}]}))
(defn container-style
[]
(defn container-style []
{:z-index 2
:align-items :center
:shadow-radius 16
@@ -31,50 +30,43 @@
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn content-style
[]
(defn content-style []
(merge (:base spacing/padding-horizontal)
{:padding-vertical 6
:elevation 2
:background-color (:ui-background @colors/theme)
:border-radius 8}))
(defn tooltip
[]
(defn tooltip []
(let [layout (reagent/atom {:height initial-height})
animation-v (animated/value 0)
animation (animated/with-timing-transition
animation-v
{:easing (:ease-in animated/easings)})
animation-v
{:easing (:ease-in animated/easings)})
on-layout (fn [evt]
(let [width (oget evt "nativeEvent" "layout" "width")
height (oget evt "nativeEvent" "layout" "height")]
(reset! layout {:width width
:height height})))]
(fn [{:keys [bottom-value accessibility-label]} & children]
(fn [{:keys [bottom-value accessibility-label]} & children]
[:<>
[animated/code
{:exec (animated/cond* (animated/not* animation-v)
(animated/set animation-v 1))}]
[animated/view
{:style (tooltip-style {:bottom-value (- (get @layout :height)
bottom-value)
:animation animation})
:pointer-events :box-none}
[animated/view
{:style (container-style)
:pointer-events :box-none}
(into [rn/view
{:style (content-style)
:pointer-events :box-none
:accessibility-label accessibility-label
:on-layout on-layout}]
[animated/code {:exec (animated/cond* (animated/not* animation-v)
(animated/set animation-v 1))}]
[animated/view {:style (tooltip-style {:bottom-value (- (get @layout :height)
bottom-value)
:animation animation})
:pointer-events :box-none}
[animated/view {:style (container-style)
:pointer-events :box-none}
(into [rn/view {:style (content-style)
:pointer-events :box-none
:accessibility-label accessibility-label
:on-layout on-layout}]
children)
(when platform/ios?
;; NOTE(Ferossgp): Android does not show elevation for tooltip making it lost on white bg
[icons/icon :icons/tooltip-tip
{:width 18
:height 8
:container-style {:elevation 3}
:color (:ui-background @colors/theme)}])]]])))
[icons/icon :icons/tooltip-tip {:width 18
:height 8
:container-style {:elevation 3}
:color (:ui-background @colors/theme)}])]]])))
+9 -9
View File
@@ -1,18 +1,18 @@
(ns quo.core
(:require [quo.components.animated-header :as animated-header]
[quo.components.bottom-sheet.view :as bottom-sheet]
[quo.components.button.view :as button]
[quo.components.controls.view :as controls]
[quo.components.header :as header]
[quo.components.list.footer :as list-footer]
[quo.components.list.header :as list-header]
[quo.components.list.index :as list-index]
[quo.components.list.item :as list-item]
[quo.components.safe-area :as safe-area]
[quo.components.separator :as separator]
[quo.components.text :as text]
[quo.components.text-input :as text-input]
[quo.components.tooltip :as tooltip]
[quo.components.text :as text]
[quo.components.button.view :as button]
[quo.components.list.header :as list-header]
[quo.components.list.footer :as list-footer]
[quo.components.list.item :as list-item]
[quo.components.list.index :as list-index]
[quo.components.controls.view :as controls]
[quo.components.bottom-sheet.view :as bottom-sheet]
[quo.components.separator :as separator]
[quo.design-system.colors :as colors]))
(def text text/text)
+30 -43
View File
@@ -1,6 +1,6 @@
(ns quo.design-system.colors
(:require [clojure.string :as string]
[reagent.core :as reagent]))
(:require [reagent.core :as reagent]
[clojure.string :as string]))
;; Colors mapping from figma to code, note that theme is more extended and
;; one can follow the comments from the light theme to choose what to use in a component.
@@ -19,17 +19,14 @@
(def light-theme
{:positive-01 "rgba(68,208,88,1)" ; Primary Positive, text, icons color
:positive-02 "rgba(78,188,96,0.1)" ; Secondary Positive, Supporting color for success
; illustrations
:positive-02 "rgba(78,188,96,0.1)" ; Secondary Positive, Supporting color for success illustrations
:positive-03 "rgba(78,188,96,1)" ; Lighter Positive, Supporting color for success illustrations
:negative-01 "rgba(255,45,85,1)" ; Primary Negative, text, icons color
:negative-02 "rgba(255,45,85,0.1))" ; Secondary Negative, Supporting color for errors
; illustrations
:negative-02 "rgba(255,45,85,0.1))" ; Secondary Negative, Supporting color for errors illustrations
:warning-01 "rgba(255, 202, 15, 1)"
:warning-02 "rgba(255, 202, 15, 0.1)"
:interactive-01 "rgba(67,96,223,1)" ; Accent color, buttons, own message, actions,active state
:interactive-02 "rgba(236,239,252,1)" ; Light Accent, buttons background, actions background,
; messages
:interactive-02 "rgba(236,239,252,1)" ; Light Accent, buttons background, actions background, messages
:interactive-03 "rgba(255,255,255,0.1)" ; Background for interactive above accent
:interactive-04 "rgba(147,155,161,1)" ; Disabled state
:ui-background "rgba(255,255,255,1)" ; Default view background
@@ -88,14 +85,12 @@
(def theme (reagent/atom light-theme))
(defn get-color
[color]
(defn get-color [color]
(get @theme color))
;; LEGACY COLORS
(defn alpha
[value opacity]
(defn alpha [value opacity]
(if (string/starts-with? value "#")
(let [hex (string/replace value #"#" "")
r (js/parseInt (subs hex 0 2) 16)
@@ -105,15 +100,13 @@
(let [rgb (string/split value #",")]
(str (string/join "," (butlast rgb)) "," opacity ")"))))
(def old-colors-mapping-light
{:mentioned-background "#def6fc"
:mentioned-border "#b8ecf9"
:pin-background "#FFEECC"})
(def old-colors-mapping-light {:mentioned-background "#def6fc"
:mentioned-border "#b8ecf9"
:pin-background "#FFEECC"})
(def old-colors-mapping-dark
{:mentioned-background "#2a4046"
:mentioned-border "#2a4046"
:pin-background "#34232B"})
(def old-colors-mapping-dark {:mentioned-background "#2a4046"
:mentioned-border "#2a4046"
:pin-background "#34232B"})
(def old-colors-mapping-themes {:dark old-colors-mapping-dark :light old-colors-mapping-light})
@@ -134,8 +127,7 @@
;; BLACK
(def black (:text-01 light-theme)) ;; Used as the default text color
(def black-persist (:ui-background dark-theme)) ;; this doesn't with theme
(def black-transparent (:ui-02 light-theme)) ;; Used as background color for rounded button on dark background and as background
;; color for containers like "Backup recovery phrase"
(def black-transparent (:ui-02 light-theme)) ;; Used as background color for rounded button on dark background and as background color for containers like "Backup recovery phrase"
(def black-transparent-20 (:backdrop light-theme)) ; accounts divider
(def black-transparent-40 (:backdrop light-theme))
(def black-transparent-40-persist (:backdrop light-theme))
@@ -144,8 +136,7 @@
(def black-transparent-86 (:ui-03 light-theme))
;; DARK GREY
(def gray (:text-02 light-theme)) ;; Dark grey, used as a background for a light foreground and as
;; section header and secondary text color
(def gray (:text-02 light-theme)) ;; Dark grey, used as a background for a light foreground and as section header and secondary text color
(def gray-transparent-10 (alpha gray 0.1))
(def gray-transparent-40 (alpha gray 0.4))
;; LIGHT GREY
@@ -173,22 +164,20 @@
(def purple "#887af9")
(def orange "#FE8F59")
(def chat-colors
["#fa6565"
"#7cda00"
purple
"#51d0f0"
orange
"#d37ef4"])
(def chat-colors ["#fa6565"
"#7cda00"
purple
"#51d0f0"
orange
"#d37ef4"])
(def account-colors
["#9B832F"
"#D37EF4"
"#1D806F"
"#FA6565"
"#7CDA00"
purple
"#8B3131"])
(def account-colors ["#9B832F"
"#D37EF4"
"#1D806F"
"#FA6565"
"#7CDA00"
purple
"#8B3131"])
(def mention-incoming "#0DA4C9")
(def mention-outgoing "#9EE8FA")
@@ -202,12 +191,10 @@
(def theme-type (reagent/atom :light))
(defn dark?
[]
(defn dark? []
(= :dark @theme-type))
(defn set-legacy-theme-type
[type]
(defn set-legacy-theme-type [type]
(when-not (= type @theme-type)
(let [old-colors-mapping-colors (get old-colors-mapping-themes type)]
(set! white (:ui-background @theme))
+15 -18
View File
@@ -1,22 +1,19 @@
(ns quo.design-system.spacing)
(def spacing
{:x-tiny 4
:tiny 8
:small 12
:base 16
:large 24
:x-large 32
:xx-large 48})
(def spacing {:x-tiny 4
:tiny 8
:small 12
:base 16
:large 24
:x-large 32
:xx-large 48})
(def padding-horizontal
(reduce-kv (fn [m k v]
(assoc m k {:padding-horizontal v}))
{}
spacing))
(def padding-horizontal (reduce-kv (fn [m k v]
(assoc m k {:padding-horizontal v}))
{}
spacing))
(def padding-vertical
(reduce-kv (fn [m k v]
(assoc m k {:padding-vertical v}))
{}
spacing))
(def padding-vertical (reduce-kv (fn [m k v]
(assoc m k {:padding-vertical v}))
{}
spacing))
+14 -21
View File
@@ -1,32 +1,25 @@
(ns quo.design-system.typography)
(def tiny
{:font-size 10
:line-height 14})
(def tiny {:font-size 10
:line-height 14})
(def x-small
{:font-size 12
:line-height 16})
(def x-small {:font-size 12
:line-height 16})
(def small
{:font-size 13
:line-height 18})
(def small {:font-size 13
:line-height 18})
(def base
{:font-size 15
:line-height 22})
(def base {:font-size 15
:line-height 22})
(def large
{:font-size 17
:line-height 24})
(def large {:font-size 17
:line-height 24})
(def x-large
{:font-size 22
:line-height 30})
(def x-large {:font-size 22
:line-height 30})
(def xx-large
{:font-size 28
:line-height 38})
(def xx-large {:font-size 28
:line-height 38})
(def font-regular {:font-family "Inter-Regular"}) ; 400
+16 -24
View File
@@ -1,17 +1,12 @@
(ns quo.gesture-handler
(:require ["react-native-gesture-handler" :refer
(TapGestureHandler PanGestureHandler
LongPressGestureHandler
TouchableWithoutFeedback
TouchableOpacity
TouchableHighlight
State
NativeViewGestureHandler
FlatList
ScrollView)]
[oops.core :refer [oget]]
(:require [oops.core :refer [oget]]
[reagent.core :as reagent]
[quo.design-system.colors :as colors]
[reagent.core :as reagent]))
["react-native-gesture-handler"
:refer (TapGestureHandler PanGestureHandler LongPressGestureHandler
TouchableWithoutFeedback TouchableOpacity
TouchableHighlight State NativeViewGestureHandler
FlatList ScrollView)]))
(def flat-list-raw FlatList)
@@ -35,11 +30,9 @@
(def touchable-highlight-class (reagent/adapt-react-class TouchableHighlight))
(defn touchable-highlight
[props & children]
(into [touchable-highlight-class
(merge {:underlay-color (:interactive-02 @colors/theme)}
props)]
(defn touchable-highlight [props & children]
(into [touchable-highlight-class (merge {:underlay-color (:interactive-02 @colors/theme)}
props)]
children))
(def touchable-opacity
@@ -47,10 +40,9 @@
(def native-view-gesture-handler (reagent/adapt-react-class NativeViewGestureHandler))
(def states
{:began (oget State "BEGAN")
:active (oget State "ACTIVE")
:cancelled (oget State "CANCELLED")
:end (oget State "END")
:failed (oget State "FAILED")
:undetermined (oget State "UNDETERMINED")})
(def states {:began (oget State "BEGAN")
:active (oget State "ACTIVE")
:cancelled (oget State "CANCELLED")
:end (oget State "END")
:failed (oget State "FAILED")
:undetermined (oget State "UNDETERMINED")})
+11 -12
View File
@@ -9,17 +9,16 @@
:notification-success "notificationSuccess"
:notification-warning "notificationWarning"
:notification-error "notificationError"
:clock-tick "clockTick" ; (Android only)
:context-click "contextClick" ; (Android only)
:keyboard-press "keyboardPress" ; (Android only)
:keyboard-release "keyboardRelease" ; (Android only)
:keyboard-tap "keyboardTap" ; (Android only)
:long-press "longPress" ; (Android only)
:text-handle-move "textHandleMove" ; (Android only)
:virtual-key "virtualKey" ; (Android only)
:virtual-key-release "virtualKeyRelease" ; (Android only)
})
:clock-tick "clockTick" ; (Android only)
:context-click "contextClick" ; (Android only)
:keyboard-press "keyboardPress" ; (Android only)
:keyboard-release "keyboardRelease" ; (Android only)
:keyboard-tap "keyboardTap" ; (Android only)
:long-press "longPress" ; (Android only)
:text-handle-move "textHandleMove" ; (Android only)
:virtual-key "virtualKey" ; (Android only)
:virtual-key-release "virtualKeyRelease" ; (Android only)
})
(defn trigger
[method]
(defn trigger [method]
(.trigger ^js react-native-haptic-feedback (get haptic-methods method)))
+43 -54
View File
@@ -1,29 +1,27 @@
(ns quo.previews.bottom-sheet
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
(:require [reagent.core :as reagent]
[quo.core :as quo]
[quo.react-native :as rn]
[reagent.core :as reagent]))
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]))
(def descriptor
[{:label "Show handle:"
:key :show-handle?
:type :boolean}
{:label "Backdrop dismiss:"
:key :backdrop-dismiss?
:type :boolean}
{:label "Disable drag:"
:key :disable-drag?
:type :boolean}
{:label "Android back cancel:"
:key :back-button-cancel
:type :boolean}
{:label "Scrollable:"
:key :scrollable
:type :boolean}])
(def descriptor [{:label "Show handle:"
:key :show-handle?
:type :boolean}
{:label "Backdrop dismiss:"
:key :backdrop-dismiss?
:type :boolean}
{:label "Disable drag:"
:key :disable-drag?
:type :boolean}
{:label "Android back cancel:"
:key :back-button-cancel
:type :boolean}
{:label "Scrollable:"
:key :scrollable
:type :boolean}])
(defn cool-preview
[]
(defn cool-preview []
(let [state (reagent/atom {:show-handle? true
:backdrop-dismiss? true
:disable-drag? false
@@ -31,47 +29,38 @@
visible (reagent/atom false)
scrollable (reagent/cursor state [:scrollable])]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[rn/view {:margin-bottom 50
:padding 16}
[preview/customizer state descriptor]
[:<>
[rn/view
{:style {:align-items :center
:padding 16}}
[rn/view {:style {:align-items :center
:padding 16}}
[rn/touchable-opacity {:on-press #(reset! visible true)}
[rn/view
{:style {:padding-horizontal 16
:padding-vertical 8
:border-radius 4
:background-color (:interactive-01 @colors/theme)}}
[rn/view {:style {:padding-horizontal 16
:padding-vertical 8
:border-radius 4
:background-color (:interactive-01 @colors/theme)}}
[quo/text {:color :secondary-inverse}
(str "Open sheet: " @visible)]]]]
[quo/bottom-sheet
(merge @state
{:visible? @visible
:on-cancel #(reset! visible false)})
[rn/view
{:style {:height (if @scrollable 1200 400)
:justify-content :center
:align-items :center}}
[quo/bottom-sheet (merge @state
{:visible? @visible
:on-cancel #(reset! visible false)})
[rn/view {:style {:height (if @scrollable 1200 400)
:justify-content :center
:align-items :center}}
[rn/touchable-opacity {:on-press #(reset! visible false)}
[quo/text {:color :link} "Close"]]
[rn/touchable-opacity
{:on-press #(swap! scrollable not)
:style {:padding-vertical 16}}
[rn/touchable-opacity {:on-press #(swap! scrollable not)
:style {:padding-vertical 16}}
[quo/text {:color :link} "Toggle size"]]
[quo/text "Hello world!"]]]]])))
(defn preview
[]
(defn preview []
(fn []
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]]))
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]]))
+58 -68
View File
@@ -1,46 +1,44 @@
(ns quo.previews.button
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
(:require [reagent.core :as reagent]
[quo.core :as quo]
[quo.react-native :as rn]
[reagent.core :as reagent]))
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]))
(def descriptor
[{:label "Type:"
:key :type
:type :select
:options [{:key :primary
:value "Primary"}
{:key :secondary
:value "Secondary"}
{:key :icon
:value "Icon"}]}
{:label "Theme:"
:key :theme
:type :select
:options [{:key :main
:value "Main"}
{:key :negative
:value "Negative"}
{:key :positive
:value "Positive"}
{:key :accent
:value "Accent"}]}
{:label "After icon:"
:key :after
:type :boolean}
{:label "Before icon:"
:key :before
:type :boolean}
{:label "Disabled:"
:key :disabled
:type :boolean}
{:label "Label"
:key :label
:type :text}])
(def descriptor [{:label "Type:"
:key :type
:type :select
:options [{:key :primary
:value "Primary"}
{:key :secondary
:value "Secondary"}
{:key :icon
:value "Icon"}]}
{:label "Theme:"
:key :theme
:type :select
:options [{:key :main
:value "Main"}
{:key :negative
:value "Negative"}
{:key :positive
:value "Positive"}
{:key :accent
:value "Accent"}]}
{:label "After icon:"
:key :after
:type :boolean}
{:label "Before icon:"
:key :before
:type :boolean}
{:label "Disabled:"
:key :disabled
:type :boolean}
{:label "Label"
:key :label
:type :text}])
(defn cool-preview
[]
(defn cool-preview []
(let [state (reagent/atom {:label "Press Me"
:type :primary
:theme :main
@@ -50,36 +48,28 @@
before (reagent/cursor state [:before])
after (reagent/cursor state [:after])]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[rn/view {:margin-bottom 50
:padding 16}
[rn/view {:flex 1}
[preview/customizer state descriptor]]
[rn/view
{:padding-vertical 16
:flex-direction :row
:justify-content :center}
[quo/button
(merge (dissoc @state
:theme
:before
:after)
{:on-press #(println "Hello world!")}
(when @theme
{:theme @theme})
(when @before
{:before :main-icons/back})
(when @after
{:after :main-icons/next}))
[rn/view {:padding-vertical 16
:flex-direction :row
:justify-content :center}
[quo/button (merge (dissoc @state
:theme :before :after)
{:on-press #(println "Hello world!")}
(when @theme
{:theme @theme})
(when @before
{:before :main-icons/back})
(when @after
{:after :main-icons/next}))
@label]]])))
(defn preview-button
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
(defn preview-button []
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:key-fn str}]])
+33 -44
View File
@@ -1,55 +1,44 @@
(ns quo.previews.controls
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [reagent.core :as reagent]
[quo.core :as quo]
[quo.react-native :as rn]
[reagent.core :as reagent]))
[quo.design-system.colors :as colors]))
(defn preview
[]
(defn preview []
(let [switch-state (reagent/atom true)
radio-state (reagent/atom true)
checkbox-state (reagent/atom true)]
(fn []
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/view
{:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity
{:style {:margin-vertical 10
:padding 10}
:on-press #(swap! switch-state not)}
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/view {:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity {:style {:margin-vertical 10
:padding 10}
:on-press #(swap! switch-state not)}
[quo/text (str "Switch state: " @switch-state)]]
[quo/switch
{:value @switch-state
:on-change #(reset! switch-state %)}]]
[quo/switch {:value @switch-state
:on-change #(reset! switch-state %)}]]
[rn/view
{:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity
{:style {:margin-vertical 10
:padding 10}
:on-press #(swap! radio-state not)}
[rn/view {:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity {:style {:margin-vertical 10
:padding 10}
:on-press #(swap! radio-state not)}
[quo/text (str "Radio state: " @radio-state)]]
[quo/radio
{:value @radio-state
:on-change #(reset! radio-state %)}]]
[rn/view
{:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity
{:style {:margin-vertical 10
:padding 10}
:on-press #(swap! checkbox-state not)}
[quo/radio {:value @radio-state
:on-change #(reset! radio-state %)}]]
[rn/view {:padding 20
:flex-direction :row
:align-items :center
:justify-content :space-between}
[rn/touchable-opacity {:style {:margin-vertical 10
:padding 10}
:on-press #(swap! checkbox-state not)}
[quo/text (str "Checkbox state: " @checkbox-state)]]
[quo/checkbox
{:value @checkbox-state
:on-change #(reset! checkbox-state %)}]]])))
[quo/checkbox {:value @checkbox-state
:on-change #(reset! checkbox-state %)}]]])))
+36 -43
View File
@@ -1,51 +1,44 @@
(ns quo.previews.header
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.react-native :as rn])
[quo.react-native :as rn]
[quo.design-system.colors :as colors])
(:require-macros [quo.previews.preview :as preview]))
(def accessories
[nil
[{:icon :main-icons/close
:on-press identity}]
[{:icon :main-icons/close
:on-press identity}
{:icon :main-icons/add
:on-press identity}]
[{:icon :main-icons/add
:on-press identity}
{:label "Text"
:on-press identity}]
[{:label "Text"
:on-press identity}]])
(def accessories [nil
[{:icon :main-icons/close
:on-press identity}]
[{:icon :main-icons/close
:on-press identity}
{:icon :main-icons/add
:on-press identity}]
[{:icon :main-icons/add
:on-press identity}
{:label "Text"
:on-press identity}]
[{:label "Text"
:on-press identity}]])
(def all-props
(preview/list-comp [left-accessories accessories
right-accessories accessories
title [nil "This is a title" "This is a very long super title"]
subtitle [nil "This is a subtitle"]
title-align [:left :center]]
{:left-accessories left-accessories
:right-accessories right-accessories
:title title
:subtitle subtitle
:title-align title-align}))
(def all-props (preview/list-comp [left-accessories accessories
right-accessories accessories
title [nil "This is a title" "This is a very long super title"]
subtitle [nil "This is a subtitle"]
title-align [:left :center]]
{:left-accessories left-accessories
:right-accessories right-accessories
:title title
:subtitle subtitle
:title-align title-align}))
(defn render-item
[props]
[rn/view
{:border-bottom-color "#EEF2F5"
:border-bottom-width 2}
(defn render-item [props]
[rn/view {:border-bottom-color "#EEF2F5"
:border-bottom-width 2}
[quo/header props]])
(defn preview-header
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:data all-props
:render-fn render-item
:key-fn str}]])
(defn preview-header []
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:data all-props
:render-fn render-item
:key-fn str}]])
+3 -5
View File
@@ -3,11 +3,9 @@
[quo.react-native :as rn]
[status-im.ui.components.icons.icons :as icons]))
(defn preview
[]
[rn/scroll-view
{:background-color (:ui-background @colors/theme)
:flex 1}
(defn preview []
[rn/scroll-view {:background-color (:ui-background @colors/theme)
:flex 1}
(for [i (keys icons/icons)]
[rn/view {:flex-direction :row}
[icons/icon (keyword i)]
+85 -96
View File
@@ -1,94 +1,87 @@
(ns quo.previews.lists
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
(:require [reagent.core :as reagent]
[quo.core :as quo]
[quo.react-native :as rn]
[reagent.core :as reagent]))
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]))
(def all-props (preview/list-comp [] {}))
(defn avatar
[]
[rn/view
{:border-radius 20
:width 40
:height 40
:justify-content :center
:align-items :center
:background-color :red}
[quo/text
{:weight :bold
:size :large}
(defn avatar []
[rn/view {:border-radius 20
:width 40
:height 40
:justify-content :center
:align-items :center
:background-color :red}
[quo/text {:weight :bold
:size :large}
"T"]])
(defn icon-element
[type]
(defn icon-element [type]
(case type
:icon :main-icons/add-contact
:component [avatar]
nil))
(def descriptor
[{:label "Accessory:"
:key :accessory
:type :select
:options [{:key :radio
:value "Radio"}
{:key :checkbox
:value "Checkbox"}
{:key :switch
:value "Switch"}
{:key :text
:value "Text"}
{:key :default
:value "Default"}]}
{:label "Size:"
:key :size
:type :select
:options [{:key :small
:value "Small"}
{:key :default
:value "Default"}]}
{:label "Icon:"
:key :icon
:type :select
:options [{:key :icon
:value "Icon"}
{:key :component
:value "Component"}]}
{:label "Theme:"
:key :theme
:type :select
:options [{:key :main
:value "Main"}
{:key :accent
:value "Accent"}
{:key :negative
:value "Negative"}
{:key :positive
:value "Positive"}]}
{:label "Selectable"
:key :selectable
:type :boolean}
{:label "Chevron"
:key :chevron
:type :boolean}
{:label "Disabled:"
:key :disabled
:type :boolean}
{:label "Title"
:key :title
:type :text}
{:label "Subtitle"
:key :subtitle
:type :text}])
(def descriptor [{:label "Accessory:"
:key :accessory
:type :select
:options [{:key :radio
:value "Radio"}
{:key :checkbox
:value "Checkbox"}
{:key :switch
:value "Switch"}
{:key :text
:value "Text"}
{:key :default
:value "Default"}]}
{:label "Size:"
:key :size
:type :select
:options [{:key :small
:value "Small"}
{:key :default
:value "Default"}]}
{:label "Icon:"
:key :icon
:type :select
:options [{:key :icon
:value "Icon"}
{:key :component
:value "Component"}]}
{:label "Theme:"
:key :theme
:type :select
:options [{:key :main
:value "Main"}
{:key :accent
:value "Accent"}
{:key :negative
:value "Negative"}
{:key :positive
:value "Positive"}]}
{:label "Selectable"
:key :selectable
:type :boolean}
{:label "Chevron"
:key :chevron
:type :boolean}
{:label "Disabled:"
:key :disabled
:type :boolean}
{:label "Title"
:key :title
:type :text}
{:label "Subtitle"
:key :subtitle
:type :text}])
(defn render-item
[_]
[rn/view {:style {:padding-vertical 24}}])
(defn render-item [_]
[rn/view {:style {:padding-vertical 24}}])
(defn cool-preview
[]
(defn cool-preview []
(let [state (reagent/atom {:title "Title"
:active false})
icon (reagent/cursor state [:icon])
@@ -99,23 +92,19 @@
[rn/view {:padding-horizontal 16}
[preview/customizer state descriptor]]
[rn/view {:padding-vertical 16}
[quo/list-item
(merge (dissoc @state :active :selectable)
(when @selectable
{:active @active
:on-press #(swap! active not)})
{:accessory-text "Accessory"
:icon (icon-element @icon)})]]])))
[quo/list-item (merge (dissoc @state :active :selectable)
(when @selectable
{:active @active
:on-press #(swap! active not)})
{:accessory-text "Accessory"
:icon (icon-element @icon)})]]])))
(defn preview
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
(defn preview []
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
+63 -72
View File
@@ -1,83 +1,75 @@
(ns quo.previews.main
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.bottom-sheet :as bottom-sheet]
[quo.previews.button :as button]
[quo.previews.controls :as controls]
[quo.previews.header :as header]
[quo.previews.icons :as icons]
[quo.previews.lists :as lists]
(:require [quo.previews.header :as header]
[quo.previews.text :as text]
[quo.previews.text-input :as text-input]
[quo.previews.tooltip :as tooltip]
[quo.previews.button :as button]
[quo.previews.lists :as lists]
[quo.previews.bottom-sheet :as bottom-sheet]
[quo.previews.controls :as controls]
[quo.react-native :as rn]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.theme :as theme]
[quo.previews.icons :as icons]
[re-frame.core :as re-frame]))
(def screens
[{:name :texts
:insets {:top false}
:component text/preview-text}
{:name :tooltip
:insets {:top false}
:component tooltip/preview-tooltip}
{:name :text-input
:insets {:top false}
:component text-input/preview-text}
{:name :headers
:insets {:top false}
:component header/preview-header}
{:name :button
:insets {:top false}
:component button/preview-button}
{:name :lists
:instes {:top false}
:component lists/preview}
{:name :bottom-sheet
:insets {:top false}
:component bottom-sheet/preview}
{:name :controls
:insets {:top false}
:component controls/preview}
{:name :icons
:insets {:top false}
:component icons/preview}])
(def screens [{:name :texts
:insets {:top false}
:component text/preview-text}
{:name :tooltip
:insets {:top false}
:component tooltip/preview-tooltip}
{:name :text-input
:insets {:top false}
:component text-input/preview-text}
{:name :headers
:insets {:top false}
:component header/preview-header}
{:name :button
:insets {:top false}
:component button/preview-button}
{:name :lists
:instes {:top false}
:component lists/preview}
{:name :bottom-sheet
:insets {:top false}
:component bottom-sheet/preview}
{:name :controls
:insets {:top false}
:component controls/preview}
{:name :icons
:insets {:top false}
:component icons/preview}])
(defn theme-switcher
[]
[rn/view
{:style {:flex-direction :row
:margin-vertical 8
:border-radius 4
:background-color (:ui-01 @colors/theme)
:border-width 1
:border-color (:ui-02 @colors/theme)}}
[rn/touchable-opacity
{:style {:padding 8
:flex 1
:justify-content :center
:align-items :center}
:on-press #(theme/set-theme :light)}
(defn theme-switcher []
[rn/view {:style {:flex-direction :row
:margin-vertical 8
:border-radius 4
:background-color (:ui-01 @colors/theme)
:border-width 1
:border-color (:ui-02 @colors/theme)}}
[rn/touchable-opacity {:style {:padding 8
:flex 1
:justify-content :center
:align-items :center}
:on-press #(theme/set-theme :light)}
[quo/text "Set light theme"]]
[rn/view
{:width 1
:margin-vertical 4
:background-color (:ui-02 @colors/theme)}]
[rn/touchable-opacity
{:style {:padding 8
:flex 1
:justify-content :center
:align-items :center}
:on-press #(theme/set-theme :dark)}
[rn/view {:width 1
:margin-vertical 4
:background-color (:ui-02 @colors/theme)}]
[rn/touchable-opacity {:style {:padding 8
:flex 1
:justify-content :center
:align-items :center}
:on-press #(theme/set-theme :dark)}
[quo/text "Set dark theme"]]])
(defn main-screen
[]
[rn/scroll-view
{:flex 1
:padding-vertical 8
:padding-horizontal 16
:background-color (:ui-background @colors/theme)}
(defn main-screen []
[rn/scroll-view {:flex 1
:padding-vertical 8
:padding-horizontal 16
:background-color (:ui-background @colors/theme)}
[theme-switcher]
[rn/view
(for [{:keys [name]} screens]
@@ -86,7 +78,6 @@
[rn/view {:style {:padding-vertical 8}}
[quo/text (str "Preview " name)]]])]])
(def main-screens
[{:name :quo-preview
:insets {:top false}
:component main-screen}])
(def main-screens [{:name :quo-preview
:insets {:top false}
:component main-screen}])
+3 -5
View File
@@ -1,17 +1,15 @@
(ns quo.previews.preview)
(defn descriptor->values
[{:keys [key options type]}]
(defn descriptor->values [{:keys [key options type]}]
{key (case type
:boolean [false true]
:text [nil "Just simple text"] ; NOTE(Ferossgp): add example with long text?
:select (mapv :key options))})
(defmacro list-comp
[[binding seq-expr & bindings] body-expr]
(defmacro list-comp [[binding seq-expr & bindings] body-expr]
(cond (not binding)
`(list ~body-expr)
:else
`(mapcat (fn [~binding] (list-comp ~bindings ~body-expr))
~seq-expr)))
~seq-expr)))
+66 -89
View File
@@ -1,26 +1,23 @@
(ns quo.previews.preview
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
(:require [reagent.core :as reagent]
[quo.react-native :as rn]
[reagent.core :as reagent])
[quo.core :as quo]
[quo.design-system.colors :as colors])
(:require-macros quo.previews.preview))
(def container
{:flex-direction :row
:padding-vertical 8
:flex 1
:align-items :center})
(def container {:flex-direction :row
:padding-vertical 8
:flex 1
:align-items :center})
(defn touchable-style
[]
(defn touchable-style []
{:flex 1
:align-items :center
:justify-content :center
:padding-horizontal 16
:height 44})
(defn select-style
[]
(defn select-style []
{:flex 1
:flex-direction :row
:align-items :center
@@ -31,8 +28,7 @@
:border-width 1
:border-color (:ui-02 @colors/theme)})
(defn select-option-style
[selected]
(defn select-option-style [selected]
(merge (select-style)
{:margin-vertical 8
:justify-content :center}
@@ -40,27 +36,23 @@
{:background-color (:interactive-02 @colors/theme)}
{:background-color (:ui-01 @colors/theme)})))
(def label-style
{:flex 0.4
:padding-right 8})
(def label-style {:flex 0.4
:padding-right 8})
(defn label-view
[state label]
(defn label-view [state label]
[rn/view {:style label-style}
[quo/text
(when-let [label-color (:preview-label-color @state)]
{:style {:color label-color}})
label]])
(defn modal-container
[]
(defn modal-container []
{:flex 1
:justify-content :center
:padding-horizontal 24
:background-color "rgba(0,0,0,0.4)"})
(defn modal-view
[]
(defn modal-view []
{:padding-horizontal 16
:padding-vertical 8
:border-radius 8
@@ -72,25 +64,21 @@
(let [state* (reagent/cursor state [key])]
[rn/view {:style container}
[label-view state label]
[rn/view
{:style {:flex-direction :row
:flex 0.6
:border-radius 4
:background-color (:ui-01 @colors/theme)
:border-width 1
:border-color (:ui-02 @colors/theme)}}
[rn/touchable-opacity
{:style (touchable-style)
:on-press #(reset! state* true)}
[quo/text {:color (if @state* :link :secondary)}
[rn/view {:style {:flex-direction :row
:flex 0.6
:border-radius 4
:background-color (:ui-01 @colors/theme)
:border-width 1
:border-color (:ui-02 @colors/theme)}}
[rn/touchable-opacity {:style (touchable-style)
:on-press #(reset! state* true)}
[quo/text {:color (if @state* :link :secondary)}
"True"]]
[rn/view
{:width 1
:margin-vertical 4
:background-color (:ui-02 @colors/theme)}]
[rn/touchable-opacity
{:style (touchable-style)
:on-press #(reset! state* false)}
[rn/view {:width 1
:margin-vertical 4
:background-color (:ui-02 @colors/theme)}]
[rn/touchable-opacity {:style (touchable-style)
:on-press #(reset! state* false)}
[quo/text {:color (if (not @state*) :link :secondary)}
"False"]]]]))
@@ -100,22 +88,20 @@
[rn/view {:style container}
[label-view state label]
[rn/view {:style {:flex 0.6}}
[quo/text-input
{:value @state*
:show-cancel false
:style {:border-radius 4
:border-width 1
:border-color (:ui-02 @colors/theme)}
:on-change-text #(do
(reset! state* %)
(reagent/flush))}]]]))
[quo/text-input {:value @state*
:show-cancel false
:style {:border-radius 4
:border-width 1
:border-color (:ui-02 @colors/theme)}
:on-change-text #(do
(reset! state* %)
(reagent/flush))}]]]))
(defn value-for-key
[id v]
(:value (first (filter #(= (:key %) id) v))))
(defn customizer-select
[]
(defn customizer-select []
(let [open (reagent/atom nil)]
(fn [{:keys [label key state options]}]
(let [state* (reagent/cursor state [key])
@@ -123,63 +109,54 @@
[rn/view {:style container}
[label-view state label]
[rn/view {:style {:flex 0.6}}
[rn/modal
{:visible @open
:on-request-close #(reset! open false)
:statusBarTranslucent true
:transparent true
:animation :slide}
[rn/modal {:visible @open
:on-request-close #(reset! open false)
:statusBarTranslucent true
:transparent true
:animation :slide}
[rn/view {:style (modal-container)}
[rn/view {:style (modal-view)}
[rn/scroll-view
(doall
(for [{:keys [key value]} options]
^{:key key}
[rn/touchable-opacity
{:style (select-option-style (= @state* key))
:on-press #(do
(reset! open false)
(reset! state* key))}
[rn/touchable-opacity {:style (select-option-style (= @state* key))
:on-press #(do
(reset! open false)
(reset! state* key))}
[quo/text {:color (if (= @state* key) :link :secondary)}
value]]))
[rn/view {:flex-direction :row}
[rn/touchable-opacity
{:style (select-option-style false)
:on-press #(do
(reset! state* nil)
(reset! open false))}
[rn/touchable-opacity {:style (select-option-style false)
:on-press #(do
(reset! state* nil)
(reset! open false))}
[quo/text "Clear"]]
[rn/view {:width 16}]
[rn/touchable-opacity
{:style (select-option-style false)
:on-press #(reset! open false)}
[rn/touchable-opacity {:style (select-option-style false)
:on-press #(reset! open false)}
[quo/text "Close"]]]]]]]
[rn/touchable-opacity
{:style (select-style)
:on-press #(reset! open true)}
[rn/touchable-opacity {:style (select-style)
:on-press #(reset! open true)}
(if selected
[quo/text {:color :link} selected]
[quo/text "Select option"])
[rn/view
{:position :absolute
:right 16
:top 0
:bottom 0
:justify-content :center}
[rn/view {:position :absolute
:right 16
:top 0
:bottom 0
:justify-content :center}
[quo/text "↓"]]]]]))))
(defn customizer
[state descriptors]
[rn/view
{:style {:flex 1}
:padding-horizontal 16}
(defn customizer [state descriptors]
[rn/view {:style {:flex 1}
:padding-horizontal 16}
(doall
(for [{:keys [key type]
:as desc}
descriptors
:let [descriptor (merge desc
{:state state})]]
:as desc} descriptors
:let [descriptor (merge desc
{:state state})]]
^{:key key}
[:<>
(case type
+73 -83
View File
@@ -1,99 +1,89 @@
(ns quo.previews.text
(:require [quo.animated :as animated]
(:require [reagent.core :as reagent]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
[quo.animated :as animated]
[quo.react-native :as rn]
[reagent.core :as reagent]))
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]))
(def all-props
(preview/list-comp [size [:tiny :small :base :large :x-large :xx-large]
weight [:regular :medium :semi-bold :bold :monospace]]
{:weight weight
:size size}))
(def all-props (preview/list-comp [size [:tiny :small :base :large :x-large :xx-large]
weight [:regular :medium :semi-bold :bold :monospace]]
{:weight weight
:size size}))
(def descriptor
[{:label "Size:"
:key :size
:type :select
:options [{:key :tiny
:value "Tiny"}
{:key :small
:value "Small"}
{:key :base
:value "Base"}
{:key :large
:value "Large"}
{:key :x-large
:value "X-Large"}
{:key :xx-large
:value "XX-Large"}]}
{:label "Weight:"
:key :weight
:type :select
:options [{:key :regular
:value "Regular"}
{:key :medium
:value "Medium"}
{:key :semi-bold
:value "Semi-bold"}
{:key :bold
:value "Bold"}
{:key :monospace
:value "Monospace"}]}
{:label "Color:"
:key :color
:type :select
:options [{:key :main
:value "main"}
{:key :secondary
:value "secondary"}
{:key :secondary-inverse
:value "secondary-inverse"}
{:key :link
:value "link"}
{:key :negative
:value "negative"}
{:key :positive
:value "positive"}]}
{:label "Animated:"
:key :animated?
:type :boolean}])
(def descriptor [{:label "Size:"
:key :size
:type :select
:options [{:key :tiny
:value "Tiny"}
{:key :small
:value "Small"}
{:key :base
:value "Base"}
{:key :large
:value "Large"}
{:key :x-large
:value "X-Large"}
{:key :xx-large
:value "XX-Large"}]}
{:label "Weight:"
:key :weight
:type :select
:options [{:key :regular
:value "Regular"}
{:key :medium
:value "Medium"}
{:key :semi-bold
:value "Semi-bold"}
{:key :bold
:value "Bold"}
{:key :monospace
:value "Monospace"}]}
{:label "Color:"
:key :color
:type :select
:options [{:key :main
:value "main"}
{:key :secondary
:value "secondary"}
{:key :secondary-inverse
:value "secondary-inverse"}
{:key :link
:value "link"}
{:key :negative
:value "negative"}
{:key :positive
:value "positive"}]}
{:label "Animated:"
:key :animated?
:type :boolean}])
(defn render-item
[props]
[rn/view
{:style {:padding-vertical 24
:padding-horizontal 16}}
(defn render-item [props]
[rn/view {:style {:padding-vertical 24
:padding-horizontal 16}}
[quo/text props
(str "Text size " props " number 0 1x2")]])
(defn cool-preview
[]
(defn cool-preview []
(let [state (reagent/atom {})
animation (animated/value 0)]
animation (animated/value 0)]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[rn/view {:margin-bottom 50
:padding 16}
[animated/code {:exec (animated/set animation (animated/loop* {:duration 1000}))}]
[preview/customizer state descriptor]
[rn/view {:padding-vertical 16}
[quo/text
(merge @state
(when (:animated? @state)
{:opacity animation}))
[quo/text (merge @state
(when (:animated? @state)
{:opacity animation}))
"This is a demo text 1 2 0 2x2 0x0"]]])))
(defn preview-text
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
(defn preview-text []
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
+64 -74
View File
@@ -1,62 +1,57 @@
(ns quo.previews.text-input
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]
(:require [reagent.core :as reagent]
[quo.core :as quo]
[quo.react-native :as rn]
[reagent.core :as reagent]))
[quo.design-system.colors :as colors]
[quo.previews.preview :as preview]))
(def all-props
(preview/list-comp [multiline [false true]
label [nil "Input label"]
default-value [nil "Test initial value"]
placeholder [nil "Placeholder value"]
before [nil {:icon :main-icons/search}]
after [nil {:icon :main-icons/close}]
error [nil "Something went wrong!"]
secure [false true]
show-cancel [false true]]
{:label label
:default-value default-value
:placeholder placeholder
:multiline multiline
:before before
:after after
:error error
:show-cancel show-cancel
:secure-text-entry secure}))
(def all-props (preview/list-comp [multiline [false true]
label [nil "Input label"]
default-value [nil "Test initial value"]
placeholder [nil "Placeholder value"]
before [nil {:icon :main-icons/search}]
after [nil {:icon :main-icons/close}]
error [nil "Something went wrong!"]
secure [false true]
show-cancel [false true]]
{:label label
:default-value default-value
:placeholder placeholder
:multiline multiline
:before before
:after after
:error error
:show-cancel show-cancel
:secure-text-entry secure}))
(def descriptor
[{:label "Multiline:"
:key :multiline
:type :boolean}
{:label "Show cancel:"
:key :show-cancel
:type :boolean}
{:label "Secure:"
:key :secure-text-entry
:type :boolean}
{:label "After icon:"
:key :after
:type :boolean}
{:label "Before icon:"
:key :before
:type :boolean}
{:label "Show error:"
:key :error
:type :boolean}
{:label "Label"
:key :label
:type :text}])
(def descriptor [{:label "Multiline:"
:key :multiline
:type :boolean}
{:label "Show cancel:"
:key :show-cancel
:type :boolean}
{:label "Secure:"
:key :secure-text-entry
:type :boolean}
{:label "After icon:"
:key :after
:type :boolean}
{:label "Before icon:"
:key :before
:type :boolean}
{:label "Show error:"
:key :error
:type :boolean}
{:label "Label"
:key :label
:type :text}])
(defn render-item
[props]
[rn/view
{:style {:padding-horizontal 16
:padding-vertical 24}}
(defn render-item [props]
[rn/view {:style {:padding-horizontal 16
:padding-vertical 24}}
[quo/text-input props]])
(defn cool-preview
[]
(defn cool-preview []
(let [state (reagent/atom {:secure false
:show-cancel false
:multiline false
@@ -65,27 +60,22 @@
after (reagent/cursor state [:after])
error (reagent/cursor state [:error])]
(fn []
[rn/view
{:margin-bottom 50
:padding 16}
[rn/view {:margin-bottom 50
:padding 16}
[preview/customizer state descriptor]
[quo/text-input
(merge @state
{:default-value nil
:placeholder "I'm a cool placeholder"
:before (when @before {:icon :main-icons/search})
:after (when @after {:icon :main-icons/close})
:error (when @error "Something went wrong!")})]])))
[quo/text-input (merge @state
{:default-value nil
:placeholder "I'm a cool placeholder"
:before (when @before {:icon :main-icons/search})
:after (when @after {:icon :main-icons/close})
:error (when @error "Something went wrong!")})]])))
(defn preview-text
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
(defn preview-text []
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:header [cool-preview]
:data all-props
:render-fn render-item
:key-fn str}]])
+21 -29
View File
@@ -1,38 +1,30 @@
(ns quo.previews.tooltip
(:require [quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.react-native :as rn])
[quo.react-native :as rn]
[quo.design-system.colors :as colors])
(:require-macros [quo.previews.preview :as preview]))
(def all-props
(preview/list-comp
[child [[quo/text {:size :small} "Simple text"]
[quo/text
{:color :negative
:size :small}
"Error text"]
[rn/view {:width 100 :height 20 :background-color :red}]
[quo/text
"Just text, but long. Officia autem est repellendus ad quia exercitationem veniam."]]]
child))
(def all-props (preview/list-comp
[child [[quo/text {:size :small} "Simple text"]
[quo/text {:color :negative
:size :small}
"Error text"]
[rn/view {:width 100 :height 20 :background-color :red}]
[quo/text "Just text, but long. Officia autem est repellendus ad quia exercitationem veniam."]]]
child))
(defn render-item
[children]
(defn render-item [children]
[rn/view {:margin-vertical 50}
[rn/view
{:height 20
:background-color "rgba(0,0,0,0.1)"}]
[rn/view {:height 20
:background-color "rgba(0,0,0,0.1)"}]
[quo/tooltip {}
children]])
(defn preview-tooltip
[]
[rn/view
{:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list
{:flex 1
:keyboardShouldPersistTaps :always
:data all-props
:render-fn render-item
:key-fn str}]])
(defn preview-tooltip []
[rn/view {:background-color (:ui-background @colors/theme)
:flex 1}
[rn/flat-list {:flex 1
:keyboardShouldPersistTaps :always
:data all-props
:render-fn render-item
:key-fn str}]])
+2 -4
View File
@@ -1,11 +1,9 @@
(ns quo.react)
(defmacro maybe-js-deps
[deps]
(defmacro maybe-js-deps [deps]
`(if ~deps (into-array ~deps) js/undefined))
(defmacro with-deps-check
[[prev-deps] f deps]
(defmacro with-deps-check [[prev-deps] f deps]
`(let [~prev-deps (quo.react/ref ~deps)]
(when (not= @~prev-deps ~deps)
(reset! ~prev-deps ~deps))
+38 -43
View File
@@ -2,12 +2,12 @@
(:refer-clojure :exclude [ref])
(:require ["react" :as react]
[oops.core :refer [oget oset!]])
(:require-macros [quo.react :refer [with-deps-check maybe-js-deps]]))
(:require-macros [quo.react :refer [with-deps-check
maybe-js-deps]]))
(def create-ref react/createRef)
(defn current-ref
[ref]
(defn current-ref [ref]
(oget ref "current"))
;; Inspired from UIX, Rum and Rumext
@@ -16,35 +16,33 @@
(oset! ref "current" val)
val)
(defn set-native-props
[^js ref ^js props]
(defn set-native-props [^js ref ^js props]
(when-let [curr-ref ^js (current-ref ref)]
(.setNativeProps curr-ref props)))
(deftype StateHook [value set-value]
cljs.core/IHash
(-hash [o] (goog/getUid o))
(-hash [o] (goog/getUid o))
cljs.core/IDeref
(-deref [_o]
value)
(-deref [_o]
value)
cljs.core/IReset
(-reset! [_o new-value]
(set-value new-value))
(-reset! [_o new-value]
(set-value new-value))
cljs.core/ISwap
(-swap! [_o f]
(set-value f))
(-swap! [_o f a]
(set-value #(f % a)))
(-swap! [_o f a b]
(set-value #(f % a b)))
(-swap! [_o f a b xs]
(set-value #(apply f % a b xs))))
(-swap! [_o f]
(set-value f))
(-swap! [_o f a]
(set-value #(f % a)))
(-swap! [_o f a b]
(set-value #(f % a b)))
(-swap! [_o f a b xs]
(set-value #(apply f % a b xs))))
(defn state
[value]
(defn state [value]
(let [[value set-value] (react/useState value)
sh (react/useMemo #(StateHook. value set-value) #js [])]
(react/useMemo (fn []
@@ -53,33 +51,31 @@
sh)
#js [value set-value])))
(defn use-ref
[val]
(defn use-ref [val]
(let [ref (react/useRef val)]
(reify
cljs.core/IHash
(-hash [_] (goog/getUid ref))
cljs.core/IHash
(-hash [_] (goog/getUid ref))
cljs.core/IDeref
(-deref [_]
(current-ref ref))
cljs.core/IDeref
(-deref [_]
(current-ref ref))
cljs.core/IReset
(-reset! [_ new-value]
(set-ref-val! ref new-value))
cljs.core/IReset
(-reset! [_ new-value]
(set-ref-val! ref new-value))
cljs.core/ISwap
(-swap! [_ f]
(-reset! ref (f (current-ref ref))))
(-swap! [_ f a]
(-reset! ref (f (current-ref ref) a)))
(-swap! [_ f a b]
(-reset! ref (f (current-ref ref) a b)))
(-swap! [_ f a b xs]
(-reset! ref (apply f (current-ref ref) a b xs))))))
cljs.core/ISwap
(-swap! [_ f]
(-reset! ref (f (current-ref ref))))
(-swap! [_ f a]
(-reset! ref (f (current-ref ref) a)))
(-swap! [_ f a b]
(-reset! ref (f (current-ref ref) a b)))
(-swap! [_ f a b xs]
(-reset! ref (apply f (current-ref ref) a b xs))))))
(defn ref
[value]
(defn ref [value]
(let [vref (use-ref value)]
(react/useMemo (fn [] vref) #js [])))
@@ -129,8 +125,7 @@
(def memo react/memo)
(defn get-children
[^js children]
(defn get-children [^js children]
(->> children
(react/Children.toArray)
(into [])))
+53 -76
View File
@@ -1,13 +1,13 @@
(ns quo.react-native
(:require ["@react-native-community/hooks" :as hooks]
["react-native" :as rn]
["react-native-draggable-flatlist" :default DraggableFlatList]
["react-native-hole-view" :refer (RNHoleView)]
["react-native-navigation" :refer (Navigation)]
["rn-emoji-keyboard" :refer (EmojiKeyboard)]
(:require [reagent.core :as reagent]
[cljs-bean.core :as bean]
[quo.platform :as platform]
[reagent.core :as reagent]))
["react-native" :as rn]
["@react-native-community/hooks" :as hooks]
["react-native-navigation" :refer (Navigation)]
["react-native-hole-view" :refer (RNHoleView)]
["rn-emoji-keyboard" :refer (EmojiKeyboard)]
["react-native-draggable-flatlist" :default DraggableFlatList]))
(def hole-view (reagent/adapt-react-class RNHoleView))
@@ -25,9 +25,7 @@
(def image (reagent/adapt-react-class (.-Image rn)))
(def text (reagent/adapt-react-class (.-Text ^js rn)))
(defn resolve-asset-source
[uri]
(js->clj (.resolveAssetSource ^js (.-Image ^js rn) uri) :keywordize-keys true))
(defn resolve-asset-source [uri] (js->clj (.resolveAssetSource ^js (.-Image ^js rn) uri) :keywordize-keys true))
(def scroll-view (reagent/adapt-react-class (.-ScrollView ^js rn)))
(def modal (reagent/adapt-react-class (.-Modal ^js rn)))
@@ -44,12 +42,11 @@
(.then (.constants Navigation)
(fn [^js consts]
(reset! navigation-const {:top-bar-height (.-topBarHeight consts)
(reset! navigation-const {:top-bar-height (.-topBarHeight consts)
:bottom-tabs-height (.-bottomTabsHeight consts)
:status-bar-height (.-statusBarHeight consts)})))
:status-bar-height (.-statusBarHeight consts)})))
(defn keyboard-avoiding-view
[]
(defn keyboard-avoiding-view []
(let [this (reagent/current-component)
props (reagent/props this)]
(into [keyboard-avoiding-view-class
@@ -69,8 +66,7 @@
(def pan-responder (.-PanResponder ^js rn))
(defn create-pan-responder
[opts]
(defn create-pan-responder [opts]
(.create ^js pan-responder (clj->js opts)))
(def animated (.-Animated rn))
@@ -83,99 +79,82 @@
(def animated-view
(reagent/adapt-react-class (.-View ^js animated)))
(def ui-manager (.-UIManager ^js rn))
(def ui-manager (.-UIManager ^js rn))
(def layout-animation (.-LayoutAnimation ^js rn))
(def configure-next (.-configureNext ^js layout-animation))
(def create-animation (.-create ^js layout-animation))
(def layout-animation-presets
{:ease-in-ease-out (-> ^js layout-animation .-Presets .-easeInEaseOut)
:linear (-> ^js layout-animation .-Presets .-linear)
:spring (-> ^js layout-animation .-Presets .-spring)})
(def layout-animation-presets {:ease-in-ease-out (-> ^js layout-animation .-Presets .-easeInEaseOut)
:linear (-> ^js layout-animation .-Presets .-linear)
:spring (-> ^js layout-animation .-Presets .-spring)})
(def layout-animation-types
{:spring (-> ^js layout-animation .-Types .-spring)
:linear (-> ^js layout-animation .-Types .-linear)
:ease-in-ease-out (-> ^js layout-animation .-Types .-easeInEaseOut)
:ease-in (-> ^js layout-animation .-Types .-easeIn)
:ease-out (-> ^js layout-animation .-Types .-easeOut)})
(def layout-animation-types {:spring (-> ^js layout-animation .-Types .-spring)
:linear (-> ^js layout-animation .-Types .-linear)
:ease-in-ease-out (-> ^js layout-animation .-Types .-easeInEaseOut)
:ease-in (-> ^js layout-animation .-Types .-easeIn)
:ease-out (-> ^js layout-animation .-Types .-easeOut)})
(def layout-animation-properties
{:opacity (-> ^js layout-animation .-Properties .-opacity)
:scale-x (-> ^js layout-animation .-Properties .-scaleX)
:scale-y (-> ^js layout-animation .-Properties .-scaleY)
:scale-xy (-> ^js layout-animation .-Properties .-scaleXY)})
(def layout-animation-properties {:opacity (-> ^js layout-animation .-Properties .-opacity)
:scale-x (-> ^js layout-animation .-Properties .-scaleX)
:scale-y (-> ^js layout-animation .-Properties .-scaleY)
:scale-xy (-> ^js layout-animation .-Properties .-scaleXY)})
(def custom-animations
{:ease-opacity-200 #js
{:duration 200
:create #js
{:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}
:update #js
{:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}
:delete #js
{:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}}})
(def custom-animations {:ease-opacity-200 #js {:duration 200
:create #js {:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}
:update #js {:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}
:delete #js {:type (:ease-in-ease-out layout-animation-types)
:property (:opacity layout-animation-properties)}}})
(defonce enable-layout-animations
(when platform/android?
(.setLayoutAnimationEnabledExperimental ^js ui-manager true)))
(when platform/android?
(.setLayoutAnimationEnabledExperimental ^js ui-manager true)))
(def activity-indicator (reagent/adapt-react-class (.-ActivityIndicator ^js rn)))
;; Flat-list
(def ^:private rn-flat-list (reagent/adapt-react-class (.-FlatList ^js rn)))
(defn- wrap-render-fn
[f render-data]
(defn- wrap-render-fn [f render-data]
(fn [data]
(reagent/as-element [f (.-item ^js data) (.-index ^js data)
(.-separators ^js data) render-data
(.-isActive ^js data) (.-drag ^js data)])))
(defn- wrap-on-drag-end-fn
[f]
(defn- wrap-on-drag-end-fn [f]
(fn [data]
(f (.-from ^js data) (.-to ^js data) (.-data ^js data))))
(defn- wrap-key-fn
[f]
(defn- wrap-key-fn [f]
(fn [data index]
{:post [(some? %)]}
(f data index)))
(defn base-list-props
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn]
:as props}]
(merge
{:data (to-array data)}
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
(when header {:ListHeaderComponent (reagent/as-element header)})
(when footer {:ListFooterComponent (reagent/as-element footer)})
(when on-drag-end-fn {:onDragEnd (wrap-on-drag-end-fn on-drag-end-fn)})
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn)))
[{:keys [key-fn render-fn empty-component header footer separator data render-data on-drag-end-fn] :as props}]
(merge {:data (to-array data)}
(when key-fn {:keyExtractor (wrap-key-fn key-fn)})
(when render-fn {:renderItem (wrap-render-fn render-fn render-data)})
(when separator {:ItemSeparatorComponent (fn [] (reagent/as-element separator))})
(when empty-component {:ListEmptyComponent (fn [] (reagent/as-element empty-component))})
(when header {:ListHeaderComponent (reagent/as-element header)})
(when footer {:ListFooterComponent (reagent/as-element footer)})
(when on-drag-end-fn {:onDragEnd (wrap-on-drag-end-fn on-drag-end-fn)})
(dissoc props :data :header :footer :empty-component :separator :render-fn :key-fn :on-drag-end-fn)))
(defn flat-list
[props]
(defn flat-list [props]
[rn-flat-list (base-list-props props)])
(defn draggable-flat-list
[props]
(defn draggable-flat-list [props]
[rn-draggable-flatlist (base-list-props props)])
(defn animated-flat-list
[props]
(defn animated-flat-list [props]
[animated-flat-list-class (base-list-props props)])
;; Hooks
(defn use-window-dimensions
[]
(defn use-window-dimensions []
(let [window (rn/useWindowDimensions)]
{:font-scale (.-fontScale window)
:height (.-height ^js window)
@@ -184,14 +163,12 @@
(def use-back-handler (.-useBackHandler hooks))
(defn use-keyboard
[]
(defn use-keyboard []
(let [kb (.useKeyboard hooks)]
{:keyboard-shown (.-keyboardShown ^js kb)
:keyboard-height (.-keyboardHeight ^js kb)}))
(defn use-layout
[]
(defn use-layout []
(let [{:keys [onLayout x y height width]} (bean/bean (.useLayout hooks))]
{:on-layout onLayout
:x x
+3 -6
View File
@@ -4,16 +4,13 @@
(def theme (reagent/atom nil))
(defn dark?
[]
(defn dark? []
(= :dark @theme))
(defn get-theme
[]
(defn get-theme []
@theme)
(defn set-theme
[value]
(defn set-theme [value]
(reset! theme value)
(reset! colors/theme (case value
:dark colors/dark-theme
+22 -19
View File
@@ -1,10 +1,14 @@
(ns quo2.components.avatars.account-avatar
(:require [quo2.components.icon :as icons]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
[quo2.components.icon :as icons]
[quo2.theme :as theme]))
(defn get-border-radius
[size]
(def icon-color-value
{:dark (get-in colors/customization [:dark :purple])
:light (get-in colors/customization [:light :purple])})
(defn get-border-radius [size]
(case size
80 16
48 12
@@ -12,8 +16,7 @@
24 8
20 6))
(defn get-inner-icon-sizes
[size]
(defn get-inner-icon-sizes [size]
(case size
80 36
48 24
@@ -22,20 +25,20 @@
20 11))
(defn account-avatar
[{:keys [size icon color]
:or {size 80
icon :i/placeholder
color :purple}}]
(let [icon-color (colors/custom-color-by-theme color 50 60)
[{:keys [size icon]
:or {size 80
icon :main-icons/placeholder}}]
(let [icon-color (if (theme/dark?)
(:dark icon-color-value)
(:light icon-color-value))
avatar-border-radius (get-border-radius size)
inner-icon-size (get-inner-icon-sizes size)]
[rn/view
{:style {:width size
:background-color icon-color
:height size
:border-radius avatar-border-radius
:justify-content :center
:align-items :center}}
inner-icon-size (get-inner-icon-sizes size)]
[rn/view {:style {:width size
:background-color icon-color
:height size
:border-radius avatar-border-radius
:justify-content :center
:align-items :center}}
[icons/icon icon
{:no-color true
:size inner-icon-size}]]))
+32 -38
View File
@@ -1,47 +1,41 @@
(ns quo2.components.avatars.channel-avatar
(:require [quo2.components.icon :as icons]
(:require [quo2.foundations.colors :as colors]
[react-native.core :as rn]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]))
[quo2.theme :as theme]))
(defn channel-avatar
[{:keys [big? locked? emoji-background-color emoji]}]
(defn channel-avatar [{:keys [big? locked? emoji-background-color emoji]}]
(let [lock-exists? (some? locked?)
dark? (theme/dark?)]
[rn/view
{:style {:width (if big? 32 24)
:height (if big? 32 24)
:border-radius (if big? 32 24)
:justify-content :center
:align-items :center
:background-color emoji-background-color}}
[rn/view
{:style {:display :flex
:justify-content :center
:align-items :center}}
[text/text
{:size (if big?
:paragraph-1
:label)} emoji]
[rn/view {:style {:width (if big? 32 24)
:height (if big? 32 24)
:border-radius (if big? 32 24)
:justify-content :center
:align-items :center
:background-color emoji-background-color}}
[rn/view {:style {:display :flex
:justify-content :center
:align-items :center}}
[text/text {:size (if big?
:paragraph-1
:label)} emoji]
(when lock-exists?
[rn/view
{:style {:position :absolute
:left (if big?
14
8)
:top (if big?
15
8)
:background-color (if dark?
colors/neutral-90
colors/white)
:border-radius 15
:padding 2}}
[icons/icon
(if locked?
:main-icons/locked
:main-icons/unlocked)
[rn/view {:style {:position :absolute
:left (if big?
14
8)
:top (if big?
15
8)
:background-color (if dark?
colors/neutral-90
colors/white)
:border-radius 15
:padding 2}}
[icons/icon (if locked?
:main-icons/locked
:main-icons/unlocked)
{:color (if dark?
colors/neutral-40
colors/neutral-50)
+12 -18
View File
@@ -1,6 +1,6 @@
(ns quo2.components.avatars.group-avatar
(:require [quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]
(:require [quo2.foundations.colors :as colors]
[quo2.components.icon :as icon]
[react-native.core :as rn]))
(def sizes
@@ -11,22 +11,16 @@
:medium 32
:large 48}})
;; TODO: this implementation does not support group display picture (can only display default group
;; icon).
(defn group-avatar
[_]
;; TODO: this implementation does not support group display picture (can only display default group icon).
(defn group-avatar [_]
(fn [{:keys [color size]}]
(let [container-size (get-in sizes [:container size])
icon-size (get-in sizes [:icon size])]
[rn/view
{:width container-size
:height container-size
:align-items :center
:justify-content :center
:border-radius (/ container-size 2)
;:background-color (colors/custom-color-by-theme color 50 60) ; TODO: this is temporary only.
;Issue: https://github.com/status-im/status-mobile/issues/14566
:background-color color}
[icon/icon :i/group
{:size icon-size
:color colors/white-opa-70}]])))
[rn/view {:width container-size
:height container-size
:align-items :center
:justify-content :center
:border-radius (/ container-size 2)
:background-color (colors/custom-color-by-theme color 50 60)}
[icon/icon :i/group {:size icon-size
:color colors/white-opa-70}]])))
+16 -18
View File
@@ -1,7 +1,7 @@
(ns quo2.components.avatars.icon-avatar
(:require [quo2.components.icon :as icons]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
[quo2.components.icon :as icons]))
(def sizes
{:big 48
@@ -12,19 +12,17 @@
[{:keys [size icon color opacity]
:or {opacity 20}}]
(let [component-size (size sizes)
circle-color (colors/custom-color color 50 opacity)
icon-color (colors/custom-color-by-theme color 50 60)
icon-size (case size
:big 20
:medium 16
:small 12)]
[rn/view
{:style {:width component-size
:height component-size
:border-radius component-size
:background-color circle-color
:justify-content :center
:align-items :center}}
[icons/icon icon
{:size icon-size
:color icon-color}]]))
circle-color (colors/custom-color color 50 opacity)
icon-color (colors/custom-color-by-theme color 50 60)
icon-size (case size
:big 20
:medium 16
:small 12)]
[rn/view {:style {:width component-size
:height component-size
:border-radius component-size
:background-color circle-color
:justify-content :center
:align-items :center}}
[icons/icon icon {:size icon-size
:color icon-color}]]))
+89 -100
View File
@@ -1,96 +1,91 @@
(ns quo2.components.avatars.user-avatar
(:require [clojure.string :refer [blank? split upper-case]]
[quo2.components.icon :as icons]
(:require [react-native.core :as rn]
[react-native.fast-image :as fast-image]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.icon :as icons]
[quo2.theme :refer [dark?]]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]))
[clojure.string :refer [upper-case split blank?]]))
(def sizes
{:big {:outer 80
:inner 72
:status-indicator 20
:status-indicator-border 4
:font-size :heading-1}
:medium {:outer 48
:inner 44
:status-indicator 12
:status-indicator-border 2
:font-size :paragraph-1}
:small {:outer 32
:inner 28
:status-indicator 12
:status-indicator-border 2
:font-size :paragraph-2}
:xs {:outer 24
:inner 24
:status-indicator 0
:status-indicator-border 0
:font-size :paragraph-2}
:xxs {:outer 20
:inner 20
:status-indicator 0
:status-indicator-border 0
:font-size :label}
:xxxs {:outer 16
:inner 16
:status-indicator 0
:status-indicator-border 0
:font-size :label}})
(def sizes {:big {:outer 80
:inner 72
:status-indicator 20
:status-indicator-border 4
:font-size :heading-1}
:medium {:outer 48
:inner 44
:status-indicator 12
:status-indicator-border 2
:font-size :paragraph-1}
:small {:outer 32
:inner 28
:status-indicator 12
:status-indicator-border 2
:font-size :paragraph-2}
:xs {:outer 24
:inner 24
:status-indicator 0
:status-indicator-border 0
:font-size :paragraph-2}
:xxs {:outer 20
:inner 20
:status-indicator 0
:status-indicator-border 0
:font-size :label}
:xxxs {:outer 16
:inner 16
:status-indicator 0
:status-indicator-border 0
:font-size :label}})
(defn dot-indicator
[size status-indicator? online? ring? dark?]
(when status-indicator?
(let [dimensions (get-in sizes [size :status-indicator])
(let [dimensions (get-in sizes [size :status-indicator])
border-width (get-in sizes [size :status-indicator-border])
right (case size
:big 2
:medium 0
:small -2
0)
bottom (case size
:big (if ring?
-1
2)
:medium (if ring?
0
-2)
:small (if ring?
-2
-2)
0)]
[rn/view
{:style {:background-color (if online?
colors/success-50
colors/neutral-40)
:width dimensions
:height dimensions
:border-width border-width
:border-radius dimensions
:border-color (if dark?
colors/neutral-100
colors/white)
:position :absolute
:bottom bottom
:right right}}])))
right (case size
:big 2
:medium 0
:small -2
0)
bottom (case size
:big (if ring?
-1
2)
:medium (if ring?
0
-2)
:small (if ring?
-2
-2)
0)]
[rn/view {:style {:background-color (if online?
colors/success-50
colors/neutral-40)
:width dimensions
:height dimensions
:border-width border-width
:border-radius dimensions
:border-color (if dark?
colors/neutral-100
colors/white)
:position :absolute
:bottom bottom
:right right}}])))
(defn container-styling
[inner-dimensions outer-dimensions]
{:width inner-dimensions
:position :absolute
:top (/ (- outer-dimensions inner-dimensions) 2)
:left (/ (- outer-dimensions inner-dimensions) 2)
:height inner-dimensions
(defn container-styling [inner-dimensions outer-dimensions]
{:width inner-dimensions
:position :absolute
:top (/ (- outer-dimensions inner-dimensions) 2)
:left (/ (- outer-dimensions inner-dimensions) 2)
:height inner-dimensions
:border-radius inner-dimensions})
(defn container
[inner-dimensions outer-dimensions & children]
[rn/view
{:style (merge {:background-color (colors/custom-color-by-theme :turquoise 50 60)
:justify-content :center
:align-items :center}
(container-styling inner-dimensions outer-dimensions))}
(defn container [inner-dimensions outer-dimensions & children]
[rn/view {:style (merge {:background-color (colors/custom-color-by-theme :turquoise 50 60)
:justify-content :center
:align-items :center}
(container-styling inner-dimensions outer-dimensions))}
children])
(def small-sizes #{:xs :xxs :xxxs})
@@ -117,11 +112,9 @@
identicon? (contains? identicon-sizes size)
small? (contains? small-sizes size)
outer-dimensions (get-in sizes [size :outer])
inner-dimensions (get-in sizes
[size
(if ring?
:inner
:outer)])
inner-dimensions (get-in sizes [size (if ring?
:inner
:outer)])
font-size (get-in sizes [size :font-size])
icon-text (if-not (or (blank? first-initial-letter)
(blank? initials))
@@ -129,26 +122,22 @@
first-initial-letter
initials)
"")]
[rn/view
{:accessibility-label :user-avatar
:style {:width outer-dimensions
:height outer-dimensions
:border-radius outer-dimensions}}
[rn/view {:accessibility-label :user-avatar
:style {:width outer-dimensions
:height outer-dimensions
:border-radius outer-dimensions}}
(when (and ring? identicon?)
[icons/icon :i/identicon-ring
{:size outer-dimensions
:no-color true}])
[icons/icon :i/identicon-ring {:size outer-dimensions
:no-color true}])
(if profile-picture
;; display image
[fast-image/fast-image
{:source profile-picture
:style (container-styling inner-dimensions outer-dimensions)}]
[fast-image/fast-image {:source {:uri profile-picture}
:style (container-styling inner-dimensions outer-dimensions)}]
;; else display initials
[container inner-dimensions outer-dimensions
^{:key :icon-text}
[text/text
{:weight :semi-bold
:size font-size
:style {:color colors/white-opa-70}}
[text/text {:weight :semi-bold
:size font-size
:style {:color colors/white-opa-70}}
(upper-case icon-text)]])
[dot-indicator size status-indicator? online? ring? (dark?)]]))
@@ -1,35 +1,31 @@
(ns quo2.components.avatars.wallet-user-avatar
(:require [clojure.string :as string]
[quo2.components.markdown.text :as text]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
[quo2.components.markdown.text :as text]
[clojure.string :as string]))
(def circle-sizes
{:small 20
:medium 32
:large 48
:x-large 80})
(def circle-sizes {:small 20
:medium 32
:large 48
:x-large 80})
(def font-sizes
{:small :label
:medium :paragraph-2
:large :paragraph-1
:x-large :heading-1})
(def font-sizes {:small :label
:medium :paragraph-2
:large :paragraph-1
:x-large :heading-1})
(def font-weights
{:small :medium
:medium :semi-bold
:large :semi-bold
:x-large :medium})
(def font-weights {:small :medium
:medium :semi-bold
:large :semi-bold
:x-large :medium})
(defn wallet-user-avatar
"params, first name, last name, color, size
and if it's dark or not!"
[{:keys [f-name l-name color size]
:or {f-name "John"
l-name "Doe"
color :red
size :x-large}}]
[{:keys [f-name l-name color size] :or {f-name "John"
l-name "Doe"
color :red
size :x-large}}]
(let [circle-size (size circle-sizes)
small? (= size :small)
f-name-initial (-> f-name
@@ -40,18 +36,16 @@
(subs 0 1))
circle-color (colors/custom-color color 50 20)
text-color (colors/custom-color-by-theme color 50 60)]
[rn/view
{:style {:width circle-size
:height circle-size
:border-radius circle-size
:text-align :center
:justify-content :center
:align-items :center
:background-color circle-color}}
[text/text
{:size (size font-sizes)
:weight (size font-weights)
:style {:color text-color}}
[rn/view {:style {:width circle-size
:height circle-size
:border-radius circle-size
:text-align :center
:justify-content :center
:align-items :center
:background-color circle-color}}
[text/text {:size (size font-sizes)
:weight (size font-weights)
:style {:color text-color}}
(if small?
(str f-name-initial)
(str f-name-initial l-name-initial))]]))
@@ -1,17 +0,0 @@
(ns quo2.components.banners.--tests--.banner-component-spec
(:require ["@testing-library/react-native" :as rtl]
[quo2.components.banners.banner.view :as banner]
[reagent.core :as reagent]))
(defn render-banner
[opts]
(rtl/render (reagent/as-element [banner/banner opts])))
(js/global.test "basic render of banner component"
(fn []
(render-banner {:pins-count "5"
:latest-pin-text "this message"})
(-> (js/expect (rtl/screen.getByText "this message"))
(.toBeTruthy))
(-> (js/expect (rtl/screen.getByText "5"))
(.toBeTruthy))))
@@ -1,19 +0,0 @@
(ns quo2.components.banners.banner.style
(:require [quo2.foundations.colors :as colors]))
(def container
{:width "100%"
:height 50
:background-color colors/primary-50-opa-20
:flex-direction :row
:align-items :center
:padding-horizontal 20
:padding-vertical 10})
(def counter
{:padding-right 22
:height 20
:width 20
:justify-content :center
:align-items :center})
@@ -1,24 +0,0 @@
(ns quo2.components.banners.banner.view
(:require [quo2.components.banners.banner.style :as style]
[quo2.components.counter.counter :as counter]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]))
(defn banner
[{:keys [show-pin? latest-pin-text pins-count on-press]}]
[rn/touchable-opacity
{:accessibility-label :pinned-banner
:style style/container
:active-opacity 1
:on-press on-press}
(when show-pin? [icons/icon :i/pin {:size 20}])
[text/text
{:number-of-lines 1
:size :paragraph-2
:style {:margin-left 10 :margin-right 50}}
latest-pin-text]
[rn/view
{:accessibility-label :pins-count
:style style/counter}
(when (pos? pins-count) [counter/counter {:type :secondary} pins-count])]])
@@ -1,28 +0,0 @@
(ns quo2.components.buttons.--tests--.buttons-component-spec
(:require ["@testing-library/react-native" :as rtl]
[quo2.components.buttons.button :as button]
[reagent.core :as reagent]))
(defn render-button
([options label]
(rtl/render (reagent/as-element [button/button options label]))))
(js/global.test "default render of button component"
(fn []
(render-button {:accessibility-label "test-button"} "")
(-> (js/expect (rtl/screen.getByLabelText "test-button"))
(.toBeTruthy))))
(js/global.test "button renders with a label"
(fn []
(render-button {} "test-label")
(-> (js/expect (rtl/screen.getByText "test-label"))
(.toBeTruthy))))
(js/global.test "button on-press works"
(let [event (js/jest.fn)]
(fn []
(render-button {:on-press event} "test-label")
(rtl/fireEvent.press (rtl/screen.getByText "test-label"))
(-> (js/expect event)
(.toHaveBeenCalledTimes 1)))))
+212 -249
View File
@@ -1,145 +1,143 @@
(ns quo2.components.buttons.button
(:require [quo2.components.icon :as quo2.icons]
[quo2.components.markdown.text :as text]
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]
[quo2.theme :as theme]
[react-native.core :as rn]
[reagent.core :as reagent]))
[reagent.core :as reagent]
[quo2.components.icon :as quo2.icons]))
(def themes
{:light {:primary {:icon-color colors/white
:label-color colors/white
:background-color {:default colors/primary-50
:pressed colors/primary-60
:disabled colors/primary-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
:label-color colors/white
:background-color {:default colors/danger-50
:pressed colors/danger-60
:disabled colors/danger-50}}
:positive {:icon-color colors/white
: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}}
: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
:label-color colors/white
:background-color {:default colors/primary-60
:pressed colors/primary-50
:disabled colors/primary-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-80
:pressed colors/neutral-60
:disabled colors/neutral-80}}
: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
:label-color colors/white
:background-color {:default colors/danger-60
:pressed colors/danger-50
:disabled colors/danger-60}}
:positive {:icon-color colors/white
: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-40
:label-color colors/white
:background-color {:default colors/white-opa-5
:pressed colors/white-opa-10
:disabled colors/white-opa-5}}
: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}}}})
{:light {:primary {:icon-color colors/white
:label-color colors/white
:background-color {:default colors/primary-50
:pressed colors/primary-60
:disabled colors/primary-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-20
:pressed colors/neutral-40
:disabled colors/neutral-20}}
: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
:label-color colors/white
:background-color {:default colors/danger-50
:pressed colors/danger-60
:disabled colors/danger-50}}
:positive {:icon-color colors/white
: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}}
: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
:label-color colors/white
:background-color {:default colors/primary-60
:pressed colors/primary-50
:disabled colors/primary-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-80
:pressed colors/neutral-60
:disabled colors/neutral-80}}
: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
:label-color colors/white
:background-color {:default colors/danger-60
:pressed colors/danger-50
:disabled colors/danger-60}}
:positive {:icon-color colors/white
: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-40
:label-color colors/white
:background-color {:default colors/white-opa-5
:pressed colors/white-opa-10
:disabled colors/white-opa-5}}
: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))
(defn shape-style-container [type icon size]
{:border-radius (if (and icon (#{:primary :secondary :danger} type))
24
(case size
56 12
@@ -147,43 +145,22 @@
32 10
24 8))})
(defn style-container
[type size disabled background-color border-color icon above width before after]
(defn style-container [type size disabled background-color border-color icon above width before after]
(merge {:height size
:align-items :center
:justify-content :center
:flex-direction (if above :column :row)
:background-color background-color
:padding-horizontal (when-not (or icon before after)
(case size
56 16
40 16
32 12
24 8))
(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))
(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))
(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))
(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))}
(case size 56 0 40 9 32 5 24 4))}
(shape-style-container type icon size)
(when width
{:width width})
@@ -195,8 +172,7 @@
(when disabled
{:opacity 0.3})))
(defn community-themed?
[type community-color]
(defn community-themed? [type community-color]
(and (= type :community) (string? community-color)))
(defn button
@@ -216,97 +192,85 @@
[button {:icon true} :main-icons/close-circle]"
[_ _]
(let [pressed (reagent/atom false)]
(fn
[{:keys [on-press disabled type size community-color community-text-color before after above
width
override-theme override-background-color
on-long-press accessibility-label icon icon-no-color style test-ID]
:or {type :primary
size 40}}
children]
(fn [{:keys [on-press disabled type size community-color community-text-color before after above width
override-theme override-background-color
on-long-press accessibility-label icon icon-no-color style test-ID]
:or {type :primary
size 40}}
children]
(let [{:keys [icon-color icon-secondary-color background-color label-color border-color]}
(get-in themes
[(or
override-theme
(theme/get-theme)) type])
state (cond disabled :disabled
@pressed :pressed
:else :default)
icon-size (when (= 24 size) 12)
(get-in themes [(or
override-theme
(theme/get-theme)) type])
state (cond disabled :disabled @pressed :pressed :else :default)
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}
(when on-press
{:on-press (fn []
(on-press))})
(when on-long-press
{:on-long-press (fn []
(on-long-press))})
{:on-press-in (fn []
(reset! pressed true))}
{:on-press-out (fn []
(reset! pressed nil))})
[rn/touchable-without-feedback (merge {:test-ID test-ID
:disabled disabled
:accessibility-label accessibility-label}
(when on-press
{:on-press (fn []
(on-press))})
(when on-long-press
{:on-long-press (fn []
(on-long-press))})
{:on-press-in (fn []
(reset! pressed true))}
{:on-press-out (fn []
(reset! pressed nil))})
[rn/view
{:style (merge
(shape-style-container type icon size)
{:background-color
(if (= state :pressed)
(colors/theme-colors colors/neutral-100 colors/white)
:transparent)}
style)}
[rn/view
{:style (merge
(style-container
type
size
disabled
(or override-background-color (get background-color state))
(get border-color state)
icon
above
width
before
after)
(when
(community-themed? type community-color)
(merge
{:background-color community-color}
(when (= state :pressed) {:opacity 0.9}))))}
[rn/view {:style (merge
(shape-style-container type icon size)
{:background-color
(if (= state :pressed)
(colors/theme-colors colors/neutral-100 colors/white)
:transparent)}
style)}
[rn/view {:style (merge
(style-container
type
size
disabled
(or override-background-color (get background-color state))
(get border-color state)
icon
above
width
before
after)
(when
(community-themed? type community-color)
(merge
{:background-color community-color}
(when (= state :pressed) {:opacity 0.9}))))}
(when above
[rn/view
[quo2.icons/icon above
{:container-style {:margin-bottom 2}
:color icon-secondary-color
:size icon-size}]])
[quo2.icons/icon above {:container-style {:margin-bottom 2}
:color icon-secondary-color
:size icon-size}]])
(when before
[rn/view
[quo2.icons/icon before
{:container-style {:margin-left (if (= size 40) 12 8)
:margin-right 4}
:color icon-secondary-color
:size icon-size}]])
[quo2.icons/icon before {:container-style {:margin-left (if (= size 40) 12 8)
:margin-right 4}
: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}]
[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 (if
(and
(community-themed? type community-color)
(string? community-text-color))
community-text-color
label-color)}}
[text/text {:size (when (#{56 24} size) :paragraph-2)
:weight :medium
:number-of-lines 1
:style {:color (if
(and
(community-themed? type community-color)
(string? community-text-color))
community-text-color
label-color)}}
children]
@@ -314,8 +278,7 @@
children)]
(when after
[rn/view
[quo2.icons/icon after
{:container-style {:margin-left 4
:margin-right (if (= size 40) 12 8)}
:color icon-secondary-color
:size icon-size}]])]]]))))
[quo2.icons/icon after {:container-style {:margin-left 4
:margin-right (if (= size 40) 12 8)}
:color icon-secondary-color
:size icon-size}]])]]]))))
+35 -40
View File
@@ -1,12 +1,11 @@
(ns quo2.components.buttons.dynamic-button
(:require [quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
(:require [react-native.core :as rn]
[reagent.core :as reagent]
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[reagent.core :as reagent]))
[quo2.components.markdown.text :as text]))
(defn- get-button-color
[type pressed? customization-color]
(defn- get-button-color [type pressed? customization-color]
(if (#{:jump-to :mention} type)
(if pressed?
(colors/custom-color-by-theme customization-color 60 50)
@@ -15,14 +14,12 @@
(colors/theme-colors colors/neutral-80-opa-80 colors/white-opa-80)
(colors/theme-colors colors/neutral-80-opa-70 colors/white-opa-70))))
(defn- get-icon-and-text-color
[type]
(defn- get-icon-and-text-color [type]
(if (#{:jump-to :mention} type)
colors/white
(colors/theme-colors colors/white colors/neutral-100)))
(defn- icon-view
[type]
(defn- icon-view [type]
[icon/icon
(case type
:jump-to :i/jump-to
@@ -31,7 +28,7 @@
:notification-up :i/arrow-up
:search-with-label :i/search
:search :i/search
:scroll-to-bottom :i/arrow-down)
:bottom :i/arrow-down)
{:size 12
:color (get-icon-and-text-color type)
:container-style {:margin-top 6
@@ -43,7 +40,7 @@
:notification-up 2
:search-with-label 8
:search 6
:scroll-to-bottom 6)
:bottom 6)
:margin-right (case type
:jump-to 8
:mention 2
@@ -51,12 +48,12 @@
:notification-up 8
:search-with-label 4
:search 6
:scroll-to-bottom 6)}}])
:bottom 6)}}])
(defn dynamic-button
"[dynamic-button opts]
opts
{:type :jump-to/:mention/:notification-down/:notification-up/:search/:search-with-label/:scroll-to-bottom
{:type :jump-to/:mention/:notification-down/:notification-up/:search/:search-with-label/:bottom
:on-press fn
:count mentions or notifications count
:customization-color customize jump-to and mention button color}"
@@ -70,34 +67,32 @@
:active-opacity 1
:style {:padding 5}
:accessibility-label type}
[rn/view
{:style (merge
{:flex-direction :row
:height 24
:border-radius 12
:background-color (get-button-color type @pressed? (or customization-color :primary))}
style)}
(when (#{:mention :search :search-with-label :scroll-to-bottom} type)
[rn/view {:style (merge
{:flex-direction :row
:height 24
:border-radius 12
:background-color (get-button-color type @pressed? (or customization-color :primary))}
style)}
(when (#{:mention :search :search-with-label :bottom} type)
[icon-view type])
(when (#{:jump-to :mention :notification-down :notification-up :search-with-label} type)
[text/text
{:weight :medium
:size :paragraph-2
:style {:color (get-icon-and-text-color type)
:margin-top 2.5
:margin-bottom 3.5
:margin-left (case type
:jump-to 8
:mention 0
:notification-down 8
:notification-up 8
:search-with-label 0)
:margin-right (case type
:jump-to 0
:mention 8
:notification-down 0
:notification-up 0
:search-with-label 8)}}
[text/text {:weight :medium
:size :paragraph-2
:style {:color (get-icon-and-text-color type)
:margin-top 2.5
:margin-bottom 3.5
:margin-left (case type
:jump-to 8
:mention 0
:notification-down 8
:notification-up 8
:search-with-label 0)
:margin-right (case type
:jump-to 0
:mention 8
:notification-down 0
:notification-up 0
:search-with-label 8)}}
(case type
:jump-to label
:search-with-label label
+74 -95
View File
@@ -3,36 +3,35 @@
[cljs-bean.core :as bean]
[clojure.string :as string]
[oops.core :as oops]
[react-native.core :as rn]
[quo2.theme :as theme]
[quo2.components.buttons.button :as button]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]
[reagent.core :as reagent]
[react-native.linear-gradient :as linear-gradient]
[react-native.masked-view :as masked-view]
[react-native.syntax-highlighter :as highlighter]
[reagent.core :as reagent]))
[react-native.syntax-highlighter :as highlighter]))
;; Example themes:
;; https://github.com/react-syntax-highlighter/react-syntax-highlighter/tree/master/src/styles/hljs
(def ^:private themes
{:light {:hljs-comment {:color colors/neutral-40}
:hljs-title {:color (colors/custom-color :blue 50)}
:hljs-keyword {:color (colors/custom-color :green 50)}
:hljs-string {:color (colors/custom-color :turquoise 50)}
{:light {:hljs-comment {:color colors/neutral-40},
:hljs-title {:color (colors/custom-color :blue 50)},
:hljs-keyword {:color (colors/custom-color :green 50)},
:hljs-string {:color (colors/custom-color :turquoise 50)},
:hljs-literal {:color (colors/custom-color :turquoise 50)}
:hljs-number {:color (colors/custom-color :turquoise 50)}
:line-number {:color colors/neutral-40}}
:dark {:hljs-comment {:color colors/neutral-60}
:hljs-title {:color (colors/custom-color :blue 60)}
:hljs-keyword {:color (colors/custom-color :green 60)}
:hljs-string {:color (colors/custom-color :turquoise 60)}
:dark {:hljs-comment {:color colors/neutral-60},
:hljs-title {:color (colors/custom-color :blue 60)},
:hljs-keyword {:color (colors/custom-color :green 60)},
:hljs-string {:color (colors/custom-color :turquoise 60)},
:hljs-literal {:color (colors/custom-color :turquoise 60)}
:hljs-number {:color (colors/custom-color :turquoise 60)}
:line-number {:color colors/neutral-40}}})
(defn- text-style
[class-names]
(defn- text-style [class-names]
(->> class-names
(map keyword)
(reduce #(merge %1 (get-in themes [(theme/get-theme) %2]))
@@ -44,41 +43,35 @@
;; layout.
:line-height 18})))
(defn- render-nodes
[nodes]
(defn- render-nodes [nodes]
(map (fn [{:keys [children value] :as node}]
;; Node can have :children or a :value.
(if children
(into [text/text
{:weight :code
:size :paragraph-2
:style (text-style (get-in node [:properties :className]))}]
(into [text/text {:weight :code
:size :paragraph-2
:style (text-style (get-in node [:properties :className]))}]
(render-nodes children))
;; Remove newlines as we already render each line separately.
(-> value string/trim-newline)))
nodes))
(defn- code-block
[{:keys [rows line-number-width]}]
(defn- code-block [{:keys [rows line-number-width]}]
[into [:<>]
(->> rows
(render-nodes)
;; Line numbers
(map-indexed (fn [idx row]
(conj [rn/view {:style {:flex-direction :row}}
[rn/view
{:style {:width line-number-width
;; 8+12 margin
:margin-right 20}}
[text/text
{:weight :code
:size :paragraph-2
:style (text-style ["line-number"])}
[rn/view {:style {:width line-number-width
;; 8+12 margin
:margin-right 20}}
[text/text {:weight :code
:size :paragraph-2
:style (text-style ["line-number"])}
(inc idx)]]]
row))))])
(defn- native-renderer
[]
(defn- native-renderer []
(let [text-height (reagent/atom nil)]
(fn [{:keys [rows max-lines on-copy-press]}]
(let [background-color (colors/theme-colors
@@ -96,81 +89,67 @@
max-line-digits (-> rows count (min max-rows) str count)
;; ~ 9 is char width, 18 is width used in Figma.
line-number-width (* font-scale (max 18 (* 9 max-line-digits)))
max-text-height (some-> max-lines
(* font-scale 18)) ;; 18 is font's line height.
max-text-height (some-> max-lines (* font-scale 18)) ;; 18 is font's line height.
truncated? (and max-text-height (< max-text-height @text-height))
maybe-mask-wrapper (if truncated?
[masked-view/masked-view
{:mask-element
(reagent/as-element
[linear-gradient/linear-gradient
{:colors ["black" "transparent"]
:locations [0.75 1]
:style {:flex 1}}])}]
[linear-gradient/linear-gradient {:colors ["black" "transparent"]
:locations [0.75 1]
:style {:flex 1}}])}]
[:<>])]
[rn/view
{:style {:overflow :hidden
:padding 8
:background-color background-color
:border-color border-color
:border-width 1
:border-radius 8
;; Hide on intial render to avoid flicker when mask-wrapper is shown.
:opacity (if @text-height 1 0)}}
[rn/view {:style {:overflow :hidden
:padding 8
:background-color background-color
:border-color border-color
:border-width 1
:border-radius 8
;; Hide on intial render to avoid flicker when mask-wrapper is shown.
:opacity (if @text-height 1 0)}}
;; Line number container
[rn/view
{:style {:position :absolute
:bottom 0
:top 0
:left 0
:width (+ line-number-width 8 8)
:background-color background-color-left
:border-right-color border-color
:border-right-width 1}}]
(conj maybe-mask-wrapper
[rn/view {:max-height max-text-height}
[rn/view
{:on-layout (fn [evt]
(let [height (oops/oget evt "nativeEvent.layout.height")]
(reset! text-height height)))}
[code-block
{:rows (take max-rows rows)
:line-number-width line-number-width}]]])
[rn/view {:style {:position :absolute
:bottom 0
:top 0
:left 0
:width (+ line-number-width 8 8)
:background-color background-color-left
:border-right-color border-color
:border-right-width 1}}]
(conj maybe-mask-wrapper [rn/view {:max-height max-text-height}
[rn/view {:on-layout (fn [evt]
(let [height (oops/oget evt "nativeEvent.layout.height")]
(reset! text-height height)))}
[code-block {:rows (take max-rows rows)
:line-number-width line-number-width}]]])
;; Copy button
[rn/view
{:style {:position :absolute
:bottom 8
:right 8}}
[button/button
{:icon true
:type :grey
:size 24
:on-press on-copy-press}
[rn/view {:style {:position :absolute
:bottom 8
:right 8}}
[button/button {:icon true
:type :grey
:size 24
:on-press on-copy-press}
:main-icons/copy]]]))))
(defn- wrap-renderer-fn
[f {:keys [max-lines on-copy-press]}]
(defn- wrap-renderer-fn [f {:keys [max-lines on-copy-press]}]
(fn [^js props]
(reagent/as-element [:f> f
{:rows (.-rows props)
:max-lines max-lines
:on-copy-press on-copy-press}])))
(reagent/as-element [:f> f {:rows (.-rows props)
:max-lines max-lines
:on-copy-press on-copy-press}])))
(defn snippet
[{:keys [language max-lines on-copy-press]} children]
[highlighter/highlighter
{:language language
:renderer (wrap-renderer-fn
native-renderer
{:max-lines max-lines
:on-copy-press #(when on-copy-press
(on-copy-press children))})
;; Default props to adapt Highlighter for react-native.
:CodeTag react-native/View
:PreTag react-native/View
:show-line-numbers false
:style #js {}
:custom-style #js {:backgroundColor nil}}
(defn snippet [{:keys [language max-lines on-copy-press]} children]
[highlighter/highlighter {:language language
:renderer (wrap-renderer-fn
native-renderer {:max-lines max-lines
:on-copy-press #(when on-copy-press
(on-copy-press children))})
;; Default props to adapt Highlighter for react-native.
:CodeTag react-native/View
:PreTag react-native/View
:show-line-numbers false
:style #js {}
:custom-style #js {:backgroundColor nil}}
children])
@@ -1,21 +1,18 @@
(ns quo2.components.community.community-card-view
(:require [quo2.components.community.community-view :as community-view]
[quo2.components.community.icon :as icon]
[quo2.components.community.style :as style]
[react-native.core :as rn]))
(:require
[quo2.components.community.community-view :as community-view]
[quo2.components.community.style :as style]
[react-native.core :as rn]))
(defn community-card-view-item
[{:keys [name description locked images
[{:keys [name description locked
status tokens cover tags width]} on-press]
[rn/touchable-opacity
{:accessibility-label :community-card-item
:on-press on-press}
[rn/touchable-opacity {:on-press on-press}
[rn/view {:style (style/community-card 20)}
[rn/view
{:style {:width width
:height 230
:border-radius 20}
:on-press on-press}
[rn/view {:style {:width width
:height 230
:border-radius 20}
:on-press on-press}
[rn/view
{:flex 1}
[rn/view (style/community-cover-container 40)
@@ -25,15 +22,14 @@
{:flex 1
:border-radius 20}}]]
[rn/view (style/card-view-content-container 12)
[rn/view (style/card-view-chat-icon 48)
[icon/community-icon {:images images} 48]]
[rn/view (style/card-view-chat-icon 48)]
;;TODO new pure component based on quo2 should be implemented without status-im usage
;[communities.icon/community-icon-redesign community 48]]
(when (= status :gated)
[rn/view (style/permission-tag-styles)
[community-view/permission-tag-container
{:locked locked
:status status
:tokens tokens}]])
[community-view/permission-tag-container {:locked locked
:status status
:tokens tokens}]])
[community-view/community-title
{:title name
:description description}]
@@ -1,131 +1,112 @@
(ns quo2.components.community.community-list-view
(:require [quo2.components.community.community-view :as community-view]
[quo2.components.community.style :as style]
[quo2.components.counter.counter :as counter]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.fast-image :as fast-image]))
(:require
[quo2.components.community.community-view :as community-view]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.counter.counter :as counter]
[quo2.components.icon :as icons]
[quo2.components.community.style :as style]
[react-native.fast-image :as fast-image]
[react-native.core :as rn]))
(defn community-icon-view
[community-icon]
[rn/view
{:width 32
:height 32}
[fast-image/fast-image
{:source {:uri community-icon}
:style {:height 32
:border-radius 16
:width 32}}]])
(defn community-icon-view [community-icon]
[rn/view {:width 32
:height 32}
[fast-image/fast-image {:source {:uri community-icon}
:style {:height 32
:border-radius 16
:width 32}}]])
(defn notification-view
[{:keys [muted?
unread-messages?
unread-mentions-count]}]
(defn notification-view [{:keys [muted?
unread-messages?
unread-mentions-count]}]
(cond
muted?
[icons/icon :i/muted
{:container-style {:align-items :center
:justify-content :center}
:resize-mode :center
:size 20
:color (colors/theme-colors
colors/neutral-40
colors/neutral-50)}]
[icons/icon :i/muted {:container-style {:align-items :center
:justify-content :center}
:resize-mode :center
:size 20
:color (colors/theme-colors
colors/neutral-40
colors/neutral-50)}]
(pos? unread-mentions-count)
[counter/counter {:type :default} unread-mentions-count]
unread-messages?
[rn/view
{:style {:width 8
:height 8
:border-radius 4
:background-color (colors/theme-colors
colors/neutral-40
colors/neutral-60)}}]))
[rn/view {:style {:width 8
:height 8
:border-radius 4
:background-color (colors/theme-colors
colors/neutral-40
colors/neutral-60)}}]))
(defn communities-list-view-item
[props
{:keys [name
locked?
status
muted?
unread-messages?
unread-mentions-count
community-icon
tokens
background-color]}]
[rn/view
{:style (merge (style/community-card 16)
{:margin-bottom 12
:margin-horizontal 20})}
[rn/touchable-highlight
(merge {:style {:height 56
:border-radius 16}}
props)
(defn communities-list-view-item [props {:keys [name
locked?
status
muted?
unread-messages?
unread-mentions-count
community-icon
tokens
background-color]}]
[rn/view {:style (merge (style/community-card 16)
{:margin-bottom 12
:margin-horizontal 20})}
[rn/touchable-highlight (merge {:style {:height 56
:border-radius 16}}
props)
[rn/view {:flex 1}
[rn/view
{:flex-direction :row
:border-radius 16
:padding-horizontal 12
:align-items :center
:padding-vertical 8
:background-color background-color}
[rn/view {:flex-direction :row
:border-radius 16
:padding-horizontal 12
:align-items :center
:padding-vertical 8
:background-color background-color}
[rn/view]
(when community-icon
[community-icon-view community-icon])
[rn/view
{:flex 1
:margin-horizontal 12}
[text/text
{:weight :semi-bold
:size :paragraph-1
:accessibility-label :community-name-text
:number-of-lines 1
:ellipsize-mode :tail
:style {:color (when muted?
(colors/theme-colors
colors/neutral-40
colors/neutral-60))}}
[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 :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?}])]]]])
[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
{:keys [name
muted?
unread-messages?
unread-mentions-count
status
community-icon
tokens
locked?]}]
(defn communities-membership-list-item [props {:keys [name
muted?
unread-messages?
unread-mentions-count
status
community-icon
tokens
locked?]}]
[rn/view {:margin-bottom 20}
[rn/touchable-highlight
(merge {:underlay-color colors/primary-50-opa-5
:style {:border-radius 12}}
props)
[rn/touchable-highlight (merge {:underlay-color colors/primary-50-opa-5
:style {:border-radius 12}}
props)
[rn/view {:flex 1}
[rn/view
{:flex-direction :row
:border-radius 16
:align-items :center}
[rn/view {:flex-direction :row
:border-radius 16
:align-items :center}
(when community-icon
[community-icon-view community-icon])
[rn/view
{:flex 1
:margin-left 12
:justify-content :center}
[rn/view {:flex 1
:margin-left 12
:justify-content :center}
[text/text
{:accessibility-label :chat-name-text
:number-of-lines 1
@@ -134,14 +115,11 @@
:size :paragraph-1}
name]]
[rn/view
{:justify-content :center
:margin-right 16}
[rn/view {:justify-content :center
:margin-right 16}
(if (= status :gated)
[community-view/permission-tag-container
{:locked? locked?
:tokens tokens}]
[notification-view
{:muted? muted?
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]]])
[community-view/permission-tag-container {:locked? locked?
:tokens tokens}]
[notification-view {:muted? muted?
:unread-mentions-count unread-mentions-count
:unread-messages? unread-messages?}])]]]]])
@@ -1,46 +1,38 @@
(ns quo2.components.community.community-view
(:require [quo2.components.community.style :as style]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.tags.permission-tag :as permission]
[quo2.components.tags.tag :as tag]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(:require
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icons]
[quo2.foundations.colors :as colors]
[quo2.components.tags.permission-tag :as permission]
[quo2.components.tags.tag :as tag]
[quo2.components.community.style :as style]
[react-native.core :as rn]))
(defn community-stats
[{:keys [icon members-count icon-color]}]
(defn community-stats [{:keys [icon members-count icon-color]}]
[rn/view (style/stats-count-container)
[rn/view {:margin-right 4}
[icons/icon icon
{:container-style {:align-items :center
:justify-content :center}
:resize-mode :center
:size 16
:color icon-color}]]
[text/text
{:weight :regular
:size :paragraph-1}
[icons/icon icon {:container-style {:align-items :center
:justify-content :center}
:resize-mode :center
:size 16
:color icon-color}]]
[text/text {:weight :regular
:size :paragraph-1}
members-count]])
(defn community-stats-column
[type]
(defn community-stats-column [type]
(let [icon-color (colors/theme-colors colors/neutral-50 colors/neutral-40)]
[rn/view
(if (= type :card-view)
(style/card-stats-container)
(style/list-stats-container))
[community-stats
{:icon :i/group
:members-count "629.2K" ;;TODO here should be formatted value, use money/format-members from
;;outside this component
:icon-color icon-color}]
[community-stats
{:icon :i/lightning
:members-count "112.1K"
:icon-color icon-color}]]))
[rn/view (if (= type :card-view)
(style/card-stats-container)
(style/list-stats-container))
[community-stats {:icon :i/group
:members-count "629.2K" ;;TODO here should be formatted value, use money/format-members from outside this component
:icon-color icon-color}]
[community-stats {:icon :i/lightning
:members-count "112.1K"
:icon-color icon-color}]]))
(defn community-tags
[tags]
(defn community-tags [tags]
[rn/view (style/community-tags-container)
(for [{:keys [id tag-label resource]} tags]
^{:key id}
@@ -53,8 +45,7 @@
:labelled true
:resource resource}]])])
(defn community-title
[{:keys [title description size] :or {size :small}}]
(defn community-title [{:keys [title description size] :or {size :small}}]
[rn/view (style/community-title-description-container (if (= size :large) 56 32))
(when title
[text/text
@@ -74,14 +65,12 @@
:style {:margin-top (if (= size :large) 8 2)}}
description])])
(defn permission-tag-container
[{:keys [locked? tokens on-press]}]
[permission/tag
{:background-color (colors/theme-colors
colors/neutral-10
colors/neutral-80)
:locked? locked?
:tokens tokens
(defn permission-tag-container [{:keys [locked? tokens on-press]}]
[permission/tag {:background-color (colors/theme-colors
colors/neutral-10
colors/neutral-80)
:locked? locked?
:tokens tokens
:size 24
:on-press on-press}])
:size 24
:on-press on-press}])
@@ -1,107 +1,94 @@
(ns quo2.components.community.discover-card
(:require [quo2.components.community.style :as style]
[quo2.components.markdown.text :as text]
(:require [quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.components.community.style :as style]
[react-native.core :as rn]))
;; Discover card placeholders images.
;; TODO replaced when real data is available
(def images
{:images [{:id 1 :column-images [{:id 1 :image ""}]}
{:images [{:id 1 :column-images [{:id 1 :image ""}]}
{:id 2 :column-images [{}]}]})
(defn card-title-and-description
[title description]
(defn card-title-and-description [title description]
[rn/view
{:flex 1
:padding-top 8
:padding-bottom 8
:border-radius 12}
[rn/view
{:flex 1
:padding-horizontal 12}
[text/text
{:accessibility-label :community-name-text
:ellipsize-mode :tail
:number-of-lines 1
:weight :semi-bold
:size :paragraph-1}
{:flex 1
:padding-top 8
:padding-bottom 8
:border-radius 12}
[rn/view {:flex 1
:padding-horizontal 12}
[text/text {:accessibility-label :community-name-text
:ellipsize-mode :tail
:number-of-lines 1
:weight :semi-bold
:size :paragraph-1}
title]
[text/text
{:accessibility-label :community-name-text
:ellipsize-mode :tail
:number-of-lines 1
:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)
:weight :regular
:size :paragraph-2}
[text/text {:accessibility-label :community-name-text
:ellipsize-mode :tail
:number-of-lines 1
:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)
:weight :regular
:size :paragraph-2}
description]]])
(defn placeholder-list-images
[{:keys [images width height border-radius]}]
(defn placeholder-list-images [{:keys [images width height border-radius]}]
[rn/view
[rn/view {:justify-content :center}
[rn/view {:justify-content :center}
(for [{:keys [id]} images]
^{:key id}
[rn/view
{:border-radius border-radius
:margin-top 4
:margin-right 4
:width width
:height height
:background-color colors/neutral-10}])]])
[rn/view {:border-radius border-radius
:margin-top 4
:margin-right 4
:width width
:height height
:background-color colors/neutral-10}])]])
(defn placeholder-row-images
[{:keys [first-image last-image images width height
border-radius]}]
(defn placeholder-row-images [{:keys [first-image last-image images width height
border-radius]}]
[rn/view
(when first-image
[rn/view
{:border-bottom-right-radius 6
:border-bottom-left-radius 6
:margin-right 4
:width width
:height height
:background-color colors/neutral-10}])
[rn/view {:border-bottom-right-radius 6
:border-bottom-left-radius 6
:margin-right 4
:width width
:height height
:background-color colors/neutral-10}])
(when images
[placeholder-list-images
{:images images
:width 32
:height 32
:border-radius 6}])
[placeholder-list-images {:images images
:width 32
:height 32
:border-radius 6}])
(when last-image
[rn/view
{:border-top-left-radius border-radius
:border-top-right-radius 6
:margin-top 4
:width width
:height height
:background-color colors/neutral-10}])])
[rn/view {:border-top-left-radius border-radius
:border-top-right-radius 6
:margin-top 4
:width width
:height height
:background-color colors/neutral-10}])])
(defn discover-card
[{:keys [title description on-press accessibility-label]}]
(let [on-joined-images (get images :images)]
(defn discover-card [{:keys [title description on-press accessibility-label]}]
(let [on-joined-images (get images :images)]
[rn/touchable-without-feedback
{:on-press on-press
:accessibility-label accessibility-label}
[rn/view
(merge (style/community-card 16)
{:background-color (colors/theme-colors
colors/white
colors/neutral-90)}
{:flex-direction :row
:margin-horizontal 20
:height 56
:padding-right 12})
[rn/view (merge (style/community-card 16)
{:background-color (colors/theme-colors
colors/white
colors/neutral-90)}
{:flex-direction :row
:margin-horizontal 20
:height 56
:padding-right 12})
[card-title-and-description title description]
(for [{:keys [id column-images]} on-joined-images]
^{:key id}
[placeholder-row-images
{:images (when (= id 1)
column-images)
:width 32
:height (if (= id 1) 8 26)
:border-radius 6
:first-image "" ; TODO replace with real data
:last-image ""}])]])) ; TODO replace with real data
[placeholder-row-images {:images (when (= id 1)
column-images)
:width 32
:height (if (= id 1) 8 26)
:border-radius 6
:first-image "" ; TODO replace with real data
:last-image ""}])]])) ; TODO replace with real data
-13
View File
@@ -1,13 +0,0 @@
(ns quo2.components.community.icon
(:require [react-native.core :as rn]))
(defn community-icon
[{:keys [images]} size]
(let [thumbnail-image (get-in images [:thumbnail :uri])]
[rn/image
{:source {:uri thumbnail-image}
:style {:border-radius 50
:border-width 0
:border-color :transparent
:width size
:height size}}]))
+45 -59
View File
@@ -8,66 +8,57 @@
:height 52
:padding-left 18})
(defn community-card
[radius]
{:shadow-offset {:width 0
(defn community-card [radius]
{:shadow-offset {:width 0
:height 2}
:shadow-radius radius
:shadow-opacity 1
:shadow-color colors/shadow
:border-radius radius
:justify-content :space-between
:elevation 2
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
:shadow-radius radius
:shadow-opacity 1
:shadow-color colors/shadow
:border-radius radius
:justify-content :space-between
:elevation 2
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
(defn stats-count-container
[]
(defn stats-count-container []
{:flex-direction :row
:align-items :center
:margin-right 16})
(defn card-stats-container
[]
(defn card-stats-container []
{:flex-direction :row})
(defn list-stats-container
[]
(defn list-stats-container []
{:flex-direction :row
:align-items :center})
(defn community-tags-container
[]
(defn community-tags-container []
{:flex-direction :row})
(defn card-stats-position
[]
{:position :absolute
:top 116
:right 12
:left 12})
(defn card-stats-position []
{:position :absolute
:top 116
:right 12
:left 12})
(defn community-tags-position
[]
{:position :absolute
:top 154
:right 12
:left 12})
(defn community-tags-position []
{:position :absolute
:top 154
:right 12
:left 12})
(defn card-view-content-container
[padding-horizontal]
{:flex 1
:height 20
:padding-left padding-horizontal
:padding-right padding-horizontal
:border-radius 16
(defn card-view-content-container [padding-horizontal]
{:flex 1
:height 20
:padding-left padding-horizontal
:padding-right padding-horizontal
:border-radius 16
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
(defn card-view-chat-icon
[icon-size]
(defn card-view-chat-icon [icon-size]
{:border-radius 48
:position :absolute
:top (- (/ icon-size 2))
@@ -77,34 +68,29 @@
colors/white
colors/neutral-90)})
(defn list-view-content-container
[]
{:flex-direction :row
:border-radius 16
:align-items :center
(defn list-view-content-container []
{:flex-direction :row
:border-radius 16
:align-items :center
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
(defn list-view-chat-icon
[]
{:border-radius 32
:padding 12})
(defn list-view-chat-icon []
{:border-radius 32
:padding 12})
(defn community-title-description-container
[margin-top]
(defn community-title-description-container [margin-top]
{:margin-top margin-top})
(defn community-cover-container
[height]
(defn community-cover-container [height]
{:flex-direction :row
:height height
:border-top-right-radius 20
:border-top-left-radius 20
:background-color colors/primary-50-opa-20})
(defn permission-tag-styles
[]
{:position :absolute
:top 8
:right 8})
(defn permission-tag-styles []
{:position :absolute
:top 8
:right 8})
+111 -143
View File
@@ -7,89 +7,81 @@
[quo2.components.markdown.text :as text]
[quo2.components.tags.token-tag :as token-tag]
[quo2.foundations.colors :as colors]
[i18n.i18n :as i18n]
[status-im.i18n.i18n :as i18n]
[status-im.ui.components.fast-image :as fast-image]))
(def ^:private token-tag-horizontal-spacing 7)
(def token-tag-vertical-spacing 5)
(def styles
{:container {:flex 1
:padding-horizontal 20}
:header-container {:flex-direction :row
:align-items :center}
:header-spacing-community {:margin-bottom 16}
:header-spacing-channel {:margin-bottom 24}
:header-avatar {:margin-right 8}
:header-community-avatar-image {:width 32 :height 32}
:header-title-container {:flex 1
:flex-direction :row
:align-items :center}
:header-title-lock {:margin-left 6}
:header-info-button {:margin-left 8}
:token-requirement-text-spacing {:margin-vertical 8}
:token-requirement-list-spacing {:padding-vertical (- 8 token-tag-vertical-spacing)}
:token-row {:flex-direction :row
:flex-wrap :wrap
:align-items :center}
:token-row-container {:flex-direction :row
:align-items :center
:margin-horizontal (- token-tag-horizontal-spacing)}
:token-row-container-no-shift {:margin-left 0}
:token-row-or-text {:margin-right 3}
:token-tag-spacing {:margin-horizontal token-tag-horizontal-spacing
:margin-vertical token-tag-vertical-spacing}
:divider {:height 1
:margin-horizontal -20
:margin-top (- 12 token-tag-vertical-spacing)
:margin-bottom 8}
:membership-request-denied {:margin-top 13}
:enter-button {:margin-top 16}
:info-text {:margin-top 12
:text-align :center
:padding-horizontal 20}})
(def styles {:container {:flex 1
:padding-horizontal 20}
:header-container {:flex-direction :row
:align-items :center}
:header-spacing-community {:margin-bottom 16}
:header-spacing-channel {:margin-bottom 24}
:header-avatar {:margin-right 8}
:header-community-avatar-image {:width 32 :height 32}
:header-title-container {:flex 1
:flex-direction :row
:align-items :center}
:header-title-lock {:margin-left 6}
:header-info-button {:margin-left 8}
:token-requirement-text-spacing {:margin-vertical 8}
:token-requirement-list-spacing {:padding-vertical (- 8 token-tag-vertical-spacing)}
:token-row {:flex-direction :row
:flex-wrap :wrap
:align-items :center}
:token-row-container {:flex-direction :row
:align-items :center
:margin-horizontal (- token-tag-horizontal-spacing)}
:token-row-container-no-shift {:margin-left 0}
:token-row-or-text {:margin-right 3}
:token-tag-spacing {:margin-horizontal token-tag-horizontal-spacing
:margin-vertical token-tag-vertical-spacing}
:divider {:height 1
:margin-horizontal -20
:margin-top (- 12 token-tag-vertical-spacing)
:margin-bottom 8}
:membership-request-denied {:margin-top 13}
:enter-button {:margin-top 16}
:info-text {:margin-top 12
:text-align :center
:padding-horizontal 20}})
(defn multiple-token-requirements?
[token-requirement-lists]
(defn multiple-token-requirements? [token-requirement-lists]
(when (vector? (first token-requirement-lists))
(> (count token-requirement-lists) 1)))
(defn is-token-requirement-met?
[token-requirement-list]
(defn is-token-requirement-met? [token-requirement-list]
(and (seq token-requirement-list)
(every?
(fn [token]
(get token :is-sufficient?))
token-requirement-list)))
(defn are-multiple-token-requirements-met?
[token-requirement-lists]
(defn are-multiple-token-requirements-met? [token-requirement-lists]
(if (multiple-token-requirements? token-requirement-lists)
(some is-token-requirement-met? token-requirement-lists)
(is-token-requirement-met? token-requirement-lists)))
(defn token-requirement-list-row
[tokens community-color]
[rn/view
{:style (merge
(get styles :token-row)
(get styles :token-requirement-list-spacing))}
(defn token-requirement-list-row [tokens community-color]
[rn/view {:style (merge
(get styles :token-row)
(get styles :token-requirement-list-spacing))}
(map-indexed (fn [token-index token]
(let [{:keys [token-img-src token amount is-sufficient? is-purchasable?]} token]
^{:key token-index}
[rn/view {:style (get styles :token-tag-spacing)}
[token-tag/token-tag
{:token token
:value amount
:size 24
:border-color community-color
:is-required is-sufficient?
:is-purchasable is-purchasable?
:token-img-src token-img-src}]]))
[token-tag/token-tag {:token token
:value amount
:size 24
:border-color community-color
:is-required is-sufficient?
:is-purchasable is-purchasable?
:token-img-src token-img-src}]]))
tokens)])
(defn token-requirement-list
[props community-color]
(defn token-requirement-list [props community-color]
(let [{:keys [gate token-requirements-changed? required-tokens-lost?]} props
[gate-type token-requirement-lists] gate
multiple-token-requirements? (multiple-token-requirements? token-requirement-lists)
@@ -97,17 +89,15 @@
you-must-hold-label (if (= gate-type :join)
(cond
token-requirements-changed? :t/you-must-now-hold
required-tokens-lost? :t/you-must-always-hold
:else :t/you-must-hold)
required-tokens-lost? :t/you-must-always-hold
:else :t/you-must-hold)
:t/you-must-hold)
message-label (cond
(= gate-type :join)
(cond
token-requirements-changed? :t/community-join-requirements-changed
required-tokens-lost? :t/community-join-requirements-tokens-lost
:else (if is-sufficient?
:t/community-join-requirements-met
:t/community-join-requirements-not-met))
required-tokens-lost? :t/community-join-requirements-tokens-lost
:else (if is-sufficient? :t/community-join-requirements-met :t/community-join-requirements-not-met))
(= gate-type :read)
(if is-sufficient?
:t/community-channel-read-requirements-met
@@ -118,14 +108,12 @@
:t/community-channel-write-requirements-not-met))]
[rn/view
[rn/view {:style (get styles :token-requirement-text-spacing)}
[text/text
{:weight :medium
:number-of-lines 1}
[text/text {:weight :medium
:number-of-lines 1}
(i18n/label
message-label)]
[text/text
{:size :paragraph-2
:number-of-lines 1}
[text/text {:size :paragraph-2
:number-of-lines 1}
(i18n/label
you-must-hold-label)]]
@@ -133,26 +121,22 @@
(map-indexed
(fn [token-requirement-index tokens]
^{:key token-requirement-index}
[rn/view
{:style (merge
(get styles :token-row-container)
(when-not (= token-requirement-index 0)
(get styles :token-row-container-no-shift)))}
[rn/view {:style (merge
(get styles :token-row-container)
(when-not (= token-requirement-index 0)
(get styles :token-row-container-no-shift)))}
(when-not (= token-requirement-index 0)
[text/text
{:style (get styles :token-row-or-text)
:size :paragraph-2} "or"])
[text/text {:style (get styles :token-row-or-text)
:size :paragraph-2} "or"])
[token-requirement-list-row tokens community-color]])
token-requirement-lists)
[rn/view {:style (get styles :token-row-container)}
[token-requirement-list-row token-requirement-lists community-color]])]))
(defn is-community-locked?
[community]
(defn is-community-locked? [community]
(not (are-multiple-token-requirements-met? (get-in community [:gates :join]))))
(defn is-channel-locked?
[channel]
(defn is-channel-locked? [channel]
(not (are-multiple-token-requirements-met?
(or (get-in channel [:gates :read])
(get-in channel [:gates :write])))))
@@ -190,98 +174,82 @@
membership-request-denied?
token-requirements-changed?
required-tokens-lost?
gates]}
(if (= type :community) community channel)
gates]} (if (= type :community) community channel)
locked? (if
(= type :community)
(= type :community)
(is-community-locked? community)
(is-channel-locked? channel))]
[rn/view
{:style (merge (get styles :container)
{:background-color (colors/theme-colors colors/white colors/neutral-90)})}
[rn/view
{:style (merge
(get styles :header-container)
(if
(= type :community)
(get styles :header-spacing-community)
(get styles :header-spacing-channel)))}
[rn/view {:style (merge (get styles :container) {:background-color (colors/theme-colors colors/white colors/neutral-90)})}
[rn/view {:style (merge
(get styles :header-container)
(if
(= type :community)
(get styles :header-spacing-community)
(get styles :header-spacing-channel)))}
[rn/view {:style (get styles :header-avatar)}
(if (= type :community)
[fast-image/fast-image
{:source community-avatar-img-src
:style (get styles :header-community-avatar-image)}]
[fast-image/fast-image {:source community-avatar-img-src
:style (get styles :header-community-avatar-image)}]
[channel-avatar/channel-avatar
{:big? true
:locked? locked?
:emoji emoji
:emoji-background-color emoji-background-color}])]
[channel-avatar/channel-avatar {:big? true
:locked? locked?
:emoji emoji
:emoji-background-color emoji-background-color}])]
[rn/view {:style (get styles :header-title-container)}
[text/text
{:weight :semi-bold
:number-of-lines 1
:size :heading-1
:style (get styles :header-text)} (if (= type :community) name (str "# " name))]
[text/text {:weight :semi-bold
:number-of-lines 1
:size :heading-1
:style (get styles :header-text)} (if (= type :community) name (str "# " name))]
(when (= type :community)
[icon/icon
(if locked?
:main-icons2/locked
:main-icons2/unlocked)
[icon/icon (if locked?
:main-icons2/locked
:main-icons2/unlocked)
{:container-style (get styles :header-title-lock)
:color (colors/theme-colors
colors/neutral-50
colors/neutral-40)}])]
[button/button
{:type :outline
:size 32
:icon true
:style (get styles :header-info-button)} :main-icons2/info]]
[button/button {:type :outline
:size 32
:icon true
:style (get styles :header-info-button)} :main-icons2/info]]
(map-indexed (fn [gate-index gate]
^{:key gate-index}
[:<>
(when-not (= gate-index 0)
[rn/view
{:style (merge
(get styles :divider)
{:background-color (colors/theme-colors
colors/neutral-10
colors/neutral-80)})}])
[token-requirement-list
{:gate gate
:token-requirements-changed? token-requirements-changed?
:required-tokens-lost? required-tokens-lost?} community-color]])
[rn/view {:style (merge
(get styles :divider)
{:background-color (colors/theme-colors
colors/neutral-10
colors/neutral-80)})}])
[token-requirement-list {:gate gate :token-requirements-changed? token-requirements-changed? :required-tokens-lost? required-tokens-lost?} community-color]])
gates)
(when (= type :channel)
(if membership-request-denied?
[information-box/information-box
{:type :error
:icon :main-icons2/untrustworthy
:no-icon-color? true
:style (get styles :membership-request-denied)}
[information-box/information-box {:type :error
:icon :main-icons2/untrustworthy
:no-icon-color? true
:style (get styles :membership-request-denied)}
(i18n/label
:t/membership-request-denied)]
[:<>
[button/button
{:type :community
:community-color community-color
:community-text-color community-text-color
:style (get styles :enter-button)
:disabled locked?
:on-press on-enter-channel}
(str "# "
(i18n/label
:t/enter-channel))]
[button/button {:type :community
:community-color community-color
:community-text-color community-text-color
:style (get styles :enter-button)
:disabled locked?
:on-press on-enter-channel}
(str "# " (i18n/label
:t/enter-channel))]
[text/text
{:size :paragraph-2
{:size :paragraph-2
:style (merge
(get styles :info-text)
{:color (colors/theme-colors
@@ -7,28 +7,28 @@
([]
(render-counter {} nil))
([opts value]
(rtl/render (reagent/as-element [counter/counter opts value]))))
(rtl/render (reagent/as-element [counter/counter opts value]))))
(js/global.test "default render of counter component"
(fn []
(render-counter)
(-> (js/expect (rtl/screen.getByTestId "counter-component"))
(.toBeTruthy))))
(fn []
(render-counter)
(-> (js/expect (rtl/screen.getByTestId "counter-component"))
(.toBeTruthy))))
(js/global.test "renders counter with a string value"
(fn []
(render-counter {} "1")
(-> (js/expect (rtl/screen.getByText "1"))
(.toBeTruthy))))
(fn []
(render-counter {} "1")
(-> (js/expect (rtl/screen.getByText "1"))
(.toBeTruthy))))
(js/global.test "renders counter with an integer value"
(fn []
(render-counter {} 1)
(-> (js/expect (rtl/screen.getByText "1"))
(.toBeTruthy))))
(fn []
(render-counter {} 1)
(-> (js/expect (rtl/screen.getByText "1"))
(.toBeTruthy))))
(js/global.test "renders counter with value 99+ when the value is greater than 99"
(fn []
(render-counter {} "100")
(-> (js/expect (rtl/screen.getByText "99+"))
(.toBeTruthy))))
(fn []
(render-counter {} "100")
(-> (js/expect (rtl/screen.getByText "99+"))
(.toBeTruthy))))
+37 -40
View File
@@ -1,21 +1,20 @@
(ns quo2.components.counter.counter
(:require [quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]))
(:require [quo2.theme :as theme]
[react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))
(def themes
{:light {:default colors/primary-50
:secondary colors/neutral-80-opa-5
:grey colors/neutral-10
:outline colors/neutral-20}
:dark {:default colors/primary-60
:secondary colors/white-opa-5
:grey colors/neutral-70
:outline colors/neutral-70}})
{:light {:default colors/primary-50
:secondary colors/neutral-80-opa-5
:grey colors/neutral-10
:outline colors/neutral-20}
:dark {:default colors/primary-60
:secondary colors/white-opa-5
:grey colors/neutral-70
:outline colors/neutral-70}})
(defn get-color
[key]
(defn get-color [key]
(get-in themes [(theme/get-theme) key]))
(defn counter
@@ -36,32 +35,30 @@
"99+"
(str value))
width (case (count label)
1 16
2 20
1 16
2 20
28)]
[rn/view
{:test-ID :counter-component
:accessible true
:accessibility-label accessibility-label
:style (cond-> (merge
{:align-items :center
:justify-content :center
:border-radius 6
:width width
:height 16}
style)
(= type :outline)
(merge {:border-width 1
:border-color (get-color type)})
[rn/view {:test-ID :counter-component
:accessible true
:accessibility-label accessibility-label
:style (cond-> (merge
{:align-items :center
:justify-content :center
:border-radius 6
:width width
:height 16}
style)
(= type :outline)
(merge {:border-width 1
:border-color (get-color type)})
(not= type :outline)
(assoc :background-color
(or override-bg-color
(get-color type)))
(not= type :outline)
(assoc :background-color
(or override-bg-color
(get-color type)))
(> value 99)
(assoc :padding-left 0.5))}
[text/text
{:weight :medium
:size :label
:style {:color text-color}} label]]))
(> value 99)
(assoc :padding-left 0.5))}
[text/text {:weight :medium
:size :label
:style {:color text-color}} label]]))
@@ -1,45 +0,0 @@
(ns quo2.components.dividers.--tests--.divider-label-component-spec
(:require ["@testing-library/react-native" :as rtl]
[quo2.components.dividers.divider-label :as divider-label]
[reagent.core :as reagent]))
(defn render-divider-label
([]
(render-divider-label {}))
([opts]
(rtl/render (reagent/as-element [divider-label/divider-label opts]))))
(js/global.test "default render of divider-label component"
(fn []
(render-divider-label)
(-> (js/expect (rtl/screen.getByLabelText "divider-label"))
(.toBeTruthy))))
(js/global.test "render divider-label component with a label"
(fn []
(render-divider-label {:label :hello})
(-> (js/expect (rtl/screen.getByText "hello"))
(.toBeTruthy))))
(js/global.test "render divider-label component with a counter-value"
(fn []
(render-divider-label {:label :hello
:counter-value "1"})
(-> (js/expect (rtl/screen.getByText "1"))
(.toBeTruthy))))
(js/global.test "divider-label chevron icon renders to the left when set"
(fn []
(render-divider-label {:label :hello
:counter-value "1"
:chevron-position :left})
(-> (js/expect (rtl/screen.getByTestId "divider-label-icon-left"))
(.toBeTruthy))))
(js/global.test "divider-label chevron icon renders to the right when set"
(fn []
(render-divider-label {:label :hello
:counter-value "1"
:chevron-position :right})
(-> (js/expect (rtl/screen.getByTestId "divider-label-icon-right"))
(.toBeTruthy))))
+13 -16
View File
@@ -1,21 +1,18 @@
(ns quo2.components.dividers.date
(:require [quo2.components.markdown.text :as text]
(:require [react-native.core :as rn]
[quo2.components.separator :as separator]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))
(defn date
[value]
[rn/view
{:margin-vertical 8
:padding-right 20
:padding-left 60}
[text/text
{:weight :medium
:accessibility-label :divider-date-text
:size :label
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)
:text-transform :capitalize
:margin-bottom 4}}
(defn date [value]
[rn/view {:margin-vertical 16
:padding-right 8
:padding-left 62}
[text/text {:weight :medium
:accessibility-label :divider-date-text
:size :label
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)
:text-transform :capitalize
:margin-bottom 4}}
value]
[separator/separator]])
+34 -45
View File
@@ -1,8 +1,8 @@
(ns quo2.components.dividers.divider-label
(:require [quo2.components.icon :as icons]
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as markdown.text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
[quo2.components.icon :as icons]))
(def chevron-icon-container-width 20)
@@ -15,56 +15,45 @@
increase-padding-top? -> boolean
blur? -> boolean"
[{:keys [label chevron-position counter-value increase-padding-top? blur?]}]
(let [dark? (colors/dark?)
border-and-counter-bg-color (if dark?
(if blur? colors/white-opa-5 colors/neutral-70)
colors/neutral-10)
padding-top (if increase-padding-top? 16 8)
text-and-icon-color (if dark? colors/neutral-40 colors/neutral-50)
counter-text-color (if dark? colors/white colors/neutral-100)]
[rn/view
{:accessible true
:accessibility-label :divider-label
:style {:border-top-width 1
:border-top-color border-and-counter-bg-color
:padding-top padding-top
:padding-horizontal 16
:align-items :center
:flex-direction :row}}
(let [dark? (colors/dark?)
border-and-counter-bg-color (if dark? (if blur? colors/white-opa-5 colors/neutral-70) colors/neutral-10)
padding-top (if increase-padding-top? 16 8)
text-and-icon-color (if dark? colors/neutral-40 colors/neutral-50)
counter-text-color (if dark? colors/white colors/neutral-100)]
[rn/view {:style {:border-top-width 1
:border-top-color border-and-counter-bg-color
:padding-top padding-top
:padding-horizontal 16
:align-items :center
:flex-direction :row}}
(when (= chevron-position :left)
[rn/view
{:test-ID :divider-label-icon-left
:style {:margin-right 4}}
[rn/view {:style {:margin-right 4}}
[icons/icon
:main-icons/chevron-down
{:color text-and-icon-color
:width chevron-icon-container-width
:height chevron-icon-container-height}]])
[markdown.text/text
{:size :paragraph-2
:weight :medium
:style {:color text-and-icon-color
:flex 1}}
[markdown.text/text {:size :paragraph-2
:weight :medium
:style {:color text-and-icon-color
:flex 1}}
label]
(when (= chevron-position :right)
[rn/view {:test-ID :divider-label-icon-right}
[icons/icon
:main-icons/chevron-down
{:color text-and-icon-color
:size chevron-icon-container-width}]])
[icons/icon
:main-icons/chevron-down
{:color text-and-icon-color
:size chevron-icon-container-width}])
(when (pos? counter-value)
[rn/view
{:style {:border-radius 6
:height 16
:width (case (count counter-value)
1 16
2 20
28)
:background-color border-and-counter-bg-color
:align-items :center
:justify-content :center}}
[markdown.text/text
{:size :label
:weight :medium
:style {:color counter-text-color}}
[rn/view {:style {:border-radius 6
:height 16
:width (case (count counter-value)
1 16
2 20
28)
:background-color border-and-counter-bg-color
:align-items :center
:justify-content :center}}
[markdown.text/text {:size :label
:weight :medium
:style {:color counter-text-color}}
counter-value]])]))
+7 -10
View File
@@ -1,7 +1,7 @@
(ns quo2.components.dividers.new-messages
(:require [quo2.components.markdown.text :as text]
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.linear-gradient :as linear-gradient]))
(defn new-messages
@@ -9,14 +9,11 @@
[{:keys [label color] :or {color :primary}}]
(let [bg-color (colors/custom-color-by-theme color 50 60 5 5)
text-color (colors/custom-color-by-theme color 50 60)]
[linear-gradient/linear-gradient
{:colors [bg-color "rgba(0,0,0,0)"]
:start {:x 0 :y 0}
:end {:x 0 :y 1}}
[rn/view
{:style {:padding-left 60
:padding-vertical 12
:padding-right 24}}
[linear-gradient/linear-gradient {:colors [bg-color "rgba(0,0,0,0)"]
:start {:x 0 :y 0} :end {:x 0 :y 1}}
[rn/view {:style {:padding-left 60
:padding-vertical 12
:padding-right 24}}
[text/text
{:size :paragraph-2
:weight :medium
@@ -5,49 +5,59 @@
(defn render-action-drawer
([options]
(rtl/render (reagent/as-element [action-drawer/action-drawer options]))))
(rtl/render (reagent/as-element [action-drawer/action-drawer options]))))
(js/global.test "action-drawer renders with elements label displaying"
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"}]])
(-> (js/expect (rtl/screen.getByText "a sample label"))
(.toBeTruthy))))
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"}]])
(-> (js/expect (rtl/screen.getByText "a sample label"))
(.toBeTruthy))))
(js/global.test "action-drawer renders with elements sub-label displaying"
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:sub-label "a sample sub label"}]])
(-> (js/expect (rtl/screen.getByText "a sample sub label"))
(.toBeTruthy))))
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:sub-label "a sample sub label"}]])
(-> (js/expect (rtl/screen.getByText "a sample sub label"))
(.toBeTruthy))))
(js/global.test "action-drawer on click action works on element"
(let [event (js/jest.fn)]
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:on-press event}]])
(rtl/fireEvent.press (rtl/screen.getByText "a sample label"))
(-> (js/expect event)
(.toHaveBeenCalled)))))
(let [event (js/jest.fn)]
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:on-press event}]])
(rtl/fireEvent.press (rtl/screen.getByText "a sample label"))
(-> (js/expect event)
(.toHaveBeenCalled)))))
(js/global.test "action-drawer renders two icons when set"
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:right-icon :i/friend
:accessibility-label :first-element}]])
(-> (js/expect (rtl/screen.getByLabelText "right-icon-for-action"))
(.toBeTruthy))
(-> (js/expect (rtl/screen.queryByLabelText "left-icon-for-action"))
(.toBeTruthy))))
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:right-icon :i/friend
:accessibility-label :first-element}]])
(-> (js/expect (rtl/screen.getByLabelText "right-icon-for-action"))
(.toBeTruthy))
(-> (js/expect (rtl/screen.queryByLabelText "left-icon-for-action"))
(.toBeTruthy))))
(js/global.test "action-drawer does not render a divider when the add-divider? prop is false"
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:add-divider? false
:accessibility-label :first-element}]])
(-> (js/expect (rtl/screen.getAllByLabelText "divider"))
(.not)
(.toBeTruthy))))
(js/global.test "action-drawer renders a divider when the add-divider? prop is true"
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:add-divider? true
:accessibility-label :first-element}]])
(-> (js/expect (rtl/screen.getAllByLabelText "divider"))
(.toBeTruthy))))
(fn []
(render-action-drawer [[{:icon :i/friend
:label "a sample label"
:add-divider? true
:accessibility-label :first-element}]])
(-> (js/expect (rtl/screen.getAllByLabelText "divider"))
(.toBeTruthy))))
+47 -57
View File
@@ -1,62 +1,54 @@
(ns quo2.components.drawers.action-drawers
(:require [quo2.components.icon :as icon]
(:require [react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
[quo2.components.icon :as icon]
[quo2.foundations.colors :as colors]))
(defn- get-icon-color
[danger?]
(defn- get-icon-color [danger?]
(if danger?
colors/danger-50
(colors/theme-colors colors/neutral-50 colors/neutral-40)))
(def divider
[rn/view
{:style {:border-top-width 1
:border-top-color (colors/theme-colors
colors/neutral-10
colors/neutral-90)
:margin-top 8
:margin-bottom 7
:align-items :center
:flex-direction :row}
:accessible true
:accessibility-label :divider}])
[rn/view {:style {:border-top-width 1
:border-top-color (colors/theme-colors
colors/neutral-10 colors/neutral-90)
:margin-top 8
:margin-bottom 7
:align-items :center
:flex-direction :row}
:accessible true
:accessibility-label :divider}])
(defn action
[{:keys [icon
label
sub-label
right-icon
danger?
on-press
add-divider?
accessibility-label]
:as action-props}]
(defn action [{:keys [icon
label
sub-label
right-icon
danger?
on-press
add-divider?
accessibility-label] :as action-props}]
(when action-props
[:<> {:key label}
(when add-divider? divider)
[rn/touchable-highlight
{:accessibility-label accessibility-label
:style {:border-radius 12
:height (if sub-label 58 50)
:margin-horizontal 8}
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90)
:on-press on-press}
[rn/view
{:style
{:height (if sub-label 58 50)
:margin-horizontal 12
:flex-direction :row}}
[rn/view
{:accessibility-label :left-icon-for-action
:accessible true
:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:margin-right 12
:width 20}}
[rn/touchable-highlight {:accessibility-label accessibility-label
:style {:border-radius 12
:height (if sub-label 58 50)
:margin-horizontal 8}
:underlay-color (colors/theme-colors colors/neutral-5 colors/neutral-90)
:on-press on-press}
[rn/view {:style
{:height (if sub-label 58 50)
:margin-horizontal 12
:flex-direction :row}}
[rn/view {:accessibility-label :left-icon-for-action
:accessible true
:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:margin-right 12
:width 20}}
[icon/icon icon
{:color (get-icon-color danger?)
:size 20}]]
@@ -78,20 +70,18 @@
(colors/theme-colors colors/neutral-50 colors/neutral-40)}}
sub-label])]
(when right-icon
[rn/view
{:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:width 20}
:accessible true
:accessibility-label :right-icon-for-action}
[rn/view {:style
{:height 20
:margin-top :auto
:margin-bottom :auto
:width 20}
:accessible true
:accessibility-label :right-icon-for-action}
[icon/icon right-icon
{:color (get-icon-color danger?)
:size 20}]])]]]))
(defn action-drawer
[sections]
(defn action-drawer [sections]
[:<>
(doall
(for [actions sections]
+92 -109
View File
@@ -1,108 +1,97 @@
(ns quo2.components.dropdowns.dropdown
(:require [quo2.components.icon :as icons]
(:require [react-native.core :as rn]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]))
(defn apply-anim
[dd-height val]
(defn apply-anim [dd-height val]
(reanimated/animate-shared-value-with-delay dd-height
val
300
:easing1
0))
(def sizes
{:big {:icon-size 20
:font {:font-size :paragraph-1}
:height 40
:padding {:padding-with-icon {:padding-vertical 9
:padding-horizontal 12}
:padding-with-no-icon {:padding-vertical 9
:padding-left 12
:padding-right 8}}}
:medium {:icon-size 20
:font {:font-size :paragraph-1}
:height 32
:padding {:padding-with-icon {:padding-vertical 5
:padding-horizontal 8}
:padding-with-no-icon {:padding-vertical 5
:padding-left 12
:padding-right 8}}}
:small {:icon-size 15
:font {:font-size :paragraph-2}
:height 24
:padding {:padding-with-icon {:padding-vertical 3
:padding-horizontal 6}
:padding-with-no-icon {:padding-vertical 3
:padding-horizontal 6}}}})
(def sizes {:big {:icon-size 20
:font {:font-size :paragraph-1}
:height 40
:padding {:padding-with-icon {:padding-vertical 9
:padding-horizontal 12}
:padding-with-no-icon {:padding-vertical 9
:padding-left 12
:padding-right 8}}}
:medium {:icon-size 20
:font {:font-size :paragraph-1}
:height 32
:padding {:padding-with-icon {:padding-vertical 5
:padding-horizontal 8}
:padding-with-no-icon {:padding-vertical 5
:padding-left 12
:padding-right 8}}}
:small {:icon-size 15
:font {:font-size :paragraph-2}
:height 24
:padding {:padding-with-icon {:padding-vertical 3
:padding-horizontal 6}
:padding-with-no-icon {:padding-vertical 3
:padding-horizontal 6}}}})
(defn color-by-10
[color]
(colors/alpha color 0.6))
(defn dropdown-comp
[{:keys [icon open? dd-height size disabled? dd-color use-border? border-color]}]
(defn dropdown-comp [{:keys [icon open? dd-height size disabled? dd-color use-border? border-color]}]
(let [dark? (colors/dark?)
{:keys [width height width-with-icon padding font icon-size]} (size sizes)
{:keys [padding-with-icon padding-with-no-icon]} padding
font-size (:font-size font)
spacing (case size
:big 4
:big 4
:medium 2
:small 2)]
[rn/touchable-opacity
(cond->
{:on-press (fn []
(if (swap! open? not)
(apply-anim dd-height 120)
(apply-anim dd-height 0)))
:style (cond->
(merge
(if icon
padding-with-icon
padding-with-no-icon)
{:width (if icon
width-with-icon
width)
:height height
:border-radius (case size
:big 12
:medium 10
:small 8)
:flex-direction :row
:align-items :center
:background-color (if @open?
dd-color
(color-by-10 dd-color))})
use-border? (assoc :border-width 1
:border-color (if @open?
border-color
(color-by-10 border-color))))}
disabled? (assoc-in [:style :opacity] 0.3)
disabled? (assoc :disabled true))
:small 2)]
[rn/touchable-opacity (cond-> {:on-press (fn []
(if (swap! open? not)
(apply-anim dd-height 120)
(apply-anim dd-height 0)))
:style (cond-> (merge
(if icon
padding-with-icon
padding-with-no-icon)
{:width (if icon
width-with-icon
width)
:height height
:border-radius (case size
:big 12
:medium 10
:small 8)
:flex-direction :row
:align-items :center
:background-color (if @open?
dd-color
(color-by-10 dd-color))})
use-border? (assoc :border-width 1
:border-color (if @open? border-color (color-by-10 border-color))))}
disabled? (assoc-in [:style :opacity] 0.3)
disabled? (assoc :disabled true))
(when icon
[icons/icon icon
{:no-color true
:size 20
:container-style {:margin-right spacing
:margin-top 1
:width icon-size
:height icon-size}}])
[text/text
{:size font-size
:weight :medium
:font :font-medium
:color :main} "Dropdown"]
[icons/icon
(if @open?
(if dark?
:main-icons/pullup-dark
:main-icons/pullup)
(if dark?
:main-icons/dropdown-dark
:main-icons/dropdown))
[icons/icon icon {:no-color true
:size 20
:container-style {:margin-right spacing
:margin-top 1
:width icon-size
:height icon-size}}])
[text/text {:size font-size
:weight :medium
:font :font-medium
:color :main} "Dropdown"]
[icons/icon (if @open?
(if dark?
:main-icons/pullup-dark
:main-icons/pullup)
(if dark?
:main-icons/dropdown-dark
:main-icons/dropdown))
{:size 20
:no-color true
:container-style {:width (+ icon-size 3)
@@ -116,10 +105,9 @@
(defn items-comp
[{:keys [items on-select]}]
(let [items-count (count items)]
[rn/scroll-view
{:style {:height "100%"}
:horizontal false
:nestedScrollEnabled true}
[rn/scroll-view {:style {:height "100%"}
:horizontal false
:nestedScrollEnabled true}
(doall
(map-indexed (fn [index item]
[rn/touchable-opacity
@@ -133,32 +121,27 @@
colors/white)
:text-align :center}
:on-press #(on-select item)}
[text/text {:style {:text-align :center}} item]])
items))]))
[text/text {:style {:text-align :center}} item]]) items))]))
(defn dropdown
[{:keys [items icon text default-item on-select size disabled? border-color use-border? dd-color]}]
(defn dropdown [{:keys [items icon text default-item on-select size disabled? border-color use-border? dd-color]}]
[:f>
(fn []
(let [open? (reagent/atom false)
dd-height (reanimated/use-shared-value 0)]
[rn/view {:style {:flex-grow 1}}
[dropdown-comp
{:items items
:icon icon
:disabled? disabled?
:size size
:dd-color dd-color
:text text
:border-color (colors/custom-color-by-theme border-color 50 60)
:use-border? use-border?
:default-item default-item
:open? open?
:dd-height dd-height}]
[reanimated/view
{:style (reanimated/apply-animations-to-style
{:height dd-height}
{:height dd-height})}
[items-comp
{:items items
:on-select on-select}]]]))])
[dropdown-comp {:items items
:icon icon
:disabled? disabled?
:size size
:dd-color dd-color
:text text
:border-color (colors/custom-color-by-theme border-color 50 60)
:use-border? use-border?
:default-item default-item
:open? open?
:dd-height dd-height}]
[reanimated/view {:style (reanimated/apply-animations-to-style
{:height dd-height}
{:height dd-height})}
[items-comp {:items items
:on-select on-select}]]]))])
+90 -120
View File
@@ -1,16 +1,15 @@
(ns quo2.components.header
(:require [oops.core :refer [oget]]
[react-native.reanimated :as reanimated]
[quo2.components.buttons.button :as button]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[reagent.core :as reagent]))
(def header-height 56)
(defn header-wrapper-style
[{:keys [height border-bottom background]}]
(defn header-wrapper-style [{:keys [height border-bottom background]}]
(merge
{:background-color (colors/theme-colors
colors/neutral-5
@@ -24,37 +23,32 @@
colors/neutral-5
colors/neutral-95)})))
(def absolute-fill
{:position :absolute
:top 0
:bottom 0
:left 0
:right 0})
(def absolute-fill {:position :absolute
:top 0
:bottom 0
:left 0
:right 0})
(def content
{:flex 1
:flex-direction :row
:align-items :center
:justify-content :center})
(def content {:flex 1
:flex-direction :row
:align-items :center
:justify-content :center})
(def left
{:position :absolute
:left 0
:top 0
:bottom 0
:justify-content :center
:align-items :flex-start})
(def left {:position :absolute
:left 0
:top 0
:bottom 0
:justify-content :center
:align-items :flex-start})
(def right
{:position :absolute
:right 0
:top 0
:bottom 0
:justify-content :center
:align-items :flex-end})
(def right {:position :absolute
:right 0
:top 0
:bottom 0
:justify-content :center
:align-items :flex-end})
(defn title-style
[{:keys [left right]} title-align]
(defn title-style [{:keys [left right]} title-align]
(merge
absolute-fill
(case title-align
@@ -75,66 +69,57 @@
(def header-action-placeholder
{:width 16})
(def element
{:align-items :center
:justify-content :center
:flex 1})
(def element {:align-items :center
:justify-content :center
:flex 1})
(defn header-action
[{:keys [icon label on-press disabled accessibility-label]}]
[button/button
(merge {:on-press on-press
:disabled disabled}
(cond
icon {:type :icon
:theme :icon}
label {:type :secondary})
(when accessibility-label
{:accessibility-label accessibility-label}))
(defn header-action [{:keys [icon label on-press disabled accessibility-label]}]
[button/button (merge {:on-press on-press
:disabled disabled}
(cond
icon {:type :icon
:theme :icon}
label {:type :secondary})
(when accessibility-label
{:accessibility-label accessibility-label}))
(cond
icon icon
label label)])
(defn header-actions
[{:keys [accessories component]}]
(defn header-actions [{:keys [accessories component]}]
[rn/view {:style element}
(cond
(seq accessories)
(into [rn/view {:style header-actions-style}]
(map header-action accessories))
component component
component component
:else
[rn/view {:style header-action-placeholder}])])
(defn header-title
[{:keys [title subtitle component title-align]}]
(defn header-title [{:keys [title subtitle component title-align]}]
[:<>
(cond
component component
component component
(and title subtitle)
[:<>
[text/text
{:weight :medium
:number-of-lines 1}
[text/text {:weight :medium
:number-of-lines 1}
title]
[text/text
{:weight :regular
:color :secondary
:number-of-lines 1}
[text/text {:weight :regular
:color :secondary
:number-of-lines 1}
subtitle]]
title [text/text
{:weight :bold
:number-of-lines 0
:align title-align
:size :large}
title])])
title [text/text {:weight :bold
:number-of-lines 0
:align title-align
:size :large}
title])])
(defn header
[{:keys [left-width right-width]}]
(defn header [{:keys [left-width right-width]}]
(let [layout (reagent/atom {:left {:width (or left-width 8)
:height header-height}
:right {:width (or right-width 8)
@@ -146,61 +131,46 @@
(let [width (oget evt "nativeEvent" "layout" "width")
height (oget evt "nativeEvent" "layout" "height")]
(when get-layout
(get-layout el
{:width width
:height height}))
(swap! layout assoc
el
{:width width
:height height}))))]
(fn
[{:keys [left-accessories left-component border-bottom
right-accessories right-component insets get-layout
title subtitle title-component style title-align
background]
:or {title-align :center
border-bottom false}}]
(get-layout el {:width width
:height height}))
(swap! layout assoc el {:width width
:height height}))))]
(fn [{:keys [left-accessories left-component border-bottom
right-accessories right-component insets get-layout
title subtitle title-component style title-align
background]
:or {title-align :center
border-bottom false}}]
(let [status-bar-height (get insets :top 0)
height (+ header-height status-bar-height)]
[reanimated/view
{:style (header-wrapper-style {:height height
:background background
:border-bottom border-bottom})}
[rn/view
{:pointer-events :box-none
:height status-bar-height}]
[rn/view
{:style (merge {:height header-height}
style)
:pointer-events :box-none}
[rn/view
{:style absolute-fill
:pointer-events :box-none}
[rn/view
{:style content
:pointer-events :box-none}
[rn/view
{:style left
:on-layout (handle-layout :left get-layout)
:pointer-events :box-none}
[header-actions
{:accessories left-accessories
:component left-component}]]
[reanimated/view {:style (header-wrapper-style {:height height
:background background
:border-bottom border-bottom})}
[rn/view {:pointer-events :box-none
:height status-bar-height}]
[rn/view {:style (merge {:height header-height}
style)
:pointer-events :box-none}
[rn/view {:style absolute-fill
:pointer-events :box-none}
[rn/view {:style content
:pointer-events :box-none}
[rn/view {:style left
:on-layout (handle-layout :left get-layout)
:pointer-events :box-none}
[header-actions {:accessories left-accessories
:component left-component}]]
[rn/view
{:style (title-style @layout title-align)
:on-layout (handle-layout :title get-layout)
:pointer-events :box-none}
[header-title
{:title title
:subtitle subtitle
:title-align title-align
:component title-component}]]
[rn/view {:style (title-style @layout title-align)
:on-layout (handle-layout :title get-layout)
:pointer-events :box-none}
[header-title {:title title
:subtitle subtitle
:title-align title-align
:component title-component}]]
[rn/view
{:style right
:on-layout (handle-layout :right get-layout)
:pointer-events :box-none}
[header-actions
{:accessories right-accessories
:component right-component}]]]]]]))))
[rn/view {:style right
:on-layout (handle-layout :right get-layout)
:pointer-events :box-none}
[header-actions {:accessories right-accessories
:component right-component}]]]]]]))))
+8 -8
View File
@@ -1,15 +1,15 @@
(ns quo2.components.icon
(:require [clojure.string :as string]
[quo2.components.icons.icons :as icons]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(:require
[clojure.string :as string]
[react-native.core :as rn]
[quo2.components.icons.icons :as icons]
[quo2.foundations.colors :as colors]))
(defn memo-icon-fn
([icon-name] (memo-icon-fn icon-name nil))
([icon-name
{:keys [color container-style size
accessibility-label no-color]
:or {accessibility-label :icon}}]
([icon-name {:keys [color container-style size
accessibility-label no-color]
:or {accessibility-label :icon}}]
(let [size (or size 20)]
^{:key icon-name}
[rn/image
+6 -12
View File
@@ -4,14 +4,12 @@
(def icon-path "./resources/images/icons2/")
(defn combine-path
[path el]
(defn combine-path [path el]
(if (System/getenv "COMPONENT_TEST")
(str "." path el "@2x.png")
(str "." path el ".png")))
(defn require-icon
[size path]
(defn require-icon [size path]
(fn [el]
(let [s (combine-path path el)
k (-> el
@@ -21,25 +19,21 @@
(str size))]
[k `(js/require ~s)])))
(defn get-files
[path]
(defn get-files [path]
(->> (io/file path)
file-seq
(filter #(string/ends-with? % "png"))
(map #(first (string/split (.getName %) #"@")))
distinct))
(defn get-icons
[size]
(defn get-icons [size]
(let [path (str icon-path size "x" size "/")]
(into {} (map (require-icon size path) (get-files path)))))
(defmacro resolve-icons
[]
(defmacro resolve-icons []
(merge
(get-icons 12)
(get-icons 16)
(get-icons 20)
(get-icons 24)
(get-icons 32)
(get-icons 120)))
(get-icons 32)))
+1 -2
View File
@@ -4,8 +4,7 @@
(def icons (icons/resolve-icons))
(defn icon-source
[icon]
(defn icon-source [icon]
(if-let [icon (get icons (name icon))]
icon
(do
+24 -28
View File
@@ -1,20 +1,19 @@
(ns quo2.components.info.info-message
(:require [quo2.components.icon :as quo2.icons]
(:require [quo2.theme :as theme]
[react-native.core :as rn]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]))
[quo2.components.icon :as quo2.icons]))
(def themes
{:light {:default colors/neutral-40
:success colors/success-50
:error colors/danger-50}
:dark {:default colors/neutral-60
:success colors/success-60
:error colors/danger-60}})
{:light {:default colors/neutral-40
:success colors/success-50
:error colors/danger-50}
:dark {:default colors/neutral-60
:success colors/success-60
:error colors/danger-60}})
(defn get-color
[key]
(defn get-color [key]
(get-in themes [(theme/get-theme) key]))
(defn info-message
@@ -27,20 +26,17 @@
:icon-color colors/white ;; icon color override
:no-icon-color? false ;; disable tint color for icon"
[{:keys [type size icon text-color icon-color no-icon-color?]} message]
(let [weight (if (= size :default) :regular :medium)
size (if (= size :default) :paragraph-2 :label)
text-color (or text-color (get-color type))
icon-color (or icon-color text-color)]
[rn/view
{:style {:flex-direction :row
:flex 1}}
[quo2.icons/icon icon
{:color icon-color
:no-color no-icon-color?
:size 12
:container-style {:margin-top 3}}]
[text/text
{:size size
:weight weight
:style {:color text-color
:margin-horizontal 8}} message]]))
(let [weight (if (= size :default) :regular :medium)
size (if (= size :default) :paragraph-2 :label)
text-color (or text-color (get-color type))
icon-color (or icon-color text-color)]
[rn/view {:style {:flex-direction :row
:flex 1}}
[quo2.icons/icon icon {:color icon-color
:no-color no-icon-color?
:size 12
:container-style {:margin-top 3}}]
[text/text {:size size
:weight weight
:style {:color text-color
:margin-horizontal 8}} message]]))
+58 -67
View File
@@ -1,46 +1,44 @@
(ns quo2.components.info.information-box
(:require [clojure.string :as string]
[quo2.components.buttons.button :as quo2.button]
[quo2.components.icon :as quo2.icons]
[quo2.components.info.info-message :as info-message]
(:require [quo2.theme :as theme]
[react-native.core :as rn]
[clojure.string :as string]
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]))
[quo2.components.icon :as quo2.icons]
[quo2.components.buttons.button :as quo2.button]
[quo2.components.info.info-message :as info-message]))
(def themes
{:light {:default {:bg colors/white
:border colors/neutral-20
:icon colors/neutral-50
:text colors/neutral-100}
:informative {:bg colors/primary-50-opa-5
:border colors/primary-50-opa-10
:icon colors/primary-50
:text colors/neutral-100}
:error {:bg colors/danger-50-opa-5
:border colors/danger-50-opa-10
:icon colors/danger-50
:text colors/danger-50}
{:light {:default {:bg colors/white
:border colors/neutral-20
:icon colors/neutral-50
:text colors/neutral-100}
:informative {:bg colors/primary-50-opa-5
:border colors/primary-50-opa-10
:icon colors/primary-50
:text colors/neutral-100}
:error {:bg colors/danger-50-opa-5
:border colors/danger-50-opa-10
:icon colors/danger-50
:text colors/danger-50}
:close-button colors/neutral-100}
:dark {:default {:bg colors/neutral-90
:border colors/neutral-70
:icon colors/neutral-40
:text colors/white}
:informative {:bg colors/primary-50-opa-5
:border colors/primary-50-opa-10
:icon colors/white
:text colors/white}
:error {:bg colors/danger-50-opa-5
:border colors/danger-50-opa-10
:icon colors/danger-50
:text colors/danger-50}
:dark {:default {:bg colors/neutral-90
:border colors/neutral-70
:icon colors/neutral-40
:text colors/white}
:informative {:bg colors/primary-50-opa-5
:border colors/primary-50-opa-10
:icon colors/white
:text colors/white}
:error {:bg colors/danger-50-opa-5
:border colors/danger-50-opa-10
:icon colors/danger-50
:text colors/danger-50}
:close-button colors/white}})
(defn get-color
[key]
(defn get-color [key]
(get-in themes [(theme/get-theme) key]))
(defn get-color-by-type
[type key]
(defn get-color-by-type [type key]
(get-in themes [(theme/get-theme) type key]))
(defn information-box
@@ -56,47 +54,40 @@
:button-label \"PressMe\" ;; add action button with label
:on-button-press action ;; (required for information box with button-label)
:on-close on-close ;; (optional on-close call)"
[{:keys [type closable? closed? id icon style button-label on-button-press on-close no-icon-color?]}
message]
[{:keys [type closable? closed? id icon style button-label on-button-press on-close no-icon-color?]} message]
(let [background-color (get-color-by-type type :bg)
border-color (get-color-by-type type :border)
icon-color (get-color-by-type type :icon)
text-color (get-color-by-type type :text)
include-button? (not (string/blank? button-label))]
(when-not closed?
[rn/view
{:accessibility-label (or id :information-box)
:style (merge {:background-color background-color
:border-color border-color
:border-width 1
:border-radius 12
:padding-top (if include-button? 10 11)
:padding-bottom (if include-button? 12 11)
:padding-horizontal 16}
style)}
[rn/view
{:style {:flex-direction :row
:align-self :flex-start}}
[info-message/info-message
{:size :default
:icon icon
:text-color text-color
:icon-color icon-color
:no-icon-color? no-icon-color?} message]
[rn/view {:accessibility-label (or id :information-box)
:style (merge {:background-color background-color
:border-color border-color
:border-width 1
:border-radius 12
:padding-top (if include-button? 10 11)
:padding-bottom (if include-button? 12 11)
:padding-horizontal 16} style)}
[rn/view {:style {:flex-direction :row
:align-self :flex-start}}
[info-message/info-message {:size :default
:icon icon
:text-color text-color
:icon-color icon-color
:no-icon-color? no-icon-color?} message]
(when closable?
[rn/touchable-opacity
{:on-press on-close
:accessibility-label (str (or id "information-box") "-close-button")}
[quo2.icons/icon :i/close
{:size 12
:color (get-color :close-button)
:container-style {:margin-top 4
:margin-left 8}}]])]
[quo2.icons/icon :i/close {:size 12
:color (get-color :close-button)
:container-style {:margin-top 4
:margin-left 8}}]])]
(when include-button?
[quo2.button/button
{:type :primary
:size 24
:on-press on-button-press
:style {:margin-left 20
:margin-top 8
:align-self :flex-start}} button-label])])))
[quo2.button/button {:type :primary
:size 24
:on-press on-button-press
:style {:margin-left 20
:margin-top 8
:align-self :flex-start}} button-label])])))

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