Compare commits

..
Author SHA1 Message Date
Omar Basem 702b8b5d9f test 2023-03-10 10:26:11 +04:00
Omar Basem 2fd9e80650 reabstract reanimated
test

updates

rebase

rebase

rebase

https://github.com/status-im/status-go/compare/551715f4...550de3bf

rebase

https://github.com/status-im/status-go/compare/551715f4...550de3bf

fix: image actions drawer

lint

fix: image action drawer

refactor

lint

lint

updates

updates

updates

updates

updates

feat: zoomable image

updates

updates

feat: zoomable image

lint

re-order arguments

updates

refactor

refactor

refactor

refactor

update event name

refactor

rebase

feat: landscape

feat: landscape

udpates

updates

updates

updates

updates

updates

updates

updates

updates

updates

rebase

updates

feat: landscape mode

updates

updates

updates

updates

updates

updates

updates

feat: landscape mode

feat: landscape mode

add todo

fix tests

fix tests

refactor

refactor

refactor

refactor

refactor

refactor

refactor

refactor

rollback

lint

rollback

refactor

rebase

refactor

fix arg

feat: more lightbox gestures

updates

updates

updates

updates

updates

updates

updates

updates

updates

lint

refactor

remove extra line

updates

updates

comment
2023-03-07 10:30:04 +04:00
andrey 998b40ec4f podfile.lock 2023-03-06 15:57:26 +01:00
Jamie CapraniandChurikova Tetiana 2861190e5b New intro screen (#15127)
* feat: add new intro page

* e2e: new intro fix

---------

Co-authored-by: Churikova Tetiana <tatiana@status.im>
2023-03-06 06:42:30 -08:00
Churikova Tetiana 404ae82cfe e2e: fix deep link profile test
Signed-off-by: Parvesh Monu <parvesh.dhullmonu@gmail.com>
2023-03-06 17:26:29 +05:30
Parvesh Monu 9ffefe74bb fix navigation to user profile 2023-03-06 17:16:49 +05:30
Vitaliy Vlasov 9959d537f3 Emoji hash is now in settings
Signed-off-by: Vitaliy Vlasov <siphiuel@protonmail.com>
2023-03-06 13:27:15 +02:00
John Ngeiandjo-mut 7a9018ae11 replaced mocked community-tags and images with real data
Co-authored-by: jo-mut <jo_ngei@Johns-MacBook-Air.local>
2023-03-06 13:57:58 +03:00
Parvesh Monu 8454ce2e11 Onboarding add background screen (#15231) 2023-03-06 16:07:07 +05:30
Parvesh Monu f314806b83 Improve profile card (#15264) 2023-03-06 14:24:34 +05:30
Omar Basem 16ffc23509 Lightbox improvements (#15243)
* feat: lightbox polishing and improvements
2023-03-06 08:35:36 +04:00
jakub 80a75c5232 nix: patch all Gradle configs of nodejs deps
Before we were patching only `build.gradle`, which is not the only type
of Gradle config file. If we do not cover them all we can encounter
errors about missing package because they will continue using remote
repositories instead of `mavenLocal()`, to which pass Nix store path.

We also need to cover `gradlePluginPortal()` to provide plugins.

This is also necessary for the React Native upgrade:
https://github.com/status-im/status-mobile/pull/15203

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-03-04 13:01:26 +01:00
jakub 20a0cc01f6 nix: refactor Gradle deps to be more generic
Refactoring the derivation that fetches all the POMs, JARs,
and AARs in order to make it more generic and easier to extend.
The main change is adding `files` key in `deps.json` which contains
a dict of all the files reletad to given package.

This way we can more easily include other files that might be available
for download, like AARs with ASC suffix, or `nodeps` JARs.

This is also necessary for the React Native upgrade:
https://github.com/status-im/status-mobile/pull/15203

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-03-04 12:41:29 +01:00
Ulises Manuel Cárdenas ff3ba6c0f0 Add new text input component 2023-03-03 15:03:38 -06:00
Mohamed Javid 3483bb1107 [Fix] Community Context for Mention or Replies Notification in Activity Center (#15234)
* [Fix] Community Context for Mention or Replies Notification in Activity Center

https://github.com/status-im/status-go/compare/ebc1fc33...71f778ec

* [Update] Status Go Version
2023-03-03 22:57:32 +05:30
Icaro Motta 1f1ab30a4e Use new RPC endpoints to fetch and count unread notifications (#15245)
There are endpoint changes in the status-go PR #3237
https://github.com/status-im/status-go/pull/3237) that will cause breakage in
the Mobile & Desktop clients. The Desktop team has already implemented the
changes and is waiting for Mobile to do the same.

The new endpoints are generally better, more ergonomic to use. There's also a
new endpoint to allow fetching multiple unread counters for all types of
notifications so we can finally remove the dreadful workaround in mobile calling
`status-go` 10+ times in a row.

- Fixes https://github.com/status-im/status-mobile/issues/15119
- Fixes https://github.com/status-im/status-mobile/issues/15229
2023-03-03 12:43:41 -03:00
Icaro Motta 064204256e Fix Activity Center popover not opening (#15239)
Fixes #15230 - The popover state in the app db must be discarded before trying to
open the Activity Center. This workaround is used in other parts of the app too.
It's ugly, but the only quick fix I found.

It's plenty obvious the popover component and all its surrounding logic should
be revisited in the future.
2023-03-03 10:34:55 -03:00
Omar Basem 8923408972 Landscape Mode (#15175)
* feat: landscape mode
2023-03-03 16:33:28 +04:00
Icaro Motta 52b87bab3e Redesign and simplify Activity Center app db (#15216)
Fixes #15215. Redesign the app db state for the Activity Center. Please, see the issue being fixed for more details about the problems being solved.

TL;DR: There's a lot less state to keep track and reconcile and way less nesting in the app db because we're only managing the state of the *current tab*, not all tabs.

Additionally:

- [x] While updating unit tests, found a bug on the sorting notifications' logic.
- [x] While updating unit tests, found a bug where notifications that are not of the type *contact request* were being removed from the app db.
- [x] Fixed regression where pressing on a notification would not open the chat.
- [x] Hardened unit tests.

#### Platforms

- Android
- iOS

##### Non-functional

- Less memory consumption.
- Faster reconciliation of notification coming from signals and from synchronous responses from RPC calls.
2023-03-03 09:17:35 -03:00
John Ngei 25d44b11f1 Fix: chat header height 2023-03-02 21:57:19 +03:00
Brian Sztamfater 9333692830 feat: remove wallet connect 1.0 (#15010) 2023-03-02 17:55:03 +01:00
jakub 4fe8b81bf6 ios: fix xcode using system Node.js version
As discovered in:
https://github.com/status-im/status-mobile/pull/15225

The attempt to fix this in:
https://github.com/status-im/status-mobile/pull/15180

But it doesn't appear to work, so instead I'm allowing an override of
`NODE_BINARY` variable and spetting it when defining the Nix shell.

The key things here are:

* Xcode injects its own paths into `PATH` which breaks Nix env.
* Combining Nix shells with `inputsFrom` does not inherit all vars.

It's important to set these variables in `shellHook` and not elsewhere.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-03-02 17:32:52 +01:00
Omar Basem 4dfd3af7f5 Album Reactions (#15208)
* feat: album actions
2023-03-02 20:11:17 +04:00
Icaro Motta 11b6702939 Fix (#15232) 2023-03-02 11:02:01 -03:00
Jamie Caprani 39c39915a7 chore: separate resources for old and new ui (#15108) 2023-03-02 14:25:01 +01:00
Ibrahem Khalil 01c058fecc [15127] Make reply and pinned banner react on edit (#15189) 2023-03-02 15:03:30 +02:00
Roman Volosovskyi 8f75874868 [#15042] Fix inconsistent contact request state on syncing 2023-03-02 12:45:37 +01:00
Icaro Motta 041622d98b Make popover delay configurable (#15225)
Make the popover delay in milliseconds configurable.

To open the Activity Center, 30ms delay seems to be more than enough. It's a quick fix because the current 250ms to open the AC gives the wrong impression to users (and confuses even us developers) who think the AC has a performance issue to open.

See issue https://github.com/status-im/status-mobile/pull/15222 for the full discussion.
2023-03-02 08:41:18 -03:00
yqrashawn 4190dfd26b feat: support community that all members allowed to pin (#15197) 2023-03-02 18:43:21 +08:00
flexsurferandChurikova Tetiana f731f75fca move profile tab (#15224)
* move profile tab

* e2e: new profile tab

* e2e: fix leftovers

* e2e: last

---------

Co-authored-by: Churikova Tetiana <tatiana@status.im>
2023-03-02 10:55:45 +01:00
Parvesh Monu 78682b823b fix root id of :init-root-fx (#15228) 2023-03-02 12:10:41 +05:30
Ulises Manuel Cárdenas 7d9709ee67 Improve chat Avatar (#15036) 2023-03-01 14:54:40 -06:00
Ajay Sivan aec1b5fafa quo2 strength divider component (#15177) 2023-03-01 15:47:02 +00:00
Jamie Caprani 5c67216b31 feat: add bottom sheet to see community rules (#15130) 2023-03-01 06:09:46 -08:00
Siddarth Kumar 0c9a195ca9 Improve QR code Handler mobile side PR (#15168)
* point to the relevant branch on status-go

https://github.com/status-im/status-go/compare/a9bfed21...6839f458

* update commit-sha1

* bump version to latest status-go
2023-03-01 18:15:49 +05:30
Churikova Tetiana 06192e7a24 e2e: outgoing CR + new UI 2023-03-01 12:36:49 +01:00
Omar Basem 4a6e42c6f9 fix: activity center closing animation (#15222)
fix: activity center closing animation
2023-03-01 15:12:16 +04:00
yqrashawn 2ce4a820d7 fix: deleted-by user name style (#15218) 2023-03-01 15:03:27 +08:00
jakub b72f0d4702 nix: fix Gradle nodeps JAR symlink filename
Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-02-28 17:57:39 +01:00
frank b75e1304d8 added param deviceType (#15136) 2023-02-28 21:43:10 +08:00
Yevheniia Berdnyk c2782a26f7 paste from clipboard fix 2023-02-28 15:07:06 +02:00
flexsurfer fa03e91080 Sanitize quo2 namespace (#15207) 2023-02-28 13:59:09 +01:00
Omar Basem f9dda56310 fix: image dimensions on Android (#15211) 2023-02-28 16:20:00 +04:00
jakub 51276237f2 nix: include nodeps JARs in Gradle deps (#15212)
* nix: update gradle dependencies

Signed-off-by: Jakub Sokołowski <jakub@status.im>

* nix: include nodeps JARs in Gradle deps

Signed-off-by: Jakub Sokołowski <jakub@status.im>

* nix: include nodeps JAR for semver4j 0.16.4

Can cause failures like in some cases:
```
A problem occurred configuring project ':react-native-hole-view'.
> Could not resolve all files for configuration ':react-native-hole-view:classpath'.
   > Could not find semver4j-0.16.4-nodeps.jar (com.github.gundy:semver4j:0.16.4).
     Searched in the following locations:
         file:/nix/store/3n2pxsqa2izlx8c23s6jgqai0bqaklm1-status-mobile-maven-deps/com/github/gundy/semver4j/0.16.4/semver4j-0.16.4-nodeps.jar
```

Signed-off-by: Jakub Sokołowski <jakub@status.im>

---------

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-02-28 17:13:44 +05:30
flexsurfer c667d05929 bump status-go v0.133.2 (#15200) 2023-02-27 17:44:36 +01:00
Churikova Tetiana e1bcc8fec4 e2e: fix pinned messages 2023-02-27 16:39:39 +01:00
Jamie Caprani f84c2ec9f5 chore: add old edit option to communities options (#15131) 2023-02-27 05:49:37 -08:00
flexsurfer 80f063d0dd [#15056] Can't see display/ens/name when mentioning in community (#15085) 2023-02-27 12:51:53 +01:00
Parvesh Monu 69c3a72357 Navigation code cleanup (#15196) 2023-02-27 15:40:11 +05:30
yqrashawn c28b34ac08 fix: toast style on android (#15194) 2023-02-27 17:25:21 +08:00
309 changed files with 13728 additions and 13814 deletions
+8 -2
View File
@@ -228,6 +228,8 @@ PODS:
- React-Core
- react-native-netinfo (4.7.0):
- React
- react-native-orientation-locker (1.5.0):
- React-Core
- react-native-randombytes (3.6.1):
- React-Core
- react-native-safe-area-context (2.0.0):
@@ -238,7 +240,7 @@ PODS:
- React
- react-native-status (1.0.0):
- React
- react-native-status-keycard (2.5.38):
- react-native-status-keycard (2.5.39):
- Keycard
- React
- react-native-webview (11.16.0):
@@ -433,6 +435,7 @@ DEPENDENCIES:
- react-native-lottie-splash-screen (from `../node_modules/react-native-lottie-splash-screen`)
- react-native-mail (from `../node_modules/react-native-mail`)
- "react-native-netinfo (from `../node_modules/@react-native-community/netinfo`)"
- react-native-orientation-locker (from `../node_modules/react-native-orientation-locker`)
- react-native-randombytes (from `../node_modules/react-native-randombytes`)
- react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`)
- react-native-shake (from `../node_modules/react-native-shake`)
@@ -545,6 +548,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-mail"
react-native-netinfo:
:path: "../node_modules/@react-native-community/netinfo"
react-native-orientation-locker:
:path: "../node_modules/react-native-orientation-locker"
react-native-randombytes:
:path: "../node_modules/react-native-randombytes"
react-native-safe-area-context:
@@ -666,12 +671,13 @@ SPEC CHECKSUMS:
react-native-lottie-splash-screen: 068688c15dd478301fda00f8d87d7fb7d5b9a93e
react-native-mail: 8fdcd3aef007c33a6877a18eb4cf7447a1d4ce4a
react-native-netinfo: ddaca8bbb9e6e914b1a23787ccb879bc642931c9
react-native-orientation-locker: 851f6510d8046ea2f14aa169b1e01fcd309a94ba
react-native-randombytes: 421f1c7d48c0af8dbcd471b0324393ebf8fe7846
react-native-safe-area-context: 60f654e00b6cc416573f6d5dbfce3839958eb57a
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
react-native-status: 21f75d492fd311dc111303da38a7a2b23a8a8466
react-native-status-keycard: f60ca57d789aad6875c64ece81ab06ef0609e0d3
react-native-status-keycard: f1c1227b2d5984c10fb44db68e4bfd2937f31e98
react-native-webview: 28a8636d97ee641f2ee8f20492d7a6c269c1d703
React-RCTActionSheet: e911b99f0d6fa7711ffc2f62d236b12a32771835
React-RCTAnimation: ad8b853170a059faf31d6add34f67d22391bbe01
+2 -2
View File
@@ -526,7 +526,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/usr/bin/env sh";
shellScript = "set -o errexit\nexport NODE_BINARY=\"node\"\nexport NODE_ARGS=\" --openssl-legacy-provider --max-old-space-size=16384 \"\n\nbash -x ../node_modules/react-native/scripts/react-native-xcode.sh > ./react-native-xcode.log 2>&1";
shellScript = "set -o errexit\nexport NODE_BINARY=\"${NODE_BINARY:-node}\"\nexport NODE_ARGS=\" --openssl-legacy-provider --max-old-space-size=16384 \"\n\nbash -x ../node_modules/react-native/scripts/react-native-xcode.sh > ./react-native-xcode.log 2>&1";
};
0F876BD5356F61BF142A01A0 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
@@ -584,7 +584,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = "/usr/bin/env sh";
shellScript = "set -o errexit\nexport NODE_BINARY=\"node\"\nexport NODE_ARGS=\" --openssl-legacy-provider --max-old-space-size=16384 \"\n\nbash -x ../node_modules/react-native/scripts/react-native-xcode.sh > ./react-native-xcode.log 2>&1";
shellScript = "set -o errexit\nexport NODE_BINARY=\"${NODE_BINARY:-node}\"\nexport NODE_ARGS=\" --openssl-legacy-provider --max-old-space-size=16384 \"\n\nbash -x ../node_modules/react-native/scripts/react-native-xcode.sh > ./react-native-xcode.log 2>&1";
};
3AAD2AD724A3A60E0075D594 /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
@@ -1139,11 +1139,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
executeRunnableStatusGoMethod(() -> Statusgo.generateAlias(seed), callback);
}
@ReactMethod
public void emojiHash(final String publicKey, final Callback callback) throws JSONException {
executeRunnableStatusGoMethod(() -> Statusgo.emojiHash(publicKey), callback);
}
@ReactMethod(isBlockingSynchronousMethod = true)
public String identicon(final String seed) {
return Statusgo.identicon(seed);
@@ -866,12 +866,6 @@ RCT_EXPORT_METHOD(generateAliasAsync:(NSString *)publicKey
callback(@[result]);
}
RCT_EXPORT_METHOD(emojiHash:(NSString *)publicKey
callback:(RCTResponseSenderBlock)callback) {
NSString *result = StatusgoEmojiHash(publicKey);
callback(@[result]);
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(identicon:(NSString *)publicKey) {
return StatusgoIdenticon(publicKey);
}
+10 -4
View File
@@ -24,6 +24,7 @@ Generating scripts:
- `get_deps.sh` - Calls Gradle to get all the dependencies of sub-projects.
- `gradle_parser.awk` - An AWK script that parses above Gradle output.
- `url2json.sh` - Converts the list of URLs into a format consumable by Nix.
- `add_package.sh` - Allows for adding a missing package manually.
Finally we have the Nix derivation in `default.nix` which produces a derivation with all of the Gradle project dependencies:
```
@@ -66,9 +67,14 @@ You can use the `add_package.sh` script to add missing Gradle dependencies:
> make shell TARGET=gradle
Configuring Nix shell for target 'gradle'...
[nix-shell:~/status-mobile]$ nix/deps/gradle/add_package.sh com.android.tools.build:gradle:3.4.0
[nix-shell:~/work/status-mobile]$ nix/deps/gradle/add_package.sh com.android.tools.build:gradle:3.5.3
Changes made:
nix/deps/gradle/deps.urls | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
Regenerating Nix files...
Found 548 direct dependencies...
Successfully added: com.android.tools.build:gradle:3.4.0
Successfully added: com.android.tools.build:gradle:3.5.3
NOTICE: Running 'make nix-update-gradle' in a new shell is recommended.
```
This may take a bit longer than normal `make nix-update-gradle` but should add the missing package.
Keep in mind that the changes made by this script do not affect the already spawned shell.
+12 -5
View File
@@ -1,6 +1,10 @@
#!/usr/bin/env bash
set -Eeu
# This script allows for adding a package by providing a Maven full name.
# Such name consists of 3 sections separated by the colon character.
# Example: com.android.tools.build:gradle:3.5.3
set -Eeuo pipefail
if [[ $# -ne 1 ]]; then
echo "Usage: add_package.sh <package>" >&2
@@ -18,12 +22,15 @@ source "${GIT_ROOT}/scripts/colors.sh"
echo "${1}" | go-maven-resolver >> nix/deps/gradle/deps.urls
# Remove duplicates and sort.
sort -uo nix/deps/gradle/deps.urls nix/deps/gradle/deps.urls
sort -uVo nix/deps/gradle/deps.urls nix/deps/gradle/deps.urls
echo -e "${GRN}Changes made:${RST}" >&2
git diff --stat nix/deps/gradle/deps.urls
echo
# Re-generate dependencies JSON.
"${GIT_ROOT}/nix/deps/gradle/generate.sh" gen_deps_json
# Re-generate dependencies list.
"${GIT_ROOT}/nix/deps/gradle/generate.sh" gen_deps_list
echo -e "${GRN}Successfully added:${RST} ${BLD}${1}${RST}" >&2
echo
echo -e "${YLW}NOTICE:${RST} Running '${BLD}make nix-update-gradle${RST}' in a new shell is recommended."
+25 -49
View File
@@ -1,68 +1,44 @@
{ stdenv, lib, pkgs, fetchurl, writeShellScriptBin }:
let
inherit (lib)
removeSuffix optionalString splitString concatMapStrings
attrByPath attrValues last makeOverridable importJSON;
inherit (lib) concatStrings concatMapStrings mapAttrsToList makeOverridable;
inherit (pkgs) aapt2;
deps = importJSON ./deps.json;
# some .jar files have an `-aot` suffix that doesn't work for .pom files
getPOM = jarUrl: "${removeSuffix "-aot" jarUrl}.pom";
deps = lib.importJSON ./deps.json;
script = writeShellScriptBin "create-local-maven-repo" (''
mkdir -p $out
cd $out
'' +
(concatMapStrings (dep:
let
url = "${dep.host}/${dep.path}";
pom = {
sha1 = attrByPath [ "pom" "sha1" ] "" dep;
sha256 = attrByPath [ "pom" "sha256" ] "" dep;
};
pom-download = optionalString (pom.sha256 != "") (
fetchurl { url = getPOM url; inherit (pom) sha256; }
);
jar = {
sha1 = attrByPath [ "jar" "sha1" ] "" dep;
sha256 = attrByPath [ "jar" "sha256" ] "" dep;
};
jar-download = optionalString (jar.sha256 != "") (
fetchurl { url = "${url}.${dep.type}"; inherit (jar) sha256; }
);
fileName = last (splitString "/" dep.path);
directory = removeSuffix fileName dep.path;
in
''
mkdir -p ${directory}
${optionalString (pom-download != "") ''
ln -s "${pom-download}" "${getPOM dep.path}"
''}
${optionalString (pom.sha1 != "") ''
echo "${pom.sha1}" > "${getPOM dep.path}.sha1"
''}
${optionalString (jar-download != "") ''
ln -s "${jar-download}" "${dep.path}.${dep.type}"
''}
${optionalString (jar.sha1 != "") ''
echo "${jar.sha1}" > "${dep.path}.${dep.type}.sha1"
''}
# For each dependency in deps.json.
(concatMapStrings (dep: concatStrings
# And for each file in the 'files' dict of given dependency.
(mapAttrsToList (filename: hashes: let
# Download given file(POM, JAR, nodeps JAR, or AAR).
download = fetchurl {
url = "${dep.repo}/${dep.path}/${filename}";
inherit (hashes) sha256;
};
# And symlink it in the correct folder along with SHA1.
in ''
mkdir -p "${dep.path}"
ln -s "${download}" "${dep.path}/${filename}"
echo "${hashes.sha1}" > "${dep.path}/${filename}.sha1"
'')
deps));
dep.files)
) deps)
);
in makeOverridable stdenv.mkDerivation {
name = "status-mobile-maven-deps";
buildInputs = [ aapt2 ];
buildInputs = [ pkgs.aapt2 ];
phases = [ "buildPhase" "patchPhase" ];
buildPhase = "${script}/bin/create-local-maven-repo";
# Patched AAPT2
# Replace AAPT2 package only with our patched version from overlay.
patchPhase = ''
aapt2_dir=$out/com/android/tools/build/aapt2/${aapt2.version}
aapt2_dir=$out/com/android/tools/build/aapt2/${pkgs.aapt2.version}
mkdir -p $aapt2_dir
ln -sf ${aapt2}/* $aapt2_dir
ln -sf ${pkgs.aapt2}/* $aapt2_dir
'';
}
+8381 -7556
View File
File diff suppressed because it is too large Load Diff
+10 -9
View File
@@ -503,12 +503,12 @@ https://repo.maven.apache.org/maven2/com/sun/istack/istack-commons-runtime/4.1.1
https://repo.maven.apache.org/maven2/com/sun/istack/istack-commons/2.21/istack-commons-2.21.pom
https://repo.maven.apache.org/maven2/com/sun/istack/istack-commons/4.1.1/istack-commons-4.1.1.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/2.2.11/jaxb-bom-ext-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/4.0.1/jaxb-bom-ext-4.0.1.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/jaxb-bom-ext/4.0.2/jaxb-bom-ext-4.0.2.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/2.2.11/jaxb-parent-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/4.0.1/jaxb-parent-4.0.1.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-parent/4.0.2/jaxb-parent-4.0.2.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-runtime-parent/2.2.11/jaxb-runtime-parent-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/2.2.11/jaxb-txw-parent-2.2.11.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/4.0.1/jaxb-txw-parent-4.0.1.pom
https://repo.maven.apache.org/maven2/com/sun/xml/bind/mvn/jaxb-txw-parent/4.0.2/jaxb-txw-parent-4.0.2.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/FastInfoset/1.2.13/FastInfoset-1.2.13.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/FastInfoset/2.1.0/FastInfoset-2.1.0.pom
https://repo.maven.apache.org/maven2/com/sun/xml/fastinfoset/fastinfoset-project/1.2.13/fastinfoset-project-1.2.13.pom
@@ -561,9 +561,9 @@ https://repo.maven.apache.org/maven2/org/antlr/ST4/4.0.8/ST4-4.0.8.pom
https://repo.maven.apache.org/maven2/org/antlr/ST4/4.3.4/ST4-4.3.4.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.5.2-1/antlr4-master-4.5.2-1.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.5.3/antlr4-master-4.5.3.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.11.1/antlr4-master-4.11.1.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-master/4.12.0/antlr4-master-4.12.0.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.5.2-1/antlr4-runtime-4.5.2-1.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.11.1/antlr4-runtime-4.11.1.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4-runtime/4.12.0/antlr4-runtime-4.12.0.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr4/4.5.3/antlr4-4.5.3.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr-master/3.3/antlr-master-3.3.pom
https://repo.maven.apache.org/maven2/org/antlr/antlr-master/3.5.2/antlr-master-3.5.2.pom
@@ -636,7 +636,7 @@ https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.56/bcprov
https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.60/bcprov-jdk15on-1.60.pom
https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.70/bcprov-jdk15on-1.70.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.5.2/checker-qual-2.5.2.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.29.0/checker-qual-3.29.0.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.32.0/checker-qual-3.32.0.pom
https://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4/codehaus-parent-4.pom
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy-all/2.4.15/groovy-all-2.4.15.pom
https://repo.maven.apache.org/maven2/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.pom
@@ -656,16 +656,17 @@ https://repo.maven.apache.org/maven2/org/easymock/easymock/5.1.0/easymock-5.1.0.
https://repo.maven.apache.org/maven2/org/eclipse/angus/angus-activation-project/2.0.0/angus-activation-project-2.0.0.pom
https://repo.maven.apache.org/maven2/org/eclipse/angus/angus-activation/2.0.0/angus-activation-2.0.0.pom
https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.7/project-1.0.7.pom
https://repo.maven.apache.org/maven2/org/eclipse/ee4j/project/1.0.8/project-1.0.8.pom
https://repo.maven.apache.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.4.2/ecj-4.4.2.pom
https://repo.maven.apache.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.4/ecj-4.4.pom
https://repo.maven.apache.org/maven2/org/eclipse/jdt/core/compiler/ecj/4.6.1/ecj-4.6.1.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/2.2.11/jaxb-bom-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/4.0.1/jaxb-bom-4.0.1.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-bom/4.0.2/jaxb-bom-4.0.2.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/2.2.11/jaxb-core-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/4.0.1/jaxb-core-4.0.1.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-core/4.0.2/jaxb-core-4.0.2.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/jaxb-runtime/2.2.11/jaxb-runtime-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/2.2.11/txw2-2.2.11.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/4.0.1/txw2-4.0.1.pom
https://repo.maven.apache.org/maven2/org/glassfish/jaxb/txw2/4.0.2/txw2-4.0.2.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/1.3/hamcrest-core-1.3.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/2.2/hamcrest-core-2.2.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-parent/1.3/hamcrest-parent-1.3.pom
+22 -22
View File
@@ -1,18 +1,16 @@
#!/usr/bin/env bash
# Stop on any failures, including in pipes
set -e
set -o pipefail
# This script takes care of generating/updating the maven-sources.nix file
# representing the offline Maven repo containing the dependencies
# required to build the project
set -Eeo pipefail
if [[ -z "${IN_NIX_SHELL}" ]]; then
echo "Remember to call 'make shell'!"
exit 1
fi
# This script takes care of generating/updating the maven-sources.nix file
# representing the offline Maven repo containing the dependencies
# required to build the project
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
source "${GIT_ROOT}/scripts/colors.sh"
@@ -27,41 +25,43 @@ ulimit -n 16384
# Generate list of Gradle sub-projects.
function gen_proj_list() {
${CUR_DIR}/get_projects.sh | sort -u -o ${PROJ_LIST}
echo -e "Found ${GRN}$(wc -l < ${PROJ_LIST})${RST} sub-projects..."
"${CUR_DIR}/get_projects.sh" | sort -u -o "${PROJ_LIST}"
echo -e "Found ${GRN}$(wc -l < "${PROJ_LIST}")${RST} sub-projects..."
}
# Check each sub-project in parallel, the ":" is for local deps.
function gen_deps_list() {
PROJECTS=$(cat ${PROJ_LIST})
${CUR_DIR}/get_deps.sh ":" ${PROJECTS[@]} | sort -uV -o ${DEPS_LIST}
echo -e "${CLR}Found ${GRN}$(wc -l < ${DEPS_LIST})${RST} direct dependencies..."
PROJECTS=$(cat "${PROJ_LIST}")
# WARNING: The ${PROJECTS[@]} needs to remain unquoted to expand correctly.
# shellcheck disable=SC2068
"${CUR_DIR}/get_deps.sh" ":" ${PROJECTS[@]} | sort -uV -o "${DEPS_LIST}"
echo -e "${CLR}Found ${GRN}$(wc -l < "${DEPS_LIST}")${RST} direct dependencies..."
}
# Find download URLs for each dependency.
function gen_deps_urls() {
cat ${DEPS_LIST} | go-maven-resolver | sort -uV -o ${DEPS_URLS}
echo -e "${CLR}Found ${GRN}$(wc -l < ${DEPS_URLS})${RST} dependency URLs..."
go-maven-resolver < "${DEPS_LIST}" | sort -uV -o "${DEPS_URLS}"
echo -e "${CLR}Found ${GRN}$(wc -l < "${DEPS_URLS}")${RST} dependency URLs..."
}
# Generate the JSON that Nix will consume.
function gen_deps_json() {
# Open the Nix attribute set.
echo -n "[" > ${DEPS_JSON}
echo -n "[" > "${DEPS_JSON}"
# Format URLs into a Nix consumable file.
URLS=$(cat ${DEPS_URLS})
URLS=$(cat "${DEPS_URLS}")
# Avoid rate limiting by using 4 of the available threads.
parallel --will-cite --keep-order --jobs 4 \
"${CUR_DIR}/url2json.sh" \
::: ${URLS} \
>> ${DEPS_JSON}
::: "${URLS}" \
>> "${DEPS_JSON}"
# Drop tailing comma on last object, stupid JSON
sed -i '$ s/},/}/' ${DEPS_JSON}
sed -i '$ s/},/}/' "${DEPS_JSON}"
# Close the Nix attribute set
echo "]" >> ${DEPS_JSON}
echo "]" >> "${DEPS_JSON}"
}
# ------------------------------------------------------------------------------
@@ -74,7 +74,7 @@ cd "${GIT_ROOT}/android"
./gradlew --stop >/dev/null
# A way to run a specific stage of generation
if [[ -n "${1}" ]] && type ${1} > /dev/null; then
if [[ -n "${1}" ]] && type "${1}" > /dev/null; then
${1}; exit 0
elif [[ -n "${1}" ]]; then
echo "No such function: ${1}"; exit 1
@@ -86,6 +86,6 @@ gen_deps_list
gen_deps_urls
gen_deps_json
REL_DEPS_JSON=$(realpath --relative-to=${PWD} ${DEPS_JSON})
REL_DEPS_JSON=$(realpath --relative-to="${PWD}" "${DEPS_JSON}")
echo -e "${CLR}Generated Nix deps file: ${REL_DEPS_JSON#../}"
echo -e "${GRN}Done${RST}"
+14 -12
View File
@@ -1,12 +1,19 @@
#!/usr/bin/env bash
set -Eeu
# This script generates a list of dependencies for the main project and its
# sub-projects defined using Gradle config files. It parses Gradle output of
# 'dependencies' and 'buildEnvironment` tasks using AWK.
set -Eeuo pipefail
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
# Gradle needs to be run in 'android' subfolder
# Gradle needs to be run in 'android' subfolder.
cd "${GIT_ROOT}/android"
AWK_SCRIPT="${GIT_ROOT}/nix/deps/gradle/gradle_parser.awk"
# Show Gradle log in case of failure.
GRADLE_LOG_FILE='/tmp/gradle.log'
function show_gradle_log() { cat "${GRADLE_LOG_FILE}" >&2; }
trap show_gradle_log ERR
# Run the gradle command for a project:
# - ':buildEnvironment' to get build tools
@@ -20,16 +27,11 @@ for i in "${!DEPS[@]}"; do
NORMAL_DEPS[${i}]="${DEPS[${i}]}:dependencies"
done
# And clean up the output by:
# - keep only lines that start with \--- or +---
# - drop lines that end with (*) or (n) but don't start with (+)
# - drop lines that refer to a project
# - drop entries starting with `status-im:` like `status-go`
# - drop entries that aren't just the name of the dependency
# - extract the package name and version, ignoring version range indications,
# such as in `com.google.android.gms:play-services-ads:[15.0.1,16.0.0) -> 15.0.1`
# And clean up the output using AWK script.
AWK_SCRIPT="${GIT_ROOT}/nix/deps/gradle/gradle_parser.awk"
./gradlew --no-daemon --console plain \
"${BUILD_DEPS[@]}" \
"${NORMAL_DEPS[@]}" \
| awk -f ${AWK_SCRIPT}
| tee "${GRADLE_LOG_FILE}" \
| awk -f "${AWK_SCRIPT}"
+12 -2
View File
@@ -1,12 +1,22 @@
#!/usr/bin/env bash
set -Eeu
# This script generates a list of Gradle sub-projects by parsing the output
# of Gradle 'projects' task using grep and sed. It is necessary in order to
# collect list of dependencies for main project and its sub-projects.
set -Eeuo pipefail
GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
# Gradle needs to be run in 'android' subfolder
# Gradle needs to be run in 'android' subfolder.
cd "${GIT_ROOT}/android"
# Show Gradle log in case of failure.
GRADLE_LOG_FILE='/tmp/gradle.log'
function show_gradle_log() { cat "${GRADLE_LOG_FILE}" >&2; }
trap show_gradle_log ERR
# Print all our sub-projects
./gradlew projects --no-daemon --console plain 2>&1 \
| tee "${GRADLE_LOG_FILE}" \
| grep "Project ':" \
| sed -E "s;^.--- Project '\:([@_a-zA-Z0-9\-]+)';\1;"
+1
View File
@@ -26,6 +26,7 @@ react-native-lottie-splash-screen
react-native-mail
react-native-navigation
react-native-nfc-manager
react-native-orientation-locker
react-native-permissions
react-native-randombytes
react-native-reanimated
+56 -54
View File
@@ -6,8 +6,6 @@
# a local Maven repository.
#
CUR_DIR=$(cd "${BASH_SOURCE%/*}" && pwd)
# This defines URLs of Maven repos we know about and use.
declare -a REPOS=(
"https://repo.maven.apache.org/maven2"
@@ -36,84 +34,88 @@ function match_repo_url() {
exit 1
}
function pom_has_nodeps_jar() {
grep '<shadedClassifierName>nodeps</shadedClassifierName>' "${1}" \
>/dev/null 2>&1
}
function fetch_and_template_file() {
local FILENAME="${1}"
local OBJ_URL OBJ_NIX_FETCH_OUT OBJ_NAME OBJ_PATH
OBJ_URL="${REPO_URL}/${PKG_PATH}/${FILENAME}"
if ! OBJ_NIX_FETCH_OUT=$(nix_fetch "${OBJ_URL}"); then
echo " ! Failed to fetch: ${OBJ_URL}" >&2
exit 1
fi
OBJ_NAME="${FILENAME}"
OBJ_PATH=$(get_nix_path "${OBJ_NIX_FETCH_OUT}")
echo -n ",
\"${OBJ_NAME}\": {
\"sha1\": \"$(get_sha1 "${OBJ_PATH}")\",
\"sha256\": \"$(get_nix_sha "${OBJ_NIX_FETCH_OUT}")\"
}"
}
if [[ -z "${1}" ]]; then
echo "Required argument not given!" >&2
echo "Required POM URL argument not given!" >&2
exit 1
fi
POM_URL=${1}
# Drop the POM extension
OBJ_REL_URL=${POM_URL%.pom}
# Drop the POM extension.
PKG_URL_NO_EXT="${POM_URL%.pom}"
# Name of package without extension.
PKG_NAME="$(basename "${PKG_URL_NO_EXT}")"
echo -en "${CLR} - Nix entry for: ${1##*/}\r" >&2
REPO_URL=$(match_repo_url "${OBJ_REL_URL}")
REPO_URL=$(match_repo_url "${PKG_URL_NO_EXT}")
if [[ -z "${REPO_URL}" ]]; then
echo "\r\n ? REPO_URL: ${REPO_URL}" >&2
echo " ! Repo URL not found: %s" "${REPO_URL}" >&2
exit 1
fi
# Get the relative path without full URL
OBJ_REL_NAME="${OBJ_REL_URL#${REPO_URL}/}"
PKG_PATH="${PKG_URL_NO_EXT#"${REPO_URL}/"}"
PKG_PATH="$(dirname "${PKG_PATH}")"
# Both JARs and AARs have a POM
POM_NIX_FETCH_OUT=$(nix_fetch "${OBJ_REL_URL}.pom")
POM_NIX_FETCH_OUT=$(nix_fetch "${PKG_URL_NO_EXT}.pom")
POM_PATH=$(get_nix_path "${POM_NIX_FETCH_OUT}")
POM_NAME=$(basename "${PKG_URL_NO_EXT}.pom")
if [[ -z "${POM_PATH}" ]]; then
echo " ! Failed to fetch: ${OBJ_REL_URL}.pom" >&2
echo " ! Failed to fetch: ${PKG_URL_NO_EXT}.pom" >&2
exit 1
fi
POM_SHA256=$(get_nix_sha "${POM_NIX_FETCH_OUT}")
POM_SHA1=$(get_sha1 "${POM_PATH}")
# Identify packaging type, JAR, AAR, or just POM.
OBJ_TYPE_RAW=$(grep -oP '<packaging>\K[^<]+' "${POM_PATH}")
# Bundle is a JAR made using maven-bundle-plugin.
case "${OBJ_TYPE_RAW}" in
''|'bundle') OBJ_TYPE=jar;;
'aar.asc') OBJ_TYPE=aar;;
*) OBJ_TYPE="${OBJ_TYPE_RAW}"
esac
# Identify packaging type, JAR, AAR, bundle, or just POM.
OBJ_TYPE=$(grep -oP '<packaging>\K[^<]+' "${POM_PATH}")
# Some deps are Eclipse plugins, and we don't need those.
if [[ "${OBJ_TYPE}" == "eclipse-plugin" ]]; then
exit 0
fi
# Some deps are just POMs, in which case there is no JAR to fetch.
if [[ "${OBJ_TYPE}" != "pom" ]]; then
OBJ_NIX_FETCH_OUT=$(nix_fetch "${OBJ_REL_URL}.${OBJ_TYPE}")
# If type was a JAR or other, not getting one is an error.
if [[ ${?} -ne 0 ]]; then
# POMs without packaging type defined can still include JARs.
if [[ "${OBJ_TYPE_RAW}" != "" ]]; then
echo " ! Failed to fetch: ${OBJ_REL_URL}.${OBJ_TYPE}" >&2
exit 1
fi
else
OBJ_PATH=$(get_nix_path "${OBJ_NIX_FETCH_OUT}")
OBJ_SHA256=$(get_nix_sha "${OBJ_NIX_FETCH_OUT}")
OBJ_SHA1=$(get_sha1 "${OBJ_PATH}")
fi
fi
# Format into a Nix attrset entry
echo -ne "
{
\"path\": \"${OBJ_REL_NAME}\",
\"host\": \"${REPO_URL}\",
\"type\": \"${OBJ_TYPE}\","
if [[ -n "${POM_SHA256}" ]]; then
echo -n "
\"pom\": {
\"sha1\": \"${POM_SHA1}\",
\"sha256\": \"${POM_SHA256}\"
}";[[ -n "${OBJ_SHA256}" ]] && echo -n ","
fi
if [[ -n "${OBJ_SHA256}" ]]; then
echo -n "
\"jar\": {
\"sha1\": \"${OBJ_SHA1}\",
\"sha256\": \"${OBJ_SHA256}\"
}"
fi
echo -e "\n },"
\"path\": \"${PKG_PATH}\",
\"repo\": \"${REPO_URL}\",
\"files\": {
\"${POM_NAME}\": {
\"sha1\": \"${POM_SHA1}\",
\"sha256\": \"${POM_SHA256}\"
}"
# Some deps are just POMs, in which case there is no JAR to fetch.
[[ "${OBJ_TYPE}" == "" ]] && fetch_and_template_file "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" == "jar" ]] && fetch_and_template_file "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" == "bundle" ]] && fetch_and_template_file "${PKG_NAME}.jar"
[[ "${OBJ_TYPE}" =~ aar* ]] && fetch_and_template_file "${PKG_NAME}.aar"
[[ "${OBJ_TYPE}" == "aar.asc" ]] && fetch_and_template_file "${PKG_NAME}.${OBJ_TYPE}"
pom_has_nodeps_jar "${POM_PATH}" && fetch_and_template_file "${PKG_NAME}-nodeps.jar"
echo -e '\n }\n },'
+8 -1
View File
@@ -29,7 +29,14 @@ stdenv.mkDerivation {
# maven and google central repositories with our own local directories.
# This prevents the builder from downloading Maven artifacts
patchGradlePhase = ''
for modBuildGradle in $(find -L ./node_modules -name build.gradle); do
gradleConfigs=$(
find -L ./node_modules \
-name build.gradle -or \
-name build.gradle.kts -or \
-name settings.gradle -or \
-name settings.gradle.kts
)
for modBuildGradle in $gradleConfigs; do
relativeToNode=''${modBuildGradle#*node_modules/}
moduleName=''${relativeToNode%%/*}
if [[ -L ./node_modules/$moduleName ]]; then
+1
View File
@@ -20,6 +20,7 @@ in {
];
# WARNING: Executes shellHook in reverse order.
# WARNING: Only some variables are merged.
inputsFrom = [
fastlane.shell
cocoapods-sh
+8 -5
View File
@@ -1,11 +1,14 @@
{ mkShell, deps }:
{ mkShell, nodejs, deps }:
mkShell {
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
NODE_OPTIONS = "--openssl-legacy-provider";
# check if node modules changed and if so install them
# Check if node modules changed and if so install them.
shellHook = ''
# Fix for ERR_OSSL_EVP_UNSUPPORTED error.
export NODE_OPTIONS="--openssl-legacy-provider";
# Fix Xcode using system Node.js version.
export NODE_BINARY="${nodejs}/bin/node";
export STATUS_MOBILE_HOME=$(git rev-parse --show-toplevel)
"$STATUS_MOBILE_HOME/nix/scripts/node_modules.sh" ${deps.nodejs-patched}
'';
+4 -3
View File
@@ -16,7 +16,8 @@ writeScript "patch-maven-srcs" (''
gradleFile="$1"
# Some of those find something, some don't, that's fine.
patchMavenSource "$gradleFile" 'mavenCentral()' 'mavenLocal()'
patchMavenSource "$gradleFile" 'google()' 'mavenLocal()'
patchMavenSource "$gradleFile" 'jcenter()' 'mavenLocal()'
patchMavenSource "$gradleFile" 'mavenCentral()' 'mavenLocal()'
patchMavenSource "$gradleFile" 'google()' 'mavenLocal()'
patchMavenSource "$gradleFile" 'jcenter()' 'mavenLocal()'
patchMavenSource "$gradleFile" 'gradlePluginPortal()' 'mavenLocal()'
'')
+1 -1
View File
@@ -28,7 +28,6 @@
"@react-native-community/push-notification-ios": "^1.4.1",
"@react-native-community/slider": "^3.0.0",
"@walletconnect/client": "^2.0.0-beta.23",
"@walletconnect/client-legacy": "npm:@walletconnect/client@^1.7.1",
"bignumber.js": "git+https://github.com/status-im/bignumber.js.git#refs/tags/v4.0.2-status",
"chance": "^1.1.0",
"create-react-class": "^15.6.2",
@@ -62,6 +61,7 @@
"react-native-lottie-splash-screen": "^1.0.1",
"react-native-mail": "^6.1.1",
"react-native-navigation": "^7.27.1",
"react-native-orientation-locker": "^1.5.0",
"react-native-permissions": "^2.1.5",
"react-native-randombytes": "^3.6.1",
"react-native-reanimated": "2.3.3",

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Before

Width:  |  Height:  |  Size: 233 KiB

After

Width:  |  Height:  |  Size: 233 KiB

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Before

Width:  |  Height:  |  Size: 5.9 KiB

After

Width:  |  Height:  |  Size: 5.9 KiB

Before

Width:  |  Height:  |  Size: 4.0 KiB

After

Width:  |  Height:  |  Size: 4.0 KiB

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Before

Width:  |  Height:  |  Size: 539 KiB

After

Width:  |  Height:  |  Size: 539 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Before

Width:  |  Height:  |  Size: 9.7 KiB

After

Width:  |  Height:  |  Size: 9.7 KiB

Before

Width:  |  Height:  |  Size: 112 KiB

After

Width:  |  Height:  |  Size: 112 KiB

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 192 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 788 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Before

Width:  |  Height:  |  Size: 601 B

After

Width:  |  Height:  |  Size: 601 B

Before

Width:  |  Height:  |  Size: 896 B

After

Width:  |  Height:  |  Size: 896 B

Before

Width:  |  Height:  |  Size: 593 B

After

Width:  |  Height:  |  Size: 593 B

Before

Width:  |  Height:  |  Size: 837 B

After

Width:  |  Height:  |  Size: 837 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Before

Width:  |  Height:  |  Size: 998 B

After

Width:  |  Height:  |  Size: 998 B

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 377 KiB

After

Width:  |  Height:  |  Size: 377 KiB

Before

Width:  |  Height:  |  Size: 738 KiB

After

Width:  |  Height:  |  Size: 738 KiB

+2 -4
View File
@@ -1,11 +1,9 @@
#!/usr/bin/env sh
CHANGES=$(git diff --no-ext-diff --diff-filter=d --cached --unified=0 --no-prefix --minimal --exit-code src/quo src/quo2 | grep '^+' || echo '')
INVALID_CHANGES=$(echo "$CHANGES" | grep -E '(re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt|status-im)')
INVALID_CHANGES=$(grep -E -r '(re-frame/dispatch|rf/dispatch|re-frame/subscribe|rf/subscribe|rf/sub|<sub|>evt|status-im\.|status-im2\.)' './src/quo2')
if test -n "$INVALID_CHANGES"; then
echo "re-frame dispatch/subscribe and status-im are not allowed in quo/quo2 components"
echo "WARNING: re-frame, status-im are not allowed in quo2 components"
echo ''
echo "$INVALID_CHANGES"
exit 1
+6
View File
@@ -139,6 +139,7 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
(def react-native-svg
#js
{:ClipPath #js {:render identity}
:Circle #js {:render identity}
:Defs #js {:render identity}
:Path #js {:render identity}
:Rect #js {:render identity}
@@ -333,6 +334,10 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
(def react-native-camera-roll
(clj->js {:default #js {}}))
(def react-native-orientation-locker
(clj->js {:default #js {}
:useDeviceOrientationChange #js {}}))
(def wallet-connect-client
#js
{:default #js {}
@@ -398,6 +403,7 @@ globalThis.__STATUS_MOBILE_JS_IDENTITY_PROXY__ = new Proxy({}, {get() { return (
"react-native-share" react-native-share
"@react-native-async-storage/async-storage" async-storage
"react-native-svg" react-native-svg
"react-native-orientation-locker" react-native-orientation-locker
"../src/js/worklet_factory.js" worklet-factory
"../src/js/shell_worklets.js" shell-worklets
"../src/js/bottom_sheet.js" bottom-sheet
@@ -1,6 +1,6 @@
(ns quo2.components.animated-header-flatlist.style
(:require [quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]))
[react-native.reanimated :as ra]))
(defn container-view
[view-height]
@@ -19,53 +19,56 @@
:border-radius 10
:justify-content :center
:align-items :center
:background-color (colors/theme-colors colors/white-opa-40 colors/neutral-80-opa-40)}
:background-color (colors/theme-colors colors/white-opa-40 colors/neutral-80-opa-40)
:position :absolute
:top 56
:z-index 3}
position))
(defn blur-view
[animation]
(reanimated/apply-animations-to-style
{:opacity animation}
(ra/apply-animations-to-style
{:opacity animation}
{:position :absolute
:top 0
:left 0
:right 0
:height 100
:width "100%"
:display :flex
:flex-direction :row
:z-index 2
:overflow :hidden}))
(defn entity-picture
[animation]
(reanimated/apply-animations-to-style
{}
(ra/apply-animations-to-style
{:width animation
:height animation}
{:transform [{:scale 1}]
:border-radius 40
:position :absolute
:bottom 72
:bottom 42
:left 20
:justify-content :center
:align-items :center
:background-color (colors/theme-colors colors/white colors/neutral-100)
:overflow :hidden}))
(defn header-bottom-part
[animation]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:border-top-right-radius animation
:border-top-left-radius animation}
{:background-color (colors/theme-colors colors/white colors/neutral-100)
:margin-top -8
:shadow-offset {:width 0
:height -16}
:shadow-radius 12
:shadow-opacity 1
:shadow-color "#09101C14"}))
{:position :absolute
:bottom 0
:height 86
:left 0
:right 0
:background-color (colors/theme-colors colors/white colors/neutral-100)}))
(defn header-comp
[y-animation opacity-animation]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
;; here using `left` won't work on Android, so we are using `translateX`
{:transform [{:translateY y-animation}]
{:transform [{:translateX (ra/use-val 64)} {:translateY y-animation}]
:opacity opacity-animation}
{:flex 1}))
{:position :absolute
:z-index 3}))
@@ -3,124 +3,95 @@
[quo2.core :as quo]
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[react-native.safe-area :as safe-area]
[react-native.fast-image :as fast-image]
[reagent.core :as reagent]
[quo2.foundations.colors :as colors]
[status-im.ui.components.fast-image :as fast-image]
[quo2.components.animated-header-flatlist.style :as style]
[oops.core :as oops]
[utils.re-frame :as rf]))
[oops.core :as oops]))
(def header-height 234)
(def cover-height 192)
(def blur-view-height 100)
(def threshold (- header-height blur-view-height))
(defn interpolate
[value input-range output-range]
(ra/interpolate value
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"}))
(defn scroll-handler
[event initial-y scroll-y]
(let [content-size-y (- (oops/oget event "nativeEvent.contentSize.height")
(oops/oget event "nativeEvent.layoutMeasurement.height"))
current-y (+ (oops/oget event "nativeEvent.contentOffset.y") initial-y)]
(reanimated/set-shared-value scroll-y (- content-size-y current-y))))
(let [current-y (- (oops/oget event "nativeEvent.contentOffset.y") initial-y)]
(ra/set-val scroll-y current-y)))
(defn header
[{:keys [theme-color cover-uri cover-bg-color title-comp]} top-inset scroll-y]
(let [input-range [0 (* threshold 0.33)]
border-animation (reanimated/interpolate scroll-y input-range [12 0]
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})]
[{:keys [theme-color display-picture-comp cover-uri title-comp]} top-inset scroll-y]
(let [input-range [0 (* threshold 0.33)]
picture-scale-down 0.4
size-animation (interpolate scroll-y input-range [80 (* 80 picture-scale-down)])
image-animation (interpolate scroll-y input-range [72 (* 72 picture-scale-down)])
border-animation (interpolate scroll-y input-range [12 0])]
[rn/view
{:style {:background-color (or theme-color (colors/theme-colors colors/white colors/neutral-95))
{:style {:height header-height
:background-color (or theme-color (colors/theme-colors colors/white colors/neutral-95))
:margin-top (when platform/ios? (- top-inset))}}
(when cover-uri
[fast-image/fast-image
{:style {:width "100%"
:height cover-height}
:source {:uri cover-uri}}])
(when cover-bg-color
[rn/view
{:style {:width "100%"
:height cover-height
:background-color cover-bg-color}}])
[reanimated/view {:style (style/header-bottom-part border-animation)}
[title-comp]]]))
[ra/view {:style (style/header-bottom-part border-animation)}
[title-comp]]
[ra/view {:style (style/entity-picture size-animation)}
[display-picture-comp image-animation]]]))
(defn animated-header-list
[{:keys [header-comp main-comp footer-comp title-comp] :as parameters}]
[{:keys [header-comp main-comp back-button-on-press] :as parameters}]
[safe-area/consumer
(fn [insets]
(let [window-height (:height (rn/get-window))
(let [window-height (:height (rn/get-window))
status-bar-height (rn/status-bar-height)
bottom-inset (:bottom insets)
initial-y (if platform/ios? (- (:top insets)) 0)]
bottom-inset (:bottom insets)
;; view height calculation is different because window height is different on iOS and Android:
view-height (if platform/ios?
(- window-height bottom-inset)
(+ window-height status-bar-height))
initial-y (if platform/ios? (- (:top insets)) 0)]
[:f>
(fn []
(let [scroll-y (reanimated/use-shared-value initial-y)
opacity-animation (reanimated/interpolate scroll-y
[(* threshold 0.33) (* threshold 0.66)]
[0 1]
{:extrapolateLeft "clamp"
:extrapolateRight "extend"})
translate-animation (reanimated/interpolate scroll-y [(* threshold 0.66) threshold] [50 0]
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})
title-opacity-animation (reanimated/interpolate scroll-y [(* threshold 0.66) threshold] [0 1]
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})]
[rn/keyboard-avoiding-view
{:style {:position :absolute
:flex 1
:top 0
:left 0
:height window-height
:bottom 0
:right 0}
:keyboardVerticalOffset (- bottom-inset)}
[reanimated/blur-view
(let [scroll-y (ra/use-val initial-y)
opacity-animation (interpolate scroll-y
[(* threshold 0.33) (* threshold 0.66)]
[0 1])
translate-animation (interpolate scroll-y [(* threshold 0.66) threshold] [100 56])
title-opacity-animation (interpolate scroll-y [(* threshold 0.66) threshold] [0 1])]
[rn/view {:style (style/container-view view-height)}
[rn/touchable-opacity
{:active-opacity 1
:on-press back-button-on-press
:style (style/button-container {:left 20})}
[quo/icon :i/arrow-left {:size 20 :color (colors/theme-colors colors/black colors/white)}]]
[rn/touchable-opacity
{:active-opacity 1
:style (style/button-container {:right 20})}
[quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]]
[ra/blur-view
{:blurAmount 32
:blurType :light
:overlayColor (if platform/ios? colors/white-opa-70 :transparent)
:style (style/blur-view opacity-animation)}]
[rn/view {:style {:position :absolute
:top 56
:left 0
:right 0
:padding-bottom 12
:width "100%"
:display :flex
:flex-direction :row
:z-index 2
:overflow :hidden}}
[rn/touchable-opacity
{:active-opacity 1
:on-press #(rf/dispatch [:navigate-back])
:style (style/button-container {:margin-left 20})}
[quo/icon :i/arrow-left {:size 20 :color (colors/theme-colors colors/black colors/white)}]]
[reanimated/view {:style (style/header-comp translate-animation title-opacity-animation)}
[header-comp]]
[rn/touchable-opacity
{:active-opacity 1
:style (style/button-container {:margin-right 20})}
[quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]]]
(when main-comp
[main-comp])
#_[reanimated/flat-list
{:data [nil]
:render-fn main-comp
:key-fn str
:inverted (when platform/ios? true)
:style (when platform/android? {:scaleY -1})
:footer (reagent/as-element (header parameters (:top insets) scroll-y))
:style (style/blur-view opacity-animation)}
[ra/view {:style (style/header-comp translate-animation title-opacity-animation)}
[header-comp]]]
[ra/flat-list
{:data [nil]
:render-fn main-comp
:key-fn str
:header (reagent/as-element (header parameters (:top insets) scroll-y))
;; TODO: https://github.com/status-im/status-mobile/issues/14924
:scroll-event-throttle 8
:keyboard-dismiss-mode :interactive
:keyboard-should-persist-taps :handled
:on-scroll (fn [event] (scroll-handler event initial-y scroll-y))}]
(when footer-comp
(footer-comp insets))]))]))])
:scroll-event-throttle 8
:on-scroll (fn [event] (scroll-handler event initial-y scroll-y))}]]))]))])
+89 -105
View File
@@ -1,6 +1,5 @@
(ns quo2.components.avatars.user-avatar
(:require [clojure.string :refer [blank? split upper-case]]
[quo2.components.icon :as icons]
(:require [clojure.string :as string]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[quo2.theme :refer [dark?]]
@@ -40,115 +39,100 @@
:font-size :label}})
(defn dot-indicator
[size status-indicator? online? ring? dark?]
(when 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}}])))
[{:keys [size online? ring? dark?]}]
(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 -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
(defn initials-style
[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})
{:position :absolute
:top (/ (- outer-dimensions inner-dimensions) 2)
:left (/ (- outer-dimensions inner-dimensions) 2)
:width inner-dimensions
:height inner-dimensions
:border-radius inner-dimensions
:justify-content :center
:align-items :center
:background-color (colors/custom-color-by-theme :turquoise 50 60)})
(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])
(defn outer-styles
[outer-dimensions]
{:width outer-dimensions
:height outer-dimensions
:border-radius outer-dimensions})
(def small-sizes #{:xs :xxs :xxxs})
(def identicon-sizes #{:big :medium :small})
(def one-initial-letter-sizes #{:xs :xxs :xxxs})
(def valid-ring-sizes #{:big :medium :small})
(defn initials-avatar
[{:keys [full-name size inner-dimensions outer-dimensions]}]
(let [amount-initials (if (one-initial-letter-sizes size) 1 2)
initials (as-> full-name $
(string/split $ " ")
(map (comp string/upper-case first) $)
(take amount-initials $)
(string/join $))
font-size (get-in sizes [size :font-size])]
[rn/view {:style (initials-style inner-dimensions outer-dimensions)}
[text/text
{:style {:color colors/white-opa-70}
:weight :semi-bold
:size font-size}
initials]]))
(defn user-avatar
[{:keys [ring?
online?
size
status-indicator?
profile-picture
full-name]
:or {full-name "empty name"
status-indicator? true
"If no `profile-picture` is given, draws the initials based on the `full-name` and
uses `ring-background` to display the ring behind the initials when given. Otherwise,
shows the profile picture which already comes with the ring drawn over it."
[{:keys [full-name status-indicator? online? size profile-picture ring-background]
:or {status-indicator? true
online? true
size :big
ring? true}}]
(let [initials (if full-name
(reduce str (map first (split full-name " ")))
"")
first-initial-letter (if full-name
(or (first full-name) "")
"")
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)])
font-size (get-in sizes [size :font-size])
icon-text (if-not (or (blank? first-initial-letter)
(blank? initials))
(if small?
first-initial-letter
initials)
"")]
size :big}}]
(let [full-name (or full-name "empty name")
draw-ring? (and ring-background (valid-ring-sizes size))
outer-dimensions (get-in sizes [size :outer])
inner-dimensions (get-in sizes [size (if draw-ring? :inner :outer)])]
[rn/view
{:accessibility-label :user-avatar
:style {:width outer-dimensions
:height outer-dimensions
:border-radius outer-dimensions}}
(when (and false (and ring? identicon?)) ;;TODO not implemented yet
[icons/icon :i/identicon-ring
{:size outer-dimensions
:no-color true}])
(if profile-picture
;; display image
{:style (outer-styles outer-dimensions)
:accessibility-label :user-avatar}
;; The `profile-picture` already has the ring in it
(when-let [image (or profile-picture ring-background)]
[fast-image/fast-image
{:source 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}}
(upper-case icon-text)]])
[dot-indicator size status-indicator? online? ring? (dark?)]]))
{:style (outer-styles outer-dimensions)
:source image}])
(when-not profile-picture
[initials-avatar
{:full-name full-name
:size size
:inner-dimensions inner-dimensions
:outer-dimensions outer-dimensions}])
(when status-indicator?
[dot-indicator
{:size size
:online? online?
:ring? draw-ring?
:dark? (dark?)}])]))
@@ -5,8 +5,8 @@
[react-native.core :as rn]))
(defn community-card-view-item
[{:keys [name description locked images
status tokens cover tags width]} on-press]
[{:keys [name description locked images cover
status tokens tags width]} on-press]
[rn/touchable-without-feedback
{:accessibility-label :community-card-item
:on-press on-press}
@@ -18,16 +18,16 @@
:on-press on-press}
[rn/view
{:flex 1}
[rn/view (style/community-cover-container 40)
[rn/view (style/community-cover-container 60)
[rn/image
{:source cover
:style
{:flex 1
:border-radius 20}}]]
{:flex 1
:border-top-right-radius 20
:border-top-left-radius 20}}]]
[rn/view (style/card-view-content-container 12)
[rn/view (style/card-view-chat-icon 48)
[icon/community-icon {:images images} 48]]
(when (= status :gated)
[rn/view (style/permission-tag-styles)
[community-view/permission-tag-container
@@ -42,16 +42,15 @@
(defn community-tags
[tags]
[rn/view (style/community-tags-container)
(for [{:keys [id tag-label resource]} tags]
^{:key id}
(for [{:keys [name emoji]} tags]
^{:key name}
[rn/view {:margin-right 8}
[tag/tag
{:id id
:size 24
:label tag-label
{:size 24
:label name
:type :emoji
:labelled? true
:resource resource}]])])
:resource emoji}]])])
(defn community-title
[{:keys [title description size] :or {size :small}}]
@@ -82,6 +81,5 @@
colors/neutral-80)
:locked? locked?
:tokens tokens
:size 24
:on-press on-press}])
+12 -8
View File
@@ -57,14 +57,18 @@
(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)})
{:position :absolute
:top 40
:bottom 0
:left 0
:right 0
:height 20
:padding-horizontal padding-horizontal
:border-top-right-radius 16
:border-top-left-radius 16
:background-color (colors/theme-colors
colors/white
colors/neutral-90)})
(defn card-view-chat-icon
[icon-size]
@@ -0,0 +1,38 @@
(ns quo2.components.dividers.strength-divider.component-spec
(:require [quo2.components.dividers.strength-divider.view :as strength-divider]
[test-helpers.component :as h]))
(h/describe "select-profile component"
(h/test "render component"
(h/render [strength-divider/view {:type :okay}])
(-> (h/expect (h/get-by-label-text :strength-divider))
(.toBeTruthy)))
(h/test "render component with :type :very-weak"
(h/render [strength-divider/view {:type :very-weak}])
(-> (h/expect (h/get-by-translation-text :strength-divider-very-weak-label))
(.toBeTruthy)))
(h/test "render component with :type :weak"
(h/render [strength-divider/view {:type :weak}])
(-> (h/expect (h/get-by-translation-text :strength-divider-weak-label))
(.toBeTruthy)))
(h/test "render component with :type :okay"
(h/render [strength-divider/view {:type :okay}])
(-> (h/expect (h/get-by-translation-text :strength-divider-okay-label))
(.toBeTruthy)))
(h/test "render component with :type :strong"
(h/render [strength-divider/view {:type :strong}])
(-> (h/expect (h/get-by-translation-text :strength-divider-strong-label))
(.toBeTruthy)))
(h/test "render component with :type :very-strong"
(h/render [strength-divider/view {:type :very-strong}])
(-> (h/expect (h/get-by-translation-text :strength-divider-very-strong-label))
(.toBeTruthy)))
(h/test "render component with :type :alert"
(h/render [strength-divider/view {:type :alert} "Text message"])
(-> (h/expect (h/get-by-text "Text message"))
(.toBeTruthy)))
(h/test "render component with :type :info"
(h/render [strength-divider/view {:type :info} "Text Info"])
(-> (h/expect (h/get-by-text "Text Info"))
(.toBeTruthy))))
@@ -0,0 +1,13 @@
(ns quo2.components.dividers.strength-divider.style)
(def container
{:height 40
:flex-direction :row
:padding-horizontal 20
:align-items :center})
(defn text
[color]
{:color color
:margin-left 4})
@@ -0,0 +1,85 @@
(ns quo2.components.dividers.strength-divider.view
(:require [quo2.components.dividers.strength-divider.style :as style]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.linear-gradient :as linear-gradient]
[react-native.svg :as svg]
[utils.i18n :as i18n]))
(def strength-divider-types
{:very-weak {:default-text (i18n/label :t/strength-divider-very-weak-label)
:color colors/danger-60
:percentage 20}
:weak {:default-text (i18n/label :t/strength-divider-weak-label)
:color (colors/custom-color :orange 60)
:percentage 40}
:okay {:default-text (i18n/label :t/strength-divider-okay-label)
:color (colors/custom-color :yellow 60)
:percentage 60}
:strong {:default-text (i18n/label :t/strength-divider-strong-label)
:color colors/success-60
:percentage 80}
:very-strong {:default-text (i18n/label :t/strength-divider-very-strong-label)
:color colors/success-60
:percentage 100}
:info {:color colors/white-opa-40}
:alert {:color colors/danger-60}})
(defn circular-progress
[{:keys [color percentage]}]
(let [strength-indicator-radius 6.5
strength-indicator-circumference (* 2 Math/PI strength-indicator-radius)]
[svg/svg
{:view-box "0 0 16 16"
:width 14.2
:transform [{:rotate "270deg"}]
:height 14.2}
[svg/circle
{:cx 8
:cy 8
:r strength-indicator-radius
:fill :transparent
:stroke-width 1.2
:stroke (colors/alpha color 0.2)}]
[svg/circle
{:cx 8
:cy 8
:r strength-indicator-radius
:fill :transparent
:stroke-width 1.2
:stroke-dasharray strength-indicator-circumference
:stroke-dashoffset (* (- 100 percentage) 0.01 strength-indicator-circumference)
:stroke color}]
[svg/circle]]))
(defn strength-indicator
[type]
(let [{:keys [color percentage]} (strength-divider-types type)]
(case type
:info nil
:alert [icon/icon :i/alert
{:color color
:size 16}]
[circular-progress {:color color :percentage percentage}])))
(defn view
"Options
- `:type` `:very-weak`/`:weak`/`:okay`/`:strong`/`:very-strong`/`:info`/`:alert`)
`text` message string(only works when type is `info`/`alert`)"
[{:keys [type] :or {type :very-weak}} text]
(let [{:keys [color default-text]} (strength-divider-types type)]
[linear-gradient/linear-gradient
{:colors [(colors/alpha color 0.05) (colors/alpha color 0)]}
[rn/view
{:style style/container
:accessibility-label :strength-divider}
[strength-indicator type]
[text/text
{:size :paragraph-2
:weight :medium
:style (style/text color)}
(or default-text text)]]]))
@@ -4,22 +4,24 @@
(def outer-container {:height 216})
(def top-card
{:flex 1
:padding-vertical 12
:padding-horizontal 20
:border-radius 20
:background-color colors/neutral-80})
{:flex 1
:padding-vertical 12
:padding-horizontal 20
:border-top-left-radius 20
:border-top-right-radius 20
:background-color colors/neutral-80})
(def bottom-card
{:position :absolute
:top 80
:left 0
:right 0
:bottom 0
:padding-vertical 12
:padding-horizontal 20
:border-radius 20
:background-color (colors/alpha colors/white 0.05)})
{:position :absolute
:top 80
:left 0
:right 0
:bottom 0
:padding-vertical 12
:padding-horizontal 20
:border-top-left-radius 20
:border-top-right-radius 20
:background-color (colors/alpha colors/white 0.05)})
(def bottom-container
{:flex-direction :row
@@ -39,13 +39,14 @@
children))
(defn card
[{:keys [on-press style heading gap top?]} children]
[{:keys [on-press style heading gap accessibility-label top?]} children]
[rn/touchable-highlight
{:on-press on-press
:border-radius 20
:style style
:underlay-color (:background-color style)}
[rn/view {}
{:accessibility-label accessibility-label
:on-press on-press
:border-radius 20
:style style
:underlay-color (:background-color style)}
[rn/view
[text/text
{:size :heading-1
:style (style/heading-text gap)
@@ -60,9 +61,11 @@
opts
{:container-style style-object
:top-card { :on-press event
:heading string}
:heading string
:accessibility-label keyword}
:bottom-card { :on-press event
:heading string}}
:heading string
:accessibility-label keyword}}
child-1 string, keyword or hiccup
child-2 string, keyword or hiccup
"
+9 -9
View File
@@ -3,16 +3,16 @@
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[reagent.core :as reagent]))
(defn apply-anim
[dd-height val]
(reanimated/animate-shared-value-with-delay dd-height
val
300
:easing1
0))
(ra/animate-delay dd-height
val
0
300
:easing1))
(def sizes
{:big {:icon-size 20
@@ -141,7 +141,7 @@
[:f>
(fn []
(let [open? (reagent/atom false)
dd-height (reanimated/use-shared-value 0)]
dd-height (ra/use-val 0)]
[rn/view {:style {:flex-grow 1}}
[dropdown-comp
{:items items
@@ -155,8 +155,8 @@
:default-item default-item
:open? open?
:dd-height dd-height}]
[reanimated/view
{:style (reanimated/apply-animations-to-style
[ra/view
{:style (ra/apply-animations-to-style
{:height dd-height}
{:height dd-height})}
[items-comp
+2 -2
View File
@@ -4,7 +4,7 @@
[quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[reagent.core :as reagent]))
(def header-height 56)
@@ -162,7 +162,7 @@
border-bottom false}}]
(let [status-bar-height (get insets :top 0)
height (+ header-height status-bar-height)]
[reanimated/view
[ra/view
{:style (header-wrapper-style {:height height
:background background
:border-bottom border-bottom})}
+170
View File
@@ -0,0 +1,170 @@
(ns quo2.components.input.style
(:require [quo2.components.markdown.text :as text]
[quo2.foundations.colors :as colors]))
(def variants-colors
"Colors that keep the same across input's status change"
{:light {:label colors/neutral-50
:icon colors/neutral-50
:cursor (colors/custom-color :blue 50)
:button-border colors/neutral-30
:clear-icon colors/neutral-40
:password-icon colors/neutral-50}
:light-blur {:label colors/neutral-80-opa-40
:icon colors/neutral-80-opa-70
:cursor (colors/custom-color :blue 50)
:button-border colors/neutral-80-opa-30
:password-icon colors/neutral-100
:clear-icon colors/neutral-80-opa-30}
:dark {:label colors/neutral-40
:icon colors/neutral-40
:cursor (colors/custom-color :blue 60)
:button-border colors/neutral-70
:password-icon colors/white
:clear-icon colors/neutral-60}
:dark-blur {:label colors/white-opa-40
:icon colors/white-opa-70
:cursor colors/white
:button-border colors/white-opa-10
:password-icon colors/white
:clear-icon colors/white-opa-10}})
(def status-colors
{:light {:default {:border-color colors/neutral-20
:placeholder colors/neutral-40
:text colors/neutral-100}
:focus {:border-color colors/neutral-40
:placeholder colors/neutral-30
:text colors/neutral-100}
:error {:border-color colors/danger-opa-40
:placeholder colors/neutral-40
:text colors/neutral-100}
:disabled {:border-color colors/neutral-20
:placeholder colors/neutral-40
:text colors/neutral-40}}
:light-blur {:default {:border-color colors/neutral-80-opa-10
:placeholder colors/neutral-80-opa-40
:text colors/neutral-100}
:focus {:border-color colors/neutral-80-opa-20
:placeholder colors/neutral-80-opa-20
:text colors/neutral-100}
:error {:border-color colors/danger-opa-40
:placeholder colors/neutral-80-opa-40
:text colors/neutral-100}
:disabled {:border-color colors/neutral-80-opa-10
:placeholder colors/neutral-80-opa-30
:text colors/neutral-80-opa-30}}
:dark {:default {:border-color colors/neutral-80
:placeholder colors/neutral-50
:text colors/white}
:focus {:border-color colors/neutral-60
:placeholder colors/neutral-60
:text colors/white}
:error {:border-color colors/danger-opa-40
:placeholder colors/white-opa-40
:text colors/white}
:disabled {:border-color colors/neutral-80
:placeholder colors/neutral-40
:text colors/neutral-40}}
:dark-blur {:default {:border-color colors/white-opa-10
:placeholder colors/white-opa-40
:text colors/white}
:focus {:border-color colors/white-opa-40
:placeholder colors/white-opa-20
:text colors/white}
:error {:border-color colors/danger-opa-40
:placeholder colors/white-opa-40
:text colors/white}
:disabled {:border-color colors/white-opa-10
:placeholder colors/white-opa-20
:text colors/white-opa-20}}})
(defn input-container
[colors-by-status small? disabled?]
{:flex-direction :row
:padding-horizontal 8
:border-width 1
:border-color (:border-color colors-by-status)
:border-radius (if small? 10 14)
:opacity (if disabled? 0.3 1)})
(defn left-icon-container
[small?]
{:margin-left (if small? 0 4)
:margin-right (if small? 4 8)
:margin-top (if small? 5 9)
:height 20
:width 20})
(defn icon
[colors-by-variant]
{:color (:icon colors-by-variant)
:size 20})
(defn input
[colors-by-status small? multiple-lines?]
(merge (text/text-style {:size :paragraph-1 :weight :regular})
{:flex 1
:text-align-vertical :top
:padding-horizontal 0
:padding-vertical (if small? 4 8)
:color (:text colors-by-status)}
(when-not multiple-lines?
{:height (if small? 30 38)})))
(defn right-icon-touchable-area
[small?]
{:margin-left (if small? 4 8)
:padding-right (if small? 0 4)
:padding-top (if small? 5 9)})
(defn password-icon
[variant-colors]
{:size 20
:color (:password-icon variant-colors)})
(defn clear-icon
[variant-colors]
{:size 20
:color (:clear-icon variant-colors)})
(def texts-container
{:flex 1
:flex-direction :row
:height 18
:margin-bottom 8})
(def label-container {:flex 1})
(defn label-color
[variant-colors]
{:color (:label variant-colors)})
(def counter-container
{:flex 1
:align-items :flex-end})
(defn counter-color
[current-chars char-limit variant-colors]
{:color (if (> current-chars char-limit)
colors/danger-60
(:label variant-colors))})
(defn button
[colors-by-variant small?]
{:justify-content :center
:align-items :center
:height 24
:border-width 1
:border-color (:button-border colors-by-variant)
:border-radius 8
:margin-vertical (if small? 3 7)
:margin-left 4
:margin-right (if small? -4 0)
:padding-horizontal 7
:padding-top 1.5
:padding-bottom 2.5})
(defn button-text
[colors-by-status]
{:color (:text colors-by-status)})
+173
View File
@@ -0,0 +1,173 @@
(ns quo2.components.input.view
(:require [oops.core :as oops]
[quo2.components.icon :as icon]
[quo2.components.input.style :as style]
[quo2.components.markdown.text :as text]
[react-native.core :as rn]
[reagent.core :as reagent]))
(defn- label-&-counter
[{:keys [label current-chars char-limit variant-colors]}]
(let [count-text (when char-limit (str current-chars "/" char-limit))]
[rn/view {:style style/texts-container}
[rn/view {:style style/label-container}
[text/text
{:style (style/label-color variant-colors)
:weight :medium
:size :paragraph-2}
label]]
[rn/view {:style style/counter-container}
[text/text
{:style (style/counter-color current-chars char-limit variant-colors)
:weight :regular
:size :paragraph-2}
count-text]]]))
(defn- left-accessory
[{:keys [variant-colors small icon-name]}]
[rn/view {:style (style/left-icon-container small)}
[icon/icon icon-name (style/icon variant-colors)]])
(defn- right-accessory
[{:keys [variant-colors small disabled on-press icon-style-fn icon-name]}]
[rn/touchable-opacity
{:style (style/right-icon-touchable-area small)
:disabled disabled
:on-press on-press}
[icon/icon icon-name (icon-style-fn variant-colors)]])
(defn- right-button
[{:keys [variant-colors colors-by-status small disabled on-press text]}]
[rn/touchable-opacity
{:style (style/button variant-colors small)
:disabled disabled
:on-press on-press}
[rn/text {:style (style/button-text colors-by-status)}
text]])
(def ^:private custom-props
"Custom properties that must be removed from properties map passed to InputText."
[:type :variant :error :right-icon :left-icon :disabled :small :button :label
:char-limit :on-char-limit-reach :icon-name])
(defn- base-input
[{:keys [on-change-text on-char-limit-reach]}]
(let [status (reagent/atom :default)
on-focus #(reset! status :focus)
on-blur #(reset! status :default)
multiple-lines? (reagent/atom false)
set-multiple-lines! #(let [height (oops/oget % "nativeEvent.contentSize.height")]
(if (> height 57)
(reset! multiple-lines? true)
(reset! multiple-lines? false)))
char-count (reagent/atom 0)
update-char-limit! (fn [new-text char-limit]
(when on-change-text (on-change-text new-text))
(let [amount-chars (count new-text)]
(reset! char-count amount-chars)
(when (>= amount-chars char-limit)
(on-char-limit-reach amount-chars))))]
(fn [{:keys [variant error right-icon left-icon disabled small button label char-limit
multiline clearable]
:or {variant :light}
:as props}]
(let [status-path (cond
disabled :disabled
error :error
:else @status)
colors-by-status (get-in style/status-colors [variant status-path])
variant-colors (style/variants-colors variant)
clean-props (apply dissoc props custom-props)]
[rn/view
(when (or label char-limit)
[label-&-counter
{:variant-colors variant-colors
:label label
:current-chars @char-count
:char-limit char-limit}])
[rn/view {:style (style/input-container colors-by-status small disabled)}
(when-let [{:keys [icon-name]} left-icon]
[left-accessory
{:variant-colors variant-colors
:small small
:icon-name icon-name}])
[rn/text-input
(cond-> {:style (style/input colors-by-status small @multiple-lines?)
:placeholder-text-color (:placeholder colors-by-status)
:cursor-color (:cursor variant-colors)
:editable (not disabled)
:on-focus on-focus
:on-blur on-blur}
:always (merge clean-props)
multiline (assoc :on-content-size-change set-multiple-lines!)
char-limit (assoc :on-change-text #(update-char-limit! char-limit %)))]
(when-let [{:keys [on-press icon-name style-fn]} right-icon]
[right-accessory
{:variant-colors variant-colors
:small small
:disabled disabled
:icon-style-fn style-fn
:icon-name icon-name
:on-press (fn []
(when clearable (reset! char-count 0))
(on-press))}])
(when-let [{:keys [on-press text]} button]
[right-button
{:colors-by-status colors-by-status
:variant-colors variant-colors
:small small
:disabled disabled
:on-press on-press
:text text}])]]))))
(defn- password-input
[_]
(let [password-shown? (reagent/atom false)]
(fn [props]
[base-input
(assoc props
:auto-capitalize :none
:auto-complete :new-password
:secure-text-entry (not @password-shown?)
:right-icon {:style-fn style/password-icon
:icon-name (if @password-shown? :i/hide :i/reveal)
:on-press #(swap! password-shown? not)})])))
(defn input
"This input supports the following properties:
- :type - Can be `:text`(default) or `:password`.
- :variant - :light(default), :light-blur, :dark or :dark-blur.
- :small - Boolean to specify if this input is rendered in its small version.
- :multiline - Boolean to specify if this input support multiple lines.
- :icon-name - The name of an icon to display at the left of the input.
- :error - Boolean to specify it this input marks an error.
- :disabled - Boolean to specify if this input is disabled or not.
- :clearable - Booolean to specify if this input has a clear button at the end.
- :on-clear - Function executed when the clear button is pressed.
- :button - Map containing `:on-press` & `:text` keys, if provided renders a button
- :label - A label for this input.
- :char-limit - A number to set a maximum char limit for this input.
- :on-char-limit-reach - Function executed each time char limit is reached or exceeded.
and supports the usual React Native's TextInput properties to control its behaviour:
- :value
- :default-value
- :on-change
- :on-change-text
...
"
[{:keys [type clearable on-clear on-change-text icon-name]
:or {type :text}
:as props}]
(let [base-props (cond-> props
icon-name (assoc-in [:left-icon :icon-name] icon-name)
clearable (assoc :right-icon
{:style-fn style/clear-icon
:icon-name :i/clear
:on-press #(when on-clear (on-clear))})
on-change-text (assoc :on-change-text
(fn [new-text]
(on-change-text new-text)
(reagent/flush))))]
(if (= type :password)
[password-input base-props]
[base-input base-props])))
@@ -0,0 +1,66 @@
(ns quo2.components.list-items.user-list
(:require [react-native.core :as rn]
[quo2.components.avatars.user-avatar :as user-avatar]
[quo2.components.markdown.text :as text]
[quo2.components.icon :as icons]
[quo2.foundations.colors :as colors]
[quo2.components.messages.author.view :as author]
[quo2.components.selectors.selectors :as selectors]))
(def container-style
{:margin-horizontal 8
:padding-vertical 8
:padding-horizontal 12
:border-radius 12
:flex 1
:flex-direction :row
:align-items :center})
(defn action-icon
[{:keys [type on-press on-check disabled? checked?]}]
[rn/touchable-opacity
{:on-press (when on-press on-press)
:style {:position :absolute :right 20}}
(case type
:options
[icons/icon :i/options
{:size 20
:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}]
:checkbox
[selectors/checkbox
{:checked? checked?
:accessibility-label :user-list-toggle-check
:disabled? disabled?
:on-change (when on-check on-check)}]
:close
[text/text "not implemented"]
[rn/view])])
(defn user-list
[{:keys [short-chat-key primary-name secondary-name photo-path online? contact? verified?
untrustworthy? on-press on-long-press accessory]}]
[rn/touchable-opacity
{:style container-style
:accessibility-label :user-list
:on-press (when on-press on-press)
:on-long-press (when on-long-press on-long-press)}
[user-avatar/user-avatar
{:full-name primary-name
:profile-picture photo-path
:status-indicator? true
:online? online?
:size :small}]
[rn/view {:style {:margin-left 8}}
[author/author
{:primary-name primary-name
:secondary-name secondary-name
:contact? contact?
:verified? verified?
:untrustworthy? untrustworthy?}]
(when short-chat-key
[text/text
{:size :paragraph-1
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}}
short-chat-key])]
(when accessory
[action-icon accessory])])
+5 -5
View File
@@ -2,7 +2,7 @@
(:require [quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.masked-view :as masked-view]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[reagent.core :as reagent]))
(def message-skeleton-height 54)
@@ -30,12 +30,12 @@
author-width (content-width :author)
message-width (content-width :message)
{window-width :width} (rn/use-window-dimensions)
translate-x (reanimated/use-shared-value (- window-width))
animated-gradient-style (reanimated/apply-animations-to-style
translate-x (ra/use-val (- window-width))
animated-gradient-style (ra/apply-animations-to-style
{:transform [{:translateX translate-x}]}
{:width window-width
:height "100%"})]
(reanimated/animate-shared-value-with-repeat translate-x window-width 1000 :linear (- 1) false)
(ra/animate-repeat translate-x window-width (- 1) false 1000 :linear)
[masked-view/masked-view
{:style {:height message-skeleton-height}
:maskElement (reagent/as-element
@@ -70,7 +70,7 @@
[rn/view
{:style {:flex 1
:background-color color}}
[reanimated/linear-gradient
[ra/linear-gradient
{:colors [color color loading-color color color]
:start {:x 0 :y 0}
:end {:x 1 :y 0}
@@ -7,14 +7,6 @@
:flex-direction :row
:align-items :center})
(defn ens-text
[]
{:color (colors/theme-colors colors/neutral-100 colors/white)})
(defn nickname-text
[]
{:color (colors/theme-colors colors/neutral-100 colors/white)})
(def middle-dot-nickname
{:color colors/neutral-50
:margin-horizontal 4})
@@ -27,12 +19,6 @@
{:color colors/neutral-50
:margin-left 4})
(defn profile-name-text
[nickname?]
{:color (if nickname?
(colors/theme-colors colors/neutral-60 colors/neutral-40)
(colors/theme-colors colors/neutral-100 colors/white))})
(def icon-container
{:margin-left 4})
+55 -81
View File
@@ -3,97 +3,71 @@
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.messages.author.style :as style]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]))
(def middle-dot "·")
(defn display-name
[{:keys [profile-name nickname ens-name text-style]}]
(let [ens? (-> ens-name string/blank? not)
nickname? (-> nickname string/blank? not)]
(if ens?
[text/text
(merge {:weight :semi-bold
:size :paragraph-2
:style (style/ens-text)}
text-style)
ens-name]
[:<>
(if nickname?
[text/text
(merge {:weight :semi-bold
:size :paragraph-2
:style (style/nickname-text)}
text-style)
nickname]
[text/text
(merge {:weight :semi-bold
:size :paragraph-2
:style (style/profile-name-text nickname?)}
text-style)
profile-name])])))
(defn author
[{:keys [profile-name nickname short-chat-key ens-name time-str contact? verified? untrustworthy?]}]
[{:keys [primary-name secondary-name short-chat-key time-str contact? verified? untrustworthy?]}]
[:f>
(fn []
(let [ens? (-> ens-name string/blank? not)
nickname? (-> nickname string/blank? not)]
[rn/view {:style style/container}
(if ens?
[rn/view {:style style/container}
[:<>
[text/text
{:weight :semi-bold
:size :paragraph-2
:number-of-lines 1
:style {:color (colors/theme-colors colors/neutral-100 colors/white)}}
primary-name]
(when (not (string/blank? secondary-name))
[:<>
[text/text
{:weight :semi-bold
:size :paragraph-2
:style (style/ens-text)}
ens-name]
[:<>
(when nickname?
[:<>
[text/text
{:weight :semi-bold
:size :paragraph-2
:style (style/nickname-text)}
nickname]
[text/text
{:size :paragraph-2
:style style/middle-dot-nickname}
middle-dot]])
[text/text
{:weight (if nickname? :medium :semi-bold)
:size :paragraph-2
:style (style/profile-name-text nickname?)}
profile-name]])
(when contact?
[icons/icon :main-icons2/contact
{:size 12
:no-color true
:container-style style/icon-container}])
(cond
verified?
[icons/icon :main-icons2/verified
{:size 12
:no-color true
:container-style style/icon-container}]
untrustworthy?
[icons/icon :main-icons2/untrustworthy
{:size 12
:no-color true
:container-style style/icon-container}])
(when-not ens?
{:size :paragraph-2
:number-of-lines 1
:style style/middle-dot-nickname}
middle-dot]
[text/text
{:monospace true
:size :paragraph-2
:style style/chat-key-text}
short-chat-key])
(when-not ens?
[text/text
{:monospace true
:size :paragraph-2
:style style/middle-dot-chat-key}
middle-dot])
{:weight :medium
:size :paragraph-2
:number-of-lines 1
:style {:color (colors/theme-colors colors/neutral-60 colors/neutral-40)}}
secondary-name]])]
(when contact?
[icons/icon :main-icons2/contact
{:size 12
:no-color true
:container-style style/icon-container}])
(cond
verified?
[icons/icon :main-icons2/verified
{:size 12
:no-color true
:container-style style/icon-container}]
untrustworthy?
[icons/icon :main-icons2/untrustworthy
{:size 12
:no-color true
:container-style style/icon-container}])
(when (and (not verified?) short-chat-key)
[text/text
{:monospace true
:size :paragraph-2
:number-of-lines 1
:style style/chat-key-text}
short-chat-key])
(when (and (not verified?) time-str)
[text/text
{:monospace true
:size :paragraph-2
:number-of-lines 1
:style style/middle-dot-chat-key}
middle-dot])
(when time-str
[text/text
{:monospace true
:size :paragraph-2
:accessibility-label :message-timestamp
:style (style/time-text ens?)}
time-str]]))])
:number-of-lines 1
:style (style/time-text verified?)}
time-str])])])
@@ -5,7 +5,7 @@
[quo2.foundations.colors :as colors]
[quo2.theme :as theme]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[utils.string :as utils]))
(def themes-landed
@@ -176,20 +176,20 @@
[{:keys [type style non-pressable? animate-landing? labels on-long-press] :as message}]
[:f>
(fn []
(let [sv-color (reanimated/use-shared-value
(let [sv-color (ra/use-val
(get-color :bg (if animate-landing? :landed :default) type))]
(when animate-landing?
(reanimated/animate-shared-value-with-delay
(ra/animate-delay
sv-color
(get-color :bg :default type)
1000
0
:linear
1000))
[reanimated/touchable-opacity
:linear))
[ra/touchable-opacity
{:on-press #(when-not non-pressable?
(reanimated/set-shared-value sv-color (get-color :bg :pressed type)))
(ra/set-val sv-color (get-color :bg :pressed type)))
:on-long-press on-long-press
:style (reanimated/apply-animations-to-style
:style (ra/apply-animations-to-style
{:background-color sv-color}
(merge
{:flex-direction :row
@@ -5,11 +5,11 @@
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.hole-view :as hole-view]
[react-native.reanimated :as reanimated]))
[react-native.reanimated :as ra]))
(defn toggle-background-color
[background-color press-out? pass-through?]
(reanimated/set-shared-value
(ra/set-val
background-color
(cond
press-out? "transparent"
@@ -31,14 +31,14 @@
on-press pass-through? icon-color-anim accessibility-label test-ID]}]
[:f>
(fn []
(let [icon-animated-style (reanimated/apply-animations-to-style
(let [icon-animated-style (ra/apply-animations-to-style
{:tint-color icon-color-anim}
{:width 24
:height 24
:margin-left 33
:margin-top 8})
background-color (reanimated/use-shared-value "transparent")
background-animated-style (reanimated/apply-animations-to-style
background-color (ra/use-val "transparent")
background-animated-style (ra/apply-animations-to-style
{:background-color background-color}
{:width 90
:height 40
@@ -49,7 +49,7 @@
:on-press-in #(toggle-background-color background-color false pass-through?)
:on-press-out #(toggle-background-color background-color true pass-through?)
:accessibility-label accessibility-label}
[reanimated/view {:style background-animated-style}
[ra/view {:style background-animated-style}
;; In android animations are not working for the animated components which are nested by
;; hole-view,
;; Interestingly this only happens when hole view and blur view are used together
@@ -69,10 +69,10 @@
:else
[{:x 47 :y 1 :width 18 :height 18 :borderRadius 7}])}
[reanimated/image
[ra/image
{:style icon-animated-style
:source (icons/icon-source (keyword (str icon 24)))}]]
[reanimated/image
[ra/image
{:style icon-animated-style
:source (icons/icon-source (keyword (str icon 24)))}])
(when new-notifications?
@@ -1,7 +1,7 @@
(ns quo2.components.navigation.floating-shell-button
(:require [quo2.components.buttons.dynamic-button :as dynamic-button]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]))
[react-native.reanimated :as ra]))
(defn dynamic-button-view
[type dynamic-buttons style]
@@ -28,12 +28,12 @@
:margin-horizontal 12
:pointer-events :box-none}
style)
animated-style (reanimated/apply-animations-to-style
animated-style (ra/apply-animations-to-style
(if opacity-anim
{:opacity opacity-anim}
{})
original-style)]
[reanimated/view {:style animated-style}
[ra/view {:style animated-style}
;; Left Section
[rn/view {:style {:flex 1}}
[dynamic-button-view :search dynamic-buttons
@@ -216,7 +216,6 @@
;; iPhone 11 Pro's height in Figma divided by Component height 56/1125
:align-items :center
:padding-horizontal 20
:margin-top 44
:height 56
:justify-content :space-between}
page-nav-background-uri (assoc :background-color page-nav-color)
@@ -7,9 +7,9 @@
[quo2.components.notifications.activity-log.style :as style]
[quo2.components.tags.status-tags :as status-tags]
[quo2.foundations.colors :as colors]
[utils.i18n :as i18n]
[react-native.core :as rn]
[reagent.core :as reagent]
[utils.i18n :as i18n]))
[reagent.core :as reagent]))
(defn- activity-reply-text-input
[{:keys [on-update-reply max-reply-length valid-reply?]} reply-input]
+26 -14
View File
@@ -5,9 +5,9 @@
[quo2.foundations.colors :as colors]
[quo2.foundations.shadows :as shadows]
[quo2.theme :as theme]
[utils.i18n :as i18n]
[react-native.blur :as blur]
[react-native.core :as rn]
[utils.i18n :as i18n]))
[react-native.core :as rn]))
(def ^:private themes
{:container {:dark {:background-color colors/white-opa-70}
@@ -56,22 +56,34 @@
(defn- toast-container
[{:keys [left title text right container-style override-theme]}]
[rn/view {:style (merge {:margin-left 12 :margin-right 12} container-style)}
[rn/view
{:style (merge {:margin-horizontal 12
:border-radius 12
:overflow :hidden}
container-style)}
[blur/view
{:style (merge-theme-style :container
(merge
(:shadow-1 shadows/normal-scale)
{:flex-direction :row
:justify-content :space-between
:padding-vertical 8
:padding-left 10
:padding-right 8
:border-radius 12})
override-theme)
{:style {:height "100%"
:width "100%"
:position :absolute
:padding-vertical 8
:padding-left 10
:padding-right 8
:background-color :transparent}
:blur-amount 13
:blur-radius 10
:blur-type :transparent
:overlay-color :transparent}
:overlay-color :transparent}]
[rn/view
{:style (merge-theme-style :container
(merge
(:shadow-1 shadows/normal-scale)
{:flex-direction :row
:justify-content :space-between
:padding-vertical 8
:padding-left 10
:padding-right 8
:border-radius 12})
override-theme)}
[rn/view {:style {:padding 2}} left]
[rn/view {:style {:padding 4 :flex 1}}
(when title
@@ -1,6 +1,5 @@
(ns quo2.components.onboarding.small-option-card.component-spec
(:require [quo2.components.onboarding.small-option-card.view :as small-option-card]
[status-im.react-native.resources :as resources]
[test-helpers.component :as h]))
(defn- testing-small-option-card
@@ -43,8 +42,7 @@
(-> on-press-fn js/expect .toHaveBeenCalled))))
(h/describe "Image rendered"
(let [image (resources/get-mock-image :small-opt-card-main)
component-props {:image image}]
(let [component-props {:image nil}]
(h/test "`:main` variant"
(h/render (testing-small-option-card :main component-props))
(-> (h/get-by-label-text :small-option-card-main-image) h/expect .-not .toBeNull))
@@ -2,12 +2,14 @@
(:require [quo2.foundations.colors :as colors]))
(defn card-container
[customization-color]
{:flex-direction :column
:padding 12
:flex 1
:border-radius 16
:background-color (colors/custom-color customization-color 50 40)})
[customization-color padding-bottom]
{:flex-direction :column
:padding-horizontal 12
:padding-top 12
:padding-bottom padding-bottom
:flex 1
:border-radius 16
:background-color (colors/custom-color customization-color 50 40)})
(def card-header
{:flex-direction :row
@@ -16,25 +18,23 @@
(def name-container
{:flex-direction :row
:margin-top 8
:margin-bottom 2
:align-items :center
:padding-right 12})
(def user-name
{:margin-right 4
:color colors/white})
{:color colors/white})
(def emoji-hash
{:margin-top 10})
{:margin-top 12})
(def user-hash
{:color colors/white-opa-60})
(def sign-button
{:margin-top 14})
{:margin-top 2
:color colors/white-opa-60})
(def keycard-icon
{:color colors/white-opa-40})
{:margin-left 4
:color colors/white-opa-40})
(def option-button
{:background-color colors/white-opa-5})
{:background-color colors/white-opa-5
:margin-left 8})
@@ -1,64 +1,80 @@
(ns quo2.components.profile.profile-card.view
(:require
[quo2.components.profile.profile-card.style :as style]
[quo2.foundations.colors :as colors]
[quo2.components.avatars.user-avatar :as user-avatar]
[quo2.components.icon :as icon]
[quo2.components.markdown.text :as text]
[quo2.components.buttons.button :as button]
[react-native.core :as rn]))
(:require [utils.i18n :as i18n]
[react-native.core :as rn]
[quo2.components.icon :as icon]
[quo2.components.tags.tag :as tag]
[quo2.foundations.colors :as colors]
[quo2.components.markdown.text :as text]
[quo2.components.buttons.button :as button]
[quo2.components.avatars.user-avatar :as user-avatar]
[quo2.components.profile.profile-card.style :as style]))
(defn profile-card
[{:keys [show-sign-profile? key-card? profile-picture name hash customization-color sign-label
emoji-hash on-press-dots on-press-sign show-emoji-hash?]
:or {show-sign-profile? false
show-emoji-hash? false
customization-color :turquoise
key-card? false}}]
[rn/view
{:style (style/card-container customization-color)}
[{:keys [key-card? profile-picture name hash customization-color
emoji-hash on-options-press show-emoji-hash? padding-bottom
show-options-button? show-user-hash? show-logged-in? on-card-press]
:or {show-emoji-hash? false
show-user-hash? false
customization-color :turquoise
show-options-button? false
show-logged-in? false
key-card? false}}]
[rn/touchable-without-feedback
{:on-press on-card-press
:flex 1
:accessibility-label :profile-card}
[rn/view
{:style style/card-header}
[user-avatar/user-avatar
{:full-name name
:profile-picture profile-picture
:override-theme :dark
:size :medium
:status-indicator? false
:ring? true}]
[button/button
{:size 32
:type :blur-bg
:icon true
:override-theme :dark
:style style/option-button
:on-press on-press-dots}
:i/options]]
[rn/view
{:style style/name-container}
[text/text
{:size :heading-2
:weight :semi-bold
:number-of-lines 1
:style style/user-name} name]
(when key-card?
(icon/icon
:i/keycard
style/keycard-icon))]
[text/text
{:weight :monospace
:number-of-lines 1
:style style/user-hash} hash]
(when (and show-emoji-hash? emoji-hash)
(style/card-container
customization-color
(or padding-bottom (if show-emoji-hash? 12 10)))
[rn/view
{:style style/card-header}
[user-avatar/user-avatar
{:full-name name
:profile-picture profile-picture
:override-theme :dark
:size :medium
:status-indicator? false}]
[rn/view {:flex-direction :row}
(when show-logged-in?
[tag/tag
{:type :icon
:size 32
:blurred? true
:labelled? true
:resource :main-icons2/check
:accessibility-label :logged-in-tag
:icon-color colors/success-50
:override-theme :dark
:label (i18n/label :t/logged-in)}])
(when show-options-button?
[button/button
{:size 32
:type :blur-bg
:icon true
:override-theme :dark
:style style/option-button
:on-press on-options-press
:accessibility-label :profile-card-options}
:i/options])]]
[rn/view
{:style style/name-container}
[text/text
{:weight :monospace
{:size :heading-2
:weight :semi-bold
:number-of-lines 1
:style style/emoji-hash} emoji-hash])
(when show-sign-profile?
[button/button
{:on-press on-press-sign
:type :community
:community-color (colors/custom-color customization-color 60)
:community-text-color colors/white
:style style/sign-button} sign-label])])
:style style/user-name} name]
(when key-card?
(icon/icon
:i/keycard
style/keycard-icon))]
(when show-user-hash?
[text/text
{:weight :monospace
:number-of-lines 1
:style style/user-hash} hash])
(when (and show-emoji-hash? emoji-hash)
[text/text
{:weight :monospace
:number-of-lines 1
:style style/emoji-hash} emoji-hash])]])
@@ -24,29 +24,31 @@
(let [internal-selected? (reagent/atom (or default-selected? false))]
(fn [{:keys [selected?
profile-picture
ring-background
name
customization-color
on-change]
:or {customization-color :turquoise}}]
(when (and (not (nil? selected?)) (not= @internal-selected? selected?))
(reset! internal-selected? selected?))
[rn/touchable-opacity
{:style (style/container customization-color @internal-selected?)
:on-press #(on-change-handler internal-selected? on-change)
:active-opacity 1
:accessibility-label :select-profile}
[rn/view {:style style/header}
[user-avatar/user-avatar
{:full-name name
:profile-picture profile-picture
:status-indicator? false
:ring? true
:size :medium}]
[rn/view {:style (style/select-radio @internal-selected?)}
(when @internal-selected? [rn/view {:style style/select-radio-inner}])]]
[text/text
{:size :heading-2
:weight :semi-bold
:style style/profile-name
} name]])))
(let [avatar-image-key (if profile-picture :profile-picture :ring-background)
picture (or profile-picture ring-background)]
(when (and (not (nil? selected?)) (not= @internal-selected? selected?))
(reset! internal-selected? selected?))
[rn/touchable-opacity
{:style (style/container customization-color @internal-selected?)
:on-press #(on-change-handler internal-selected? on-change)
:active-opacity 1
:accessibility-label :select-profile}
[rn/view {:style style/header}
[user-avatar/user-avatar
{:full-name name
:status-indicator? false
:size :medium
avatar-image-key picture}]
[rn/view {:style (style/select-radio @internal-selected?)}
(when @internal-selected? [rn/view {:style style/select-radio-inner}])]]
[text/text
{:size :heading-2
:weight :semi-bold
:style style/profile-name}
name]]))))
@@ -1,6 +1,6 @@
(ns quo2.components.record-audio.record-audio.--tests--.record-audio-component-spec
(:require [quo2.components.record-audio.record-audio.view :as record-audio]
[status-im.audio.core :as audio]
[react-native.audio-toolkit :as audio]
[test-helpers.component :as h]))
(h/describe "record audio component"
@@ -20,7 +20,9 @@
(h/test "record-audio on-start-recording works"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-start-recording event}])
(h/render [record-audio/record-audio
{:on-start-recording event
:record-audio-permission-granted true}])
(h/fire-event
:on-start-should-set-responder
(h/get-by-test-id "record-audio")
@@ -31,7 +33,9 @@
(h/test "record-audio on-reviewing-audio works"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-reviewing-audio event}])
(h/render [record-audio/record-audio
{:on-reviewing-audio event
:record-audio-permission-granted true}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))]
(h/fire-event
@@ -50,7 +54,9 @@
(h/test "record-audio on-send works after reviewing audio"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-send event}])
(h/render [record-audio/record-audio
{:on-send event
:record-audio-permission-granted true}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))
audio/get-recorder-file-path (fn [] "audio-file-path")]
@@ -77,7 +83,9 @@
(h/test "record-audio on-send works after sliding to the send button"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-send event}])
(h/render [record-audio/record-audio
{:on-send event
:record-audio-permission-granted true}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))
audio/stop-recording (fn [_ on-stop _]
@@ -108,7 +116,9 @@
(h/test "record-audio on-cancel works after reviewing audio"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-cancel event}])
(h/render [record-audio/record-audio
{:on-cancel event
:record-audio-permission-granted true}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))]
(h/fire-event
@@ -132,7 +142,9 @@
(h/test "cord-audio on-cancel works after sliding to the cancel button"
(let [event (js/jest.fn)]
(h/render [record-audio/record-audio {:on-cancel event}])
(h/render [record-audio/record-audio
{:on-cancel event
:record-audio-permission-granted true}])
(with-redefs [audio/start-recording (fn [_ on-start _]
(on-start))
audio/stop-recording (fn [_ on-stop _]
@@ -2,7 +2,7 @@
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear-with-delay
@@ -14,14 +14,14 @@
[recording? ready-to-delete? reviewing-audio?]
[:f>
(fn []
(let [opacity (reanimated/use-shared-value 0)
translate-x (reanimated/use-shared-value 20)
scale (reanimated/use-shared-value 1)
connector-opacity (reanimated/use-shared-value 0)
connector-width (reanimated/use-shared-value 24)
connector-height (reanimated/use-shared-value 12)
border-radius-first-half (reanimated/use-shared-value 8)
border-radius-second-half (reanimated/use-shared-value 8)
(let [opacity (ra/use-val 0)
translate-x (ra/use-val 20)
scale (ra/use-val 1)
connector-opacity (ra/use-val 0)
connector-width (ra/use-val 24)
connector-height (ra/use-val 12)
border-radius-first-half (ra/use-val 8)
border-radius-second-half (ra/use-val 8)
start-x-animation (fn []
(animate-linear-with-delay translate-x 12 50 133.33)
(animate-easing-with-delay connector-opacity 1 0 93.33)
@@ -73,14 +73,14 @@
(reset-x-animation)))
[@ready-to-delete?])
[:<>
[reanimated/view {:style (style/delete-button-container opacity)}
[reanimated/view
[ra/view {:style (style/delete-button-container opacity)}
[ra/view
{:style (style/delete-button-connector connector-opacity
connector-width
connector-height
border-radius-first-half
border-radius-second-half)}]]
[reanimated/view
[ra/view
{:style (style/delete-button scale translate-x opacity)
:pointer-events :none}
[icons/icon :i/delete
@@ -2,7 +2,7 @@
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear-with-delay
@@ -14,13 +14,13 @@
[recording? ready-to-lock? locked?]
[:f>
(fn []
(let [translate-x-y (reanimated/use-shared-value 20)
opacity (reanimated/use-shared-value 0)
connector-opacity (reanimated/use-shared-value 0)
width (reanimated/use-shared-value 24)
height (reanimated/use-shared-value 12)
border-radius-first-half (reanimated/use-shared-value 8)
border-radius-second-half (reanimated/use-shared-value 8)
(let [translate-x-y (ra/use-val 20)
opacity (ra/use-val 0)
connector-opacity (ra/use-val 0)
width (ra/use-val 24)
height (ra/use-val 12)
border-radius-first-half (ra/use-val 8)
border-radius-second-half (ra/use-val 8)
start-x-y-animation (fn []
(animate-linear-with-delay translate-x-y 8 50 116.66)
(animate-easing-with-delay connector-opacity 1 0 80)
@@ -70,14 +70,14 @@
(reset-x-y-animation)))
[@locked?])
[:<>
[reanimated/view {:style (style/lock-button-container opacity)}
[reanimated/view
[ra/view {:style (style/lock-button-container opacity)}
[ra/view
{:style (style/lock-button-connector connector-opacity
width
height
border-radius-first-half
border-radius-second-half)}]]
[reanimated/view
[ra/view
{:style (style/lock-button translate-x-y opacity)
:pointer-events :none}
[icons/icon (if @ready-to-lock? :i/locked :i/unlocked)
@@ -3,7 +3,7 @@
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.core :as rn :refer [use-effect]]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[quo2.components.buttons.button :as button]
[quo2.components.record-audio.record-audio.helpers :refer [set-value]]))
@@ -11,7 +11,7 @@
[recording? reviewing-audio?]
[:f>
(fn []
(let [opacity (reanimated/use-shared-value 1)
(let [opacity (ra/use-val 1)
show-animation #(set-value opacity 1)
hide-animation #(set-value opacity 0)]
(use-effect (fn []
@@ -19,7 +19,7 @@
(hide-animation)
(show-animation)))
[@recording? @reviewing-audio?])
[reanimated/view {:style (style/record-button-container opacity)}
[ra/view {:style (style/record-button-container opacity)}
[button/button
{:type :outline
:size 32
@@ -3,8 +3,8 @@
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.core :as rn :refer [use-effect]]
[react-native.reanimated :as reanimated]
[status-im.audio.core :as audio]
[react-native.reanimated :as ra]
[react-native.audio-toolkit :as audio]
[taoensso.timbre :as log]
[cljs-bean.core :as bean]
[reagent.core :as reagent]
@@ -37,7 +37,7 @@
(fn [props]
(let [{:keys [scale opacity color]} (bean/bean props)]
(reagent/as-element
[reanimated/view {:style (style/animated-circle scale opacity color)}]))))))
[ra/view {:style (style/animated-circle scale opacity color)}]))))))
(defn record-button-big
[recording? ready-to-send? ready-to-lock? ready-to-delete? record-button-is-animating?
@@ -45,29 +45,29 @@
clear-timeout touch-active? recorder-ref reload-recorder-fn idle? on-send on-cancel]
[:f>
(fn []
(let [scale (reanimated/use-shared-value 1)
opacity (reanimated/use-shared-value 0)
(let [scale (ra/use-val 1)
opacity (ra/use-val 0)
opacity-from (if @ready-to-lock? opacity-from-lock opacity-from-default)
animations (map
(fn [index]
(let [ring-scale (ring-scale scale (* scale-padding index))]
{:scale ring-scale
:opacity (reanimated/interpolate ring-scale
[1 scale-to-each]
[opacity-from 0])}))
:opacity (ra/interpolate ring-scale
[1 scale-to-each]
[opacity-from 0])}))
(range 0 5))
rings-color (cond
@ready-to-lock? (colors/theme-colors colors/neutral-80-opa-5-opaque
colors/neutral-80)
@ready-to-delete? colors/danger-50
:else colors/primary-50)
translate-y (reanimated/use-shared-value 0)
translate-x (reanimated/use-shared-value 0)
translate-y (ra/use-val 0)
translate-x (ra/use-val 0)
button-color colors/primary-50
icon-color (if (and (not (colors/dark?)) @ready-to-lock?) colors/black colors/white)
icon-opacity (reanimated/use-shared-value 1)
red-overlay-opacity (reanimated/use-shared-value 0)
gray-overlay-opacity (reanimated/use-shared-value 0)
icon-opacity (ra/use-val 1)
red-overlay-opacity (ra/use-val 0)
gray-overlay-opacity (ra/use-val 0)
complete-animation (fn []
(cond
(and @ready-to-lock? (not @record-button-is-animating?))
@@ -114,7 +114,7 @@
signal-anim-duration)))
stop-animation (fn []
(set-value opacity 0)
(reanimated/cancel-animation scale)
(ra/cancel-animation scale)
(set-value scale 1)
(when @clear-timeout (js/clearTimeout @clear-timeout)))
start-y-animation (fn []
@@ -190,7 +190,7 @@
(start-x-animation)
(reset-x-animation)))
[@ready-to-delete?])
[reanimated/view
[ra/view
{:style (style/record-button-big-container translate-x translate-y opacity)
:pointer-events :none}
[:<>
@@ -203,9 +203,9 @@
:color rings-color}])
animations)]
[rn/view {:style (style/record-button-big-body button-color)}
[reanimated/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}]
[reanimated/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}]
[reanimated/view {:style (style/record-button-big-icon-container icon-opacity)}
[ra/view {:style (style/record-button-big-red-overlay red-overlay-opacity)}]
[ra/view {:style (style/record-button-big-gray-overlay gray-overlay-opacity)}]
[ra/view {:style (style/record-button-big-icon-container icon-opacity)}
(if @locked?
[rn/view {:style style/stop-icon}]
[icons/icon :i/audio {:color icon-color}])]]]))])
@@ -2,7 +2,7 @@
(:require [quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[react-native.core :refer [use-effect]]
[quo2.components.record-audio.record-audio.helpers :refer
[animate-linear
@@ -14,13 +14,13 @@
[recording? ready-to-send? reviewing-audio?]
[:f>
(fn []
(let [opacity (reanimated/use-shared-value 0)
translate-y (reanimated/use-shared-value 20)
connector-opacity (reanimated/use-shared-value 0)
width (reanimated/use-shared-value 12)
height (reanimated/use-shared-value 24)
border-radius-first-half (reanimated/use-shared-value 16)
border-radius-second-half (reanimated/use-shared-value 8)
(let [opacity (ra/use-val 0)
translate-y (ra/use-val 20)
connector-opacity (ra/use-val 0)
width (ra/use-val 12)
height (ra/use-val 24)
border-radius-first-half (ra/use-val 16)
border-radius-second-half (ra/use-val 8)
start-y-animation (fn []
(animate-linear-with-delay translate-y 12 50 133.33)
(animate-easing-with-delay connector-opacity 1 0 93.33)
@@ -74,14 +74,14 @@
@recording? (reset-y-animation)))
[@ready-to-send?])
[:<>
[reanimated/view {:style (style/send-button-container opacity)}
[reanimated/view
[ra/view {:style (style/send-button-container opacity)}
[ra/view
{:style (style/send-button-connector connector-opacity
width
height
border-radius-first-half
border-radius-second-half)}]]
[reanimated/view
[ra/view
{:style (style/send-button translate-y opacity)
:pointer-events :none}
[icons/icon :i/arrow-up
@@ -1,9 +1,9 @@
(ns quo2.components.record-audio.record-audio.helpers
(:require [react-native.reanimated :as reanimated]))
(:require [react-native.reanimated :as ra]))
(defn animate-linear
[shared-value value duration]
(reanimated/animate-shared-value-with-timing
(ra/animate
shared-value
value
duration
@@ -11,26 +11,26 @@
(defn animate-linear-with-delay
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay
(ra/animate-delay
shared-value
value
delay
duration
:linear
delay))
:linear))
(defn animate-linear-with-delay-loop
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay-repeat
(ra/animate-delay-repeat
shared-value
value
duration
:linear
delay
-1))
-1
duration
:linear))
(defn animate-easing
[shared-value value duration]
(reanimated/animate-shared-value-with-timing
(ra/animate
shared-value
value
duration
@@ -38,13 +38,13 @@
(defn animate-easing-with-delay
[shared-value value duration delay]
(reanimated/animate-shared-value-with-delay
(ra/animate-delay
shared-value
value
delay
duration
:easing1
delay))
:easing1))
(defn set-value
[shared-value value]
(reanimated/set-shared-value shared-value value))
(ra/set-val shared-value value))
@@ -1,10 +1,10 @@
(ns quo2.components.record-audio.record-audio.style
(:require [quo2.foundations.colors :as colors]
[react-native.reanimated :as reanimated]))
[react-native.reanimated :as ra]))
(defn animated-circle
[scale opacity color]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:transform [{:scale scale}]
:opacity opacity}
{:width 56
@@ -19,7 +19,7 @@
(defn record-button-big-container
[translate-x translate-y opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:transform [{:translateY translate-y}
{:translateX translate-x}]
:opacity opacity}
@@ -44,7 +44,7 @@
(defn record-button-big-red-overlay
[red-overlay-opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity red-overlay-opacity}
{:position :absolute
:top 0
@@ -55,7 +55,7 @@
(defn record-button-big-gray-overlay
[gray-overlay-opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity gray-overlay-opacity}
{:position :absolute
:top 0
@@ -66,7 +66,7 @@
(defn record-button-big-icon-container
[icon-opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity icon-opacity}
{}))
@@ -78,7 +78,7 @@
(defn send-button-container
[opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity opacity}
{:justify-content :center
:align-items :center
@@ -90,7 +90,7 @@
(defn send-button-connector
[opacity width height border-radius-first-half border-radius-second-half]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity opacity
:width width
:height height
@@ -106,7 +106,7 @@
(defn send-button
[translate-y opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:transform [{:translateY translate-y}]
:opacity opacity}
{:justify-content :center
@@ -125,7 +125,7 @@
(defn lock-button-container
[opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity opacity}
{:transform [{:rotate "45deg"}]
:justify-content :center
@@ -138,7 +138,7 @@
(defn lock-button-connector
[opacity width height border-radius-first-half border-radius-second-half]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity opacity
:width width
:height height
@@ -154,7 +154,7 @@
(defn lock-button
[translate-x-y opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:transform [{:translateX translate-x-y}
{:translateY translate-x-y}]
:opacity opacity}
@@ -172,7 +172,7 @@
(defn delete-button-container
[opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity opacity}
{:justify-content :center
:align-items :center
@@ -184,7 +184,7 @@
(defn delete-button-connector
[opacity width height border-radius-first-half border-radius-second-half]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity opacity
:width width
:height height
@@ -200,7 +200,7 @@
(defn delete-button
[scale translate-x opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:transform [{:translateX translate-x}
{:scale scale}]
:opacity opacity}
@@ -217,7 +217,7 @@
(defn record-button-container
[opacity]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity opacity}
{:margin-bottom 32
:margin-right 32}))
@@ -1,19 +1,14 @@
(ns quo2.components.record-audio.record-audio.view
(:require [cljs-bean.core :as bean]
[oops.core :as oops]
(:require [oops.core :as oops]
[quo2.components.icon :as icons]
[quo2.components.record-audio.record-audio.style :as style]
[quo2.foundations.colors :as colors]
[quo2.components.record-audio.soundtrack.view :as soundtrack]
[react-native.core :as rn :refer [use-effect]]
[reagent.core :as reagent]
[status-im.utils.utils :as utils]
[quo2.components.markdown.text :as text]
[goog.string :as gstring]
[status-im.audio.core :as audio]
[utils.re-frame :as rf]
[utils.i18n :as i18n]
[react-native.permissions :as permissions]
[react-native.audio-toolkit :as audio]
[taoensso.timbre :as log]
[quo2.components.record-audio.record-audio.buttons.record-button-big :as record-button-big]
[quo2.components.record-audio.record-audio.buttons.send-button :as send-button]
@@ -154,7 +149,8 @@
{:color (colors/theme-colors colors/neutral-100 colors/white)}]]))])
(defn view
[{:keys [on-start-recording on-send on-cancel on-reviewing-audio]}]
[{:keys [on-start-recording on-send on-cancel on-reviewing-audio record-audio-permission-granted
on-request-record-audio-permission on-check-audio-permissions]}]
[:f>
(fn []
(let [recording? (reagent/atom false)
@@ -176,29 +172,8 @@
playing-timer (atom nil)
recorder-ref (atom nil)
player-ref (atom nil)
record-audio-permission-granted (atom true)
output-file (atom nil)
reached-max-duration? (atom false)
check-audio-permission
(fn []
(permissions/permission-granted?
:record-audio
#(reset! record-audio-permission-granted %)
#(reset! record-audio-permission-granted false)))
request-record-audio-permission
(fn []
(rf/dispatch
[:request-permissions
{:permissions [:record-audio]
:on-allowed
#(reset! record-audio-permission-granted true)
:on-denied
#(js/setTimeout
(fn []
(utils/show-popup
(i18n/label :t/audio-recorder-error)
(i18n/label :t/audio-recorder-permissions-error)))
50)}]))
destroy-player
(fn []
(audio/destroy-player @player-ref)
@@ -247,7 +222,7 @@
:ignore-max-x? false}
record-button-area)]
(when-not @reviewing-audio?
(if @record-audio-permission-granted
(if record-audio-permission-granted
(do
(when (not @idle?)
(reset! recording? pressed-record-button?))
@@ -294,8 +269,8 @@
#(log/error "[record-audio] start recording - error: " %))
(when on-start-recording
(on-start-recording))))
(request-record-audio-permission)))
(when @record-audio-permission-granted
(some-> on-request-record-audio-permission)))
(when record-audio-permission-granted
(reset! touch-active? true))))
(not @idle?))
on-responder-move
@@ -469,7 +444,7 @@
(reset! reached-max-duration? false)))]
(fn []
(use-effect (fn []
(check-audio-permission)
(some-> on-check-audio-permissions)
(reload-recorder)))
[rn/view
{:style style/bar-container}
@@ -515,14 +490,4 @@
on-cancel]
[record-button/record-button recording? reviewing-audio?]]])))])
(def record-audio
(reagent/adapt-react-class
(rn/memo
(fn [props]
(let [{:keys [onStartRecording onReviewingAudio onSend onCancel]} (bean/bean props)]
(reagent/as-element
[view
{:on-start-recording onStartRecording
:on-reviewing-audio onReviewingAudio
:on-send onSend
:on-cancel onCancel}]))))))
(def record-audio view)
@@ -2,7 +2,7 @@
(:require [quo2.components.record-audio.soundtrack.view :as soundtrack]
[test-helpers.component :as h]
[reagent.core :as reagent]
[status-im.audio.core :as audio]))
[react-native.audio-toolkit :as audio]))
(h/describe "soundtrack component"
(h/before-each
@@ -1,7 +1,7 @@
(ns quo2.components.record-audio.soundtrack.view
(:require [quo2.components.record-audio.soundtrack.style :as style]
[quo2.foundations.colors :as colors]
[status-im.audio.core :as audio]
[react-native.audio-toolkit :as audio]
[taoensso.timbre :as log]
[react-native.platform :as platform]
[react-native.slider :as slider]))
+14 -5
View File
@@ -2,7 +2,7 @@
(:require [react-native.core :as rn]))
(defn style-container
[size disabled border-color border-width background-color label type]
[size disabled border-color border-width background-color labelled? type]
(merge {:height size
:border-color border-color
:background-color background-color
@@ -12,14 +12,23 @@
:justify-content :center}
(when disabled
{:opacity 0.3})
(when (and (or (= type :icon) (= type :emoji)) (not label))
(when (and (or (= type :icon) (= type :emoji)) (not labelled?))
{:width size})))
(defn base-tag
[_]
(fn [{:keys [id size disabled? border-color border-width background-color on-press
accessibility-label labelled? type]
:or {size 32}} children]
(fn
[{:keys [id
size
disabled?
border-color
border-width
background-color
on-press
accessibility-label
type
labelled?]
:or {size 32}} children]
[rn/touchable-without-feedback
(merge {:disabled disabled?
:accessibility-label accessibility-label}
+26 -15
View File
@@ -27,7 +27,7 @@
:text-color {:style {:color colors/white}}}}})
(defn tag-resources
[size type resource icon-color label text-color labelled]
[size type resource icon-color label text-color labelled?]
[rn/view
{:style (merge {:flex-direction :row
:align-items :center
@@ -46,16 +46,14 @@
24 12)
:color icon-color}])
(when (= type :emoji)
[rn/image
{:source resource
:style (merge (case size
32 {:height 20
:width 20}
24 {:height 12
:width 12})
(when label
{:margin-right 4}))}])
(when labelled
[text/text
{:style {:margin-right 4}
:size (case size
32 :paragraph-1
24 :paragraph-2
nil)}
resource])
(when labelled?
[text/text
(merge {:size (case size
32 :paragraph-1
@@ -70,6 +68,7 @@
(defn tag
"opts
{:type :icon/:emoji/:label
:label string
:size 32/24
:on-press fn
:blurred? true/false
@@ -82,14 +81,26 @@
- `type` can be icon or emoji with or without a tag label
- `labelled` boolean: is true if tag has label else false"
[_ _]
(fn [{:keys [id on-press disabled? size resource active accessibility-label
label type labelled? blurred? icon-color]
:or {size 32}}]
(fn
[{:keys [id
on-press
disabled?
size
active
accessibility-label
label
resource
type
labelled?
blurred?
icon-color
override-theme]
:or {size 32}}]
(let [state (cond disabled? :disabled
active :active
:else :default)
{:keys [border-color blurred-border-color text-color]}
(get-in themes [(theme/get-theme) state])]
(get-in themes [(or override-theme (theme/get-theme)) state])]
[rn/view {:style {:align-items :center}}
[base-tag/base-tag
{:id id
+8 -5
View File
@@ -138,7 +138,9 @@
:blurred? blurred?
:icon-color icon-color
:disabled? disabled?
:label label
:label (if labelled?
label
(when (= type :label) label))
:type type
:labelled? labelled?
:on-press (fn [id]
@@ -150,17 +152,18 @@
:index index
:viewPosition 0.5}))
(when on-change
(on-change id)))}
label]])})])
(on-change id)))}]])})])
[rn/view {:style {:flex-direction :row}}
(for [{:keys [label id resource]} data]
(for [{:keys [id label resource]} data]
^{:key id}
[rn/view {:style {:margin-right 8}}
[tag/tag
(merge {:id id
:size size
:type type
:label (if labelled? label (when (= type :label) label))
:label (if labelled?
label
(when (= type :label) label))
:active (= id active-tab-id)
:disabled? disabled?
:blurred? blurred?

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