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
122 changed files with 10349 additions and 9087 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
@@ -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 -63
View File
@@ -1,82 +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
'' +
# TODO: Generalize this section to not repeat the same code.
(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; }
);
nodeps = {
sha1 = attrByPath [ "nodeps" "sha1" ] "" dep;
sha256 = attrByPath [ "nodeps" "sha256" ] "" dep;
};
nodeps-download = optionalString (nodeps.sha256 != "") (
fetchurl { url = "${url}-nodeps.jar"; inherit (nodeps) 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"
''}
${optionalString (nodeps-download != "") ''
ln -s "${nodeps-download}" "${dep.path}-nodeps.jar"
''}
${optionalString (nodeps.sha1 != "") ''
echo "${nodeps.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
'';
}
+8377 -7566
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -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.31.0/checker-qual-3.31.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
+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
+53 -73
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"
@@ -37,105 +35,87 @@ function match_repo_url() {
}
function pom_has_nodeps_jar() {
grep '<shadedClassifierName>nodeps</shadedClassifierName>' $1 \
2>&1 >/dev/null
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
# Some deps include nodeps JARs which include.
if pom_has_nodeps_jar "${POM_PATH}"; then
NODEPS_NIX_FETCH_OUT=$(nix_fetch "${OBJ_REL_URL}-nodeps.jar")
if [[ ${?} -eq 0 ]]; then
NODEPS_PATH=$(get_nix_path "${NODEPS_NIX_FETCH_OUT}")
NODEPS_SHA256=$(get_nix_sha "${NODEPS_NIX_FETCH_OUT}")
NODEPS_SHA1=$(get_sha1 "${NODEPS_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}\"
}";[[ -n "${NODEPS_SHA256}" ]] && echo -n ","
fi
if [[ -n "${NODEPS_SHA256}" ]]; then
echo -n "
\"nodeps\": {
\"sha1\": \"${NODEPS_SHA1}\",
\"sha256\": \"${NODEPS_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
+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()'
'')

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

Before

Width:  |  Height:  |  Size: 2.4 MiB

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

@@ -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]
@@ -27,7 +27,7 @@
(defn blur-view
[animation]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity animation}
{:position :absolute
:top 0
@@ -39,7 +39,7 @@
(defn entity-picture
[animation]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:width animation
:height animation}
{:transform [{:scale 1}]
@@ -54,7 +54,7 @@
(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}
{:position :absolute
@@ -66,9 +66,9 @@
(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 [{:translateX (reanimated/use-shared-value 64)} {:translateY y-animation}]
{:transform [{:translateX (ra/use-val 64)} {:translateY y-animation}]
:opacity opacity-animation}
{:position :absolute
:z-index 3}))
@@ -3,7 +3,7 @@
[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]
@@ -18,16 +18,16 @@
(defn interpolate
[value input-range output-range]
(reanimated/interpolate value
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"}))
(ra/interpolate value
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"}))
(defn scroll-handler
[event initial-y scroll-y]
(let [current-y (- (oops/oget event "nativeEvent.contentOffset.y") initial-y)]
(reanimated/set-shared-value scroll-y current-y)))
(ra/set-val scroll-y current-y)))
(defn header
[{:keys [theme-color display-picture-comp cover-uri title-comp]} top-inset scroll-y]
@@ -45,9 +45,9 @@
{:style {:width "100%"
:height cover-height}
:source {:uri cover-uri}}])
[reanimated/view {:style (style/header-bottom-part border-animation)}
[ra/view {:style (style/header-bottom-part border-animation)}
[title-comp]]
[reanimated/view {:style (style/entity-picture size-animation)}
[ra/view {:style (style/entity-picture size-animation)}
[display-picture-comp image-animation]]]))
(defn animated-header-list
@@ -64,7 +64,7 @@
initial-y (if platform/ios? (- (:top insets)) 0)]
[:f>
(fn []
(let [scroll-y (reanimated/use-shared-value initial-y)
(let [scroll-y (ra/use-val initial-y)
opacity-animation (interpolate scroll-y
[(* threshold 0.33) (* threshold 0.66)]
[0 1])
@@ -80,14 +80,14 @@
{:active-opacity 1
:style (style/button-container {:right 20})}
[quo/icon :i/options {:size 20 :color (colors/theme-colors colors/black colors/white)}]]
[reanimated/blur-view
[ra/blur-view
{:blurAmount 32
:blurType :light
:overlayColor (if platform/ios? colors/white-opa-70 :transparent)
:style (style/blur-view opacity-animation)}
[reanimated/view {:style (style/header-comp translate-animation title-opacity-animation)}
[ra/view {:style (style/header-comp translate-animation title-opacity-animation)}
[header-comp]]]
[reanimated/flat-list
[ra/flat-list
{:data [nil]
:render-fn main-comp
:key-fn str
@@ -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]
@@ -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])))
+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}
@@ -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
@@ -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,63 +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}]
[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])]])
@@ -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,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]
[react-native.audio-toolkit :as audio]
[taoensso.timbre :as log]
[cljs-bean.core :as bean]
@@ -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}))
+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?
+4
View File
@@ -30,6 +30,7 @@
quo2.components.icon
quo2.components.info.info-message
quo2.components.info.information-box
quo2.components.input.view
quo2.components.list-items.channel
quo2.components.list-items.menu-item
quo2.components.list-items.preview-list
@@ -139,6 +140,9 @@
(def drawer-buttons quo2.components.drawers.drawer-buttons.view/view)
(def permission-context quo2.components.drawers.permission-context.view/view)
;;;; INPUTS
(def input quo2.components.input.view/input)
;;;; LIST ITEMS
(def channel-list-item quo2.components.list-items.channel/list-item)
(def menu-item quo2.components.list-items.menu-item/menu-item)
+12 -4
View File
@@ -58,10 +58,6 @@
(def neutral-95 "#0D1625")
(def neutral-100 "#09101C")
;;Blur
(def neutral-5-opa-70 (alpha neutral-5 0.7))
(def neutral-90-opa-70 (alpha neutral-90 0.7))
;;80 with transparency
(def neutral-80-opa-5 (alpha neutral-80 0.05))
(def neutral-80-opa-10 (alpha neutral-80 0.1))
@@ -114,6 +110,14 @@
(def white-opa-90 (alpha white 0.9))
(def white-opa-95 (alpha white 0.95))
;;;;Blur
(def white-70-blur (alpha white 0.7))
(def neutral-5-opa-70-blur (alpha neutral-5 0.7))
(def neutral-80-opa-80-blur (alpha "#192438" 0.8))
(def neutral-90-opa-70-blur (alpha neutral-90 0.7))
(def neutral-95-opa-70-blur neutral-95-opa-70)
(def neutral-100-opa-70-blur neutral-100-opa-70)
;;;;Black
;;Solid
@@ -152,6 +156,10 @@
(def success-60-opa-40 (alpha success-60 0.4))
;;;;Danger
(def danger "#E95460")
;; Danger with transparency
(def danger-opa-40 (alpha danger 0.4))
;;Solid
(def danger-50 "#E65F5C")
+94 -98
View File
@@ -20,12 +20,13 @@
[react-native.flat-list :as rn-flat-list]
[utils.collection]))
;; Animations
(def slide-in-up-animation SlideInUp)
(def slide-out-up-animation SlideOutUp)
(def linear-transition LinearTransition)
;;; Constants
(def ^:const default-duration 300)
;; Animated Components
;;; Worklets
(def worklet-factory (js/require "../src/js/worklet_factory.js"))
;;; Animated Components
(def create-animated-component (comp reagent/adapt-react-class (.-createAnimatedComponent reanimated)))
(def view (reagent/adapt-react-class (.-View reanimated)))
@@ -34,18 +35,22 @@
(defn flat-list
[props]
[reanimated-flat-list (rn-flat-list/base-list-props props)])
(def touchable-opacity (create-animated-component (.-TouchableOpacity ^js rn)))
(def linear-gradient (create-animated-component LinearGradient))
(def fast-image (create-animated-component FastImage))
(def blur-view (create-animated-component (.-BlurView blur)))
;; Hooks
(def use-shared-value useSharedValue)
(def use-animated-style useAnimatedStyle)
;;; Easings
(def in-out (.-inOut ^js Easing))
(def bezier (.-bezier ^js Easing))
(def easings
{:default (in-out (.-quad ^js Easing))
:linear (bezier 0 0 1 1)
:easing1 (bezier 0.25 0.1 0.25 1)
:easing2 (bezier 0 0.3 0.6 0.9)
:easing3 (bezier 0.3 0.3 0.3 0.9)})
;; Animations
;;; Animations
(def with-timing withTiming)
(def with-delay withDelay)
(def with-spring withSpring)
@@ -53,112 +58,103 @@
(def key-frame Keyframe)
(def with-repeat withRepeat)
(def cancel-animation cancelAnimation)
(defn with-repeat-timing
[val reps reverse? duration easing]
(with-repeat
(with-timing val
(clj->js {:duration duration
:easing (get easings easing)}))
reps
reverse?))
;; Easings
(def bezier (.-bezier ^js Easing))
(def in-out
(.-inOut ^js Easing))
(def easings
{:linear (bezier 0 0 1 1)
:easing1 (bezier 0.25 0.1 0.25 1)
:easing2 (bezier 0 0.3 0.6 0.9)
:easing3 (bezier 0.3 0.3 0.3 0.9)})
;; Helper functions
(defn get-shared-value
;;; Hooks and Helpers
(def use-val useSharedValue)
(defn get-val
[anim]
(when anim
(.-value anim)))
(defn set-shared-value
(defn set-val
[anim val]
(when (and anim (some? val))
(set! (.-value anim) val)))
;; Worklets
(def worklet-factory (js/require "../src/js/worklet_factory.js"))
;;; Executing animation functions
(defn animate
([animation value]
(animate animation value default-duration :default))
([animation value duration]
(animate animation value duration :default))
([animation value duration easing]
(set-val animation
(with-timing value
(clj->js {:duration duration
:easing (get easings easing)})))))
(defn animate-spring
[animation val {:keys [damping mass stiffness]}]
(set-val animation
(with-spring val
(clj->js {:damping damping
:mass mass
:stiffness stiffness}))))
(defn animate-decay
([animation velocity]
(animate-decay animation velocity []))
([animation velocity clamp]
(set-val animation
(with-decay (clj->js {:velocity velocity
:clamp clamp})))))
(defn animate-delay
([animation val delay]
(animate-delay animation val delay default-duration :default))
([animation val delay duration]
(animate-delay animation val delay duration :default))
([animation val delay duration easing]
(set-val animation
(with-delay delay
(with-timing val
(clj->js {:duration duration
:easing (get easings easing)}))))))
(defn animate-repeat
([animation val reps]
(animate-repeat animation val reps false default-duration :default))
([animation val reps reverse?]
(animate-repeat animation val reps reverse? default-duration :default))
([animation val reps reverse? duration]
(animate-repeat animation val reps reverse? duration :default))
([animation val reps reverse? duration easing]
(set-val animation (with-repeat-timing val reps reverse? duration easing))))
(defn animate-delay-repeat
([animation val duration easing delay reps]
(animate-delay-repeat animation val duration easing delay reps false))
([animation val duration easing delay reps reverse?]
(set-val animation (with-delay delay (with-repeat-timing val reps reverse? duration easing)))))
(defn interpolate
([shared-value input-range output-range]
(interpolate shared-value input-range output-range nil))
([shared-value input-range output-range extrapolation]
([val input-range output-range]
(interpolate val input-range output-range nil))
([val input-range output-range extrapolation]
(.interpolateValue ^js worklet-factory
shared-value
val
(clj->js input-range)
(clj->js output-range)
(clj->js extrapolation))))
;;;; Component Animations
;;; Styling
(def use-animated-style useAnimatedStyle)
(defn apply-animations-to-style
[animations style]
(use-animated-style
(.applyAnimationsToStyle ^js worklet-factory (clj->js animations) (clj->js style))))
;; Animators
(defn animate-shared-value-with-timing
[anim val duration easing]
(set-shared-value anim
(with-timing val
(js-obj "duration" duration
"easing" (get easings easing)))))
(defn animate-shared-value-with-delay
[anim val duration easing delay]
(set-shared-value anim
(with-delay delay
(with-timing val
(js-obj "duration" duration
"easing" (get easings easing))))))
(defn animate-shared-value-with-delay-default-easing
[anim val duration delay]
(set-shared-value anim
(with-delay delay
(with-timing val
(js-obj "duration" duration
"easing" (in-out (.-quad ^js Easing)))))))
(defn animate-shared-value-with-repeat
[anim val duration easing number-of-repetitions reverse?]
(set-shared-value anim
(with-repeat (with-timing val
(js-obj "duration" duration
"easing" (get easings easing)))
number-of-repetitions
reverse?)))
(defn animate-shared-value-with-delay-repeat
([anim val duration easing delay number-of-repetitions]
(animate-shared-value-with-delay-repeat anim val duration easing delay number-of-repetitions false))
([anim val duration easing delay number-of-repetitions reverse?]
(set-shared-value anim
(with-delay delay
(with-repeat
(with-timing val
#js
{:duration duration
:easing (get easings easing)})
number-of-repetitions
reverse?)))))
(defn animate-shared-value-with-spring
[anim val {:keys [mass stiffness damping]}]
(set-shared-value anim
(with-spring val
(js-obj "mass" mass
"damping" damping
"stiffness" stiffness))))
(defn animate-shared-value-with-decay
[anim velocity clamp]
(set-shared-value anim
(with-decay (clj->js {:velocity velocity
:clamp clamp}))))
(defn with-timing-duration
[val duration]
(with-timing val
(clj->js {:duration duration
:easing (in-out (.-quad ^js Easing))})))
;;; Built-in Animations
(def slide-in-up-animation SlideInUp)
(def slide-out-up-animation SlideOutUp)
(def linear-transition LinearTransition)
+1 -2
View File
@@ -18,8 +18,7 @@
{:db (-> db
(assoc-in [:keycard :creating-backup?] backup-type))}
(when (:multiaccount db)
(navigation/change-tab :browser-stack)) ;; Profile tab - Currently browser tab is used for
;; profile
(navigation/navigate-to-cofx :my-profile nil))
(navigation/navigate-to-cofx :seed-phrase nil)))
(rf/defn recovery-card-pressed
+1 -1
View File
@@ -70,7 +70,7 @@
:status nil))
:hide-popover nil})
(when (:multiaccount db)
(navigation/change-tab :browser-stack)) ;; Profile tab - Currently browser tab is used for profile
(navigation/navigate-to-cofx :my-profile nil))
(when-not (:multiaccounts/login db)
(if (:popover/popover db)
(navigation/navigate-replace :keycard-pin nil)
+6 -4
View File
@@ -1,6 +1,7 @@
(ns status-im.multiaccounts.login.core
(:require
[clojure.string :as string]
[clojure.set :as set]
[re-frame.core :as re-frame]
[status-im.async-storage.core :as async-storage]
[status-im.communities.core :as communities]
@@ -43,8 +44,7 @@
[status-im2.navigation.events :as navigation]
[status-im2.common.log :as logging]
[taoensso.timbre :as log]
[utils.security.core :as security]
[status-im2.contexts.emoji-hash.events :as emoji-hash]))
[utils.security.core :as security]))
(re-frame/reg-fx
::initialize-communities-enabled
@@ -388,7 +388,10 @@
(let [{:networks/keys [current-network networks]
:as settings}
(data-store.settings/rpc->settings settings)
multiaccount (dissoc settings :networks/current-network :networks/networks)
multiaccount (-> settings
(dissoc :networks/current-network :networks/networks)
(set/rename-keys {:compressedKey :compressed-key
:emojiHash :emoji-hash}))
;;for some reason we save default networks in db, in case when we want to modify default-networks
;;for
;; existing accounts we have to merge them again into networks
@@ -472,7 +475,6 @@
(get-group-chat-invitations)
(multiaccounts/get-profile-picture)
(multiaccounts/switch-preview-privacy-mode-flag)
(emoji-hash/fetch-for-current-public-key)
(link-preview/request-link-preview-whitelist)
(visibility-status-updates-store/fetch-visibility-status-updates-rpc)
(switcher-cards-store/fetch-switcher-cards-rpc))))
-6
View File
@@ -481,12 +481,6 @@
(when (validators/valid-public-key? public-key)
(.generateAliasAsync ^js (status) public-key callback)))
(defn public-key->emoji-hash
"Generate an emoji hash from the multiaccount public key"
[public-key callback]
(when (validators/valid-public-key? public-key)
(.emojiHash ^js (status) public-key callback)))
(defn identicon
"Generate a icon based on a string, synchronously"
[seed]
+3 -2
View File
@@ -64,8 +64,9 @@
(let [own (new-chat.db/own-public-key? db public-key)]
(cond
(and public-key own)
{:shell/change-tab-fx :browser-stack ;; Profile tab - Currently browser tab is used for profile
:pop-to-root-fx :shell-stack}
(rf/merge cofx
{:pop-to-root-fx :shell-stack}
(navigation/navigate-to-cofx :my-profile nil))
(and public-key (not own))
(rf/merge cofx
@@ -25,7 +25,7 @@
[utils.datetime :as datetime]
[utils.re-frame :as rf]))
(def request-cooldown-ms (* 7 24 60 60 1000))
(def request-cooldown-ms (* 24 60 60 1000))
(defn can-request-access-again?
[requested-at]
@@ -1,47 +0,0 @@
(ns status-im.ui.screens.onboarding.intro.styles
(:require [quo.animated :as animated]
[quo.design-system.colors :as colors]))
(def dot-size 6)
(def progress-size 36)
(def intro-view
{:flex 1
:justify-content :flex-end
:margin-bottom 12})
(defn dot-selector
[]
{:flex-direction :row
:justify-content :space-between
:margin-bottom 16
:align-items :center})
(defn dot-style
[active]
{:background-color colors/blue-light
:overflow :hidden
:opacity 1
:margin-horizontal 2
:width (animated/mix active dot-size progress-size)
:height dot-size
:border-radius 3})
(defn dot-progress
[active progress]
{:background-color colors/blue
:height dot-size
:width progress-size
:opacity (animated/mix active 0 1)
:transform [{:translateX (animated/mix progress (- progress-size) 0)}]})
(defn wizard-text-with-height
[height]
(merge {:color colors/gray
:text-align :center}
(when-not (zero? height)
{:height height})))
(def wizard-title
{:margin-bottom 16
:text-align :center})
@@ -1,204 +0,0 @@
(ns status-im.ui.screens.onboarding.intro.views
(:require [quo.animated :as animated]
[quo.core :as quo]
[quo.design-system.colors :as colors]
[quo.design-system.typography :as typography]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[utils.i18n :as i18n]
[status-im.react-native.resources :as resources]
[status-im.ui.components.react :as react]
[status-im.ui.screens.onboarding.intro.styles :as styles]))
(defonce index (reagent/atom 0))
(defn code
[val]
^{:key val}
[animated/code {:exec val}])
(defn dot
[]
(let [active (animated/value 0)
active-transition (animated/with-timing-transition active {:duration 100})]
(fn [{:keys [selected progress]}]
[animated/view {:style (styles/dot-style active-transition)}
[code (animated/set active (if selected 1 0))]
[animated/view {:style (styles/dot-progress active-transition progress)}]])))
(defn dots-selector
[{:keys [n progress]}]
(let [selected @index]
[react/view {:style (styles/dot-selector)}
(for [i (range n)]
^{:key i}
[dot
{:progress progress
:selected (= selected i)}])]))
(defn slides-view
[slides width]
(let [height (reagent/atom 0)
text-height (reagent/atom 0)
text-temp-height (atom 0)
text-temp-timer (atom nil)]
(fn [_]
[:<>
(doall
(for [s slides]
^{:key (:title s)}
[react/view
{:style {:flex 1
:width width
:justify-content :flex-end
:align-items :center
:padding-horizontal 32}}
(let [size (min width @height)]
[react/view
{:style {:flex 1}
:on-layout (fn [^js e]
(let [new-height (-> e .-nativeEvent .-layout .-height)]
(swap! height #(if (pos? %) (min % new-height) new-height))))}
[react/image
{:source (:image s)
:resize-mode :contain
:style {:width size
:height size}}]])
[quo/text
{:style styles/wizard-title
:align :center
:weight :bold
:size :x-large}
(i18n/label (:title s))]
[quo/text
{:style (styles/wizard-text-with-height @text-height)
:on-layout
(fn [^js e]
(let [new-height (-> e .-nativeEvent .-layout .-height)]
(when (and (not= new-height @text-temp-height)
(not (zero? new-height))
(< new-height 200))
(swap! text-temp-height #(if (pos? %) (max % new-height) new-height))
(when @text-temp-timer (js/clearTimeout @text-temp-timer))
(reset! text-temp-timer
(js/setTimeout #(reset! text-height @text-temp-height) 500)))))}
(i18n/label (:text s))]]))])))
(defn carousel
[slides width]
;;TODO this is really not the best implementation, must be a better way
(let [scroll-x (reagent/atom 0)
scroll-view-ref (atom nil)
manual-scroll (atom false)
progress (animated/value 1)
autoscroll (animated/value 1)
finished (animated/value 0)
clock (animated/clock)
go-next (fn []
(let [x (if (>= @scroll-x
(- (* (dec (count slides))
width)
5))
0
(+ @scroll-x width))]
(reset! index (Math/round (/ x width)))
(some-> ^js @scroll-view-ref
(.scrollTo #js {:x x :animated true}))))
code (animated/block
[(animated/cond* (animated/and* (animated/not* (animated/clock-running clock))
autoscroll)
(animated/start-clock clock))
(animated/cond* (animated/and* (animated/clock-running clock)
(animated/not* autoscroll))
[(animated/stop-clock clock)
(animated/set finished 1)])
(animated/set progress
(animated/cancelable-loop
{:clock clock
:finished finished
:duration 4000
:on-reach go-next}))])
cancel-animation (fn []
(reset! manual-scroll true)
(animated/set-value autoscroll 0))
restart-animation (fn []
(animated/set-value autoscroll 1))]
(fn [_ _]
[react/view
{:style {:align-items :center
:flex 1
:justify-content :flex-end}}
[animated/code {:exec code}]
[react/scroll-view
{:horizontal true
:paging-enabled true
:ref #(reset! scroll-view-ref %)
:shows-vertical-scroll-indicator false
:shows-horizontal-scroll-indicator false
:pinch-gesture-enabled false
:scroll-event-throttle 16
:on-scroll #(let [x (.-nativeEvent.contentOffset.x ^js %)]
(when @manual-scroll
;; NOTE: Will be not synced if velocity is big
(reset! index (Math/round (/ x width))))
(reset! scroll-x x))
:on-scroll-begin-drag cancel-animation
:on-scroll-end-drag restart-animation
:on-momentum-scroll-end #(reset! manual-scroll false)
:style {:margin-bottom 16}}
[slides-view slides width]]
[dots-selector
{:progress progress
:n (count slides)}]])))
(defonce tos-accepted (reagent/atom false))
(defn intro
[]
[react/view {:style styles/intro-view}
[carousel
[{:image (resources/get-theme-image :chat)
:title :intro-title1
:text :intro-text1}
{:image (resources/get-theme-image :wallet)
:title :intro-title2
:text :intro-text2}
{:image (resources/get-theme-image :browser)
:title :intro-title3
:text :intro-text3}]
@(re-frame/subscribe [:dimensions/window-width])]
[react/view {:style {:align-items :center}}
[react/view
{:flex-direction :row
:justify-content :space-between
:align-items :center
:margin-top 36
:margin-bottom 24}
[quo/checkbox
{:value @tos-accepted
:on-change #(swap! tos-accepted not)}]
[rn/touchable-opacity {:test-ID :terms-of-service :on-press #(swap! tos-accepted not)}
[react/nested-text {:style {:margin-left 12}}
(i18n/label :t/accept-status-tos-prefix)
[{:style (merge {:color colors/blue}
typography/font-medium)
:on-press #(re-frame/dispatch [:open-modal :terms-of-service])
:accessibility-label :terms-of-service-link}
" "
(i18n/label :t/terms-of-service)]]]]
[react/view {:style {:margin-bottom 24}}
[quo/button
{:test-ID :get-started
:disabled (not @tos-accepted)
:on-press #(do (re-frame/dispatch [:init-root :onboarding])
;; clear atom state for next use
(reset! tos-accepted false)
(re-frame/dispatch [:hide-terms-of-services-opt-in-screen]))}
(i18n/label :t/get-started)]]
[react/text
{:style {:color colors/blue}
:on-press #(re-frame/dispatch [:open-modal :privacy-policy])
:accessibility-label :privacy-policy-link}
(i18n/label :t/privacy-policy)]]])
-6
View File
@@ -60,7 +60,6 @@
[status-im.ui.screens.notifications-settings.views :as notifications-settings]
[status-im.ui.screens.offline-messaging-settings.edit-mailserver.views :as edit-mailserver]
[status-im.ui.screens.offline-messaging-settings.views :as offline-messaging-settings]
[status-im.ui.screens.onboarding.intro.views :as onboarding.intro]
[status-im.ui.screens.onboarding.keys.views :as onboarding.keys]
[status-im.ui.screens.onboarding.notifications.views :as onboarding.notifications]
[status-im.ui.screens.onboarding.password.views :as onboarding.password]
@@ -130,11 +129,6 @@
{:name :progress
:component progress/progress}
;[Onboarding]
{:name :intro
:insets {:bottom true}
:component onboarding.intro/intro}
;[Onboarding]
{:name :get-your-keys
:insets {:bottom true}
@@ -4,7 +4,7 @@
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[status-im.ui2.screens.chat.pin-limit-popover.style :as style]
[utils.re-frame :as rf]))
@@ -16,17 +16,17 @@
(fn []
(let [width (rf/sub [:dimensions/window-width])
show-pin-limit-modal? (rf/sub [:chats/pin-modal chat-id])
opacity-animation (reanimated/use-shared-value 0)
z-index-animation (reanimated/use-shared-value -1)]
opacity-animation (ra/use-val 0)
z-index-animation (ra/use-val -1)]
(react/effect!
#(do
(reanimated/set-shared-value opacity-animation
(reanimated/with-timing (if show-pin-limit-modal? 1 0)))
(reanimated/set-shared-value z-index-animation
(reanimated/with-timing (if show-pin-limit-modal? 10 -1)))))
(ra/set-val opacity-animation
(ra/with-timing (if show-pin-limit-modal? 1 0)))
(ra/set-val z-index-animation
(ra/with-timing (if show-pin-limit-modal? 10 -1)))))
(when show-pin-limit-modal?
[reanimated/view
{:style (reanimated/apply-animations-to-style
[ra/view
{:style (ra/apply-animations-to-style
{:opacity opacity-animation
:z-index z-index-animation}
(style/pin-popover width))
@@ -109,8 +109,9 @@
(log/info "universal-links: handling view profile" public-key)
(cond
(and public-key (new-chat.db/own-public-key? db public-key))
{:shell/change-tab-fx :browser-stack ;; Profile tab - Currently browser tab is used for profile
:pop-to-root-fx :shell-stack}
(rf/merge cofx
{:pop-to-root-fx :shell-stack}
(navigation/navigate-to-cofx :my-profile nil))
public-key
{:dispatch [:chat.ui/show-profile public-key ens-name]}))
+23 -23
View File
@@ -8,7 +8,7 @@
[react-native.gesture :as gesture]
[react-native.hooks :as hooks]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]))
@@ -18,7 +18,7 @@
(defn with-animation
[value & [options callback]]
(reanimated/with-spring
(ra/with-spring
value
(clj->js (merge {:mass 2
:stiffness 500
@@ -45,12 +45,12 @@
max-pan-down (if @expanded?
bg-height-expanded
bg-height)]
(reanimated/set-shared-value pan-y
(max
(min
(.-translationY evt)
max-pan-down)
max-pan-up))))))
(ra/set-val pan-y
(max
(min
(.-translationY evt)
max-pan-down)
max-pan-up))))))
(gesture/on-end
(fn [_]
(reset! gesture-running? false)
@@ -127,8 +127,8 @@
{:keys [keyboard-shown]} (hooks/use-keyboard)
bg-height-expanded (- window-height (:top insets))
bg-height (max (min @content-height bg-height-expanded) 109)
bottom-sheet-dy (reanimated/use-shared-value 0)
pan-y (reanimated/use-shared-value 0)
bottom-sheet-dy (ra/use-val 0)
pan-y (ra/use-val 0)
translate-y (.useTranslateY ^js bottom-sheet-js window-height bottom-sheet-dy pan-y)
bg-opacity
(.useBackgroundOpacity ^js bottom-sheet-js translate-y bg-height window-height)
@@ -136,11 +136,11 @@
(let [height (oget evt "nativeEvent" "layout" "height")]
(reset! content-height height)))
on-expanded (fn []
(reanimated/set-shared-value bottom-sheet-dy bg-height-expanded)
(reanimated/set-shared-value pan-y 0))
(ra/set-val bottom-sheet-dy bg-height-expanded)
(ra/set-val pan-y 0))
on-collapsed (fn []
(reanimated/set-shared-value bottom-sheet-dy bg-height)
(reanimated/set-shared-value pan-y 0))
(ra/set-val bottom-sheet-dy bg-height)
(ra/set-val pan-y 0))
bottom-sheet-gesture (get-bottom-sheet-gesture
pan-y
translate-y
@@ -185,38 +185,38 @@
@show-bottom-sheet?
(if @expanded?
(do
(reanimated/set-shared-value
(ra/set-val
bottom-sheet-dy
(with-animation (+ bg-height-expanded (.-value pan-y))))
;; Workaround for
;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741
;; https://github.com/software-mansion/react-native-ra/issues/1758#issue-817145741
;; withTiming/withSpring callback not working
;; on-expanded should be called as a callback of
;; with-animation instead, once this issue has been resolved
(timer/set-timeout on-expanded animation-delay))
(do
(reanimated/set-shared-value
(ra/set-val
bottom-sheet-dy
(with-animation (+ bg-height (.-value pan-y))))
;; Workaround for
;; https://github.com/software-mansion/react-native-reanimated/issues/1758#issue-817145741
;; https://github.com/software-mansion/react-native-ra/issues/1758#issue-817145741
;; withTiming/withSpring callback not working
;; on-collapsed should be called as a callback of
;; with-animation instead, once this issue has been resolved
(timer/set-timeout on-collapsed animation-delay)))
(= @show-bottom-sheet? false)
(reanimated/set-shared-value bottom-sheet-dy (with-animation 0)))))
(ra/set-val bottom-sheet-dy (with-animation 0)))))
[@show-bottom-sheet? @expanded? @gesture-running?])
[:<>
[rn/touchable-without-feedback {:on-press (when backdrop-dismiss? close-bottom-sheet)}
[reanimated/view
{:style (reanimated/apply-animations-to-style
[ra/view
{:style (ra/apply-animations-to-style
{:opacity bg-opacity}
styles/backdrop)}]]
(cond->> [reanimated/view
{:style (reanimated/apply-animations-to-style
(cond->> [ra/view
{:style (ra/apply-animations-to-style
{:transform [{:translateY translate-y}]}
{:width window-width
:height window-height})}
+6 -1
View File
@@ -2,10 +2,15 @@
(def ui
{:add-new-contact (js/require "../resources/images/ui2/add-contact.png")
:intro-1 (js/require "../resources/images/ui2/intro-1.png")
:intro-2 (js/require "../resources/images/ui2/intro-2.png")
:intro-3 (js/require "../resources/images/ui2/intro-3.png")
:intro-4 (js/require "../resources/images/ui2/intro-4.png")
:lifestyle (js/require "../resources/images/ui2/lifestyle.png")
:music (js/require "../resources/images/ui2/music.png")
:podcasts (js/require "../resources/images/ui2/podcasts.png")
:sync-device (js/require "../resources/images/ui2/sync-new-device-cover-background.png")})
:sync-device (js/require "../resources/images/ui2/sync-new-device-cover-background.png")
:onboarding-bg-1 (js/require "../resources/images/ui2/onboarding-bg-1.png")})
(def mock-images
{:coinbase (js/require "../resources/images/mock2/coinbase.png")
+4 -4
View File
@@ -1,7 +1,7 @@
(ns status-im2.common.scroll-page.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]))
[react-native.reanimated :as ra]))
(defn image-slider
[size]
@@ -13,7 +13,7 @@
(defn blur-slider
[animation height]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:transform [{:translateY animation}]}
{:z-index 5
:position :absolute
@@ -39,7 +39,7 @@
(defn sticky-header-title
[animation]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:opacity animation}
{:position :absolute
:flex-direction :row
@@ -57,7 +57,7 @@
(defn display-picture-container
[animation]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:transform [{:scale animation}]}
{:border-radius 50
:border-width 1
+28 -27
View File
@@ -7,7 +7,7 @@
[reagent.core :as reagent]
[status-im2.common.scroll-page.style :as style]
[utils.re-frame :as rf]
[react-native.reanimated :as reanimated]))
[react-native.reanimated :as ra]))
(defn icon-color
[]
@@ -31,30 +31,30 @@
height
name
page-nav
cover
logo
sticky-header
top-nav
title-colum
navigate-back?]
(let [input-range (if platform/ios? [-47 10] [0 10])
output-range (if platform/ios? [-208 0] [-208 -45])
y (reanimated/use-shared-value scroll-height)
translate-animation (reanimated/interpolate y
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})
opacity-animation (reanimated/use-shared-value 0)
y (ra/use-val scroll-height)
translate-animation (ra/interpolate y
input-range
output-range
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})
opacity-animation (ra/use-val 0)
threshold (if platform/ios? 30 170)]
(rn/use-effect
#(do
(reanimated/set-shared-value y scroll-height)
(reanimated/set-shared-value opacity-animation
(reanimated/with-timing (if (>= scroll-height threshold) 1 0)
(clj->js {:duration 300}))))
(ra/set-val y scroll-height)
(ra/set-val opacity-animation
(ra/with-timing (if (>= scroll-height threshold) 1 0)
(clj->js {:duration 300}))))
[scroll-height])
[:<>
[reanimated/blur-view
[ra/blur-view
{:blur-amount 20
:blur-type :transparent
:overlay-color :transparent
@@ -65,11 +65,11 @@
:top 0
:left 0
:right 0}}
(when cover
[reanimated/view
(when logo
[ra/view
{:style (style/sticky-header-title opacity-animation)}
[rn/image
{:source cover
{:source logo
:style style/sticky-header-image}]
[quo/text
{:size :paragraph-1
@@ -101,17 +101,17 @@
(defn display-picture
[scroll-height cover]
(let [input-range (if platform/ios? [-67 10] [0 150])
y (reanimated/use-shared-value scroll-height)
animation (reanimated/interpolate y
input-range
[1.2 0.5]
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})]
y (ra/use-val scroll-height)
animation (ra/interpolate y
input-range
[1.2 0.5]
{:extrapolateLeft "clamp"
:extrapolateRight "clamp"})]
(rn/use-effect #(do
(reanimated/set-shared-value y scroll-height)
(ra/set-val y scroll-height)
js/undefined)
[scroll-height])
[reanimated/view
[ra/view
{:style (style/display-picture-container animation)}
[rn/image
{:source cover
@@ -122,6 +122,7 @@
(let [scroll-height (reagent/atom negative-scroll-position-0)]
(fn
[{:keys [cover-image
logo
page-nav-right-section-buttons
name
on-scroll
@@ -134,7 +135,7 @@
children]
[:<>
[:f> scroll-page-header @scroll-height height name page-nav-right-section-buttons
cover-image sticky-header top-nav title-colum navigate-back?]
logo sticky-header top-nav title-colum navigate-back?]
[rn/scroll-view
{:content-container-style (style/scroll-view-container
(diff-with-max-min @scroll-height 16 0))
@@ -162,5 +163,5 @@
:border-radius (diff-with-max-min @scroll-height 16 0)
:background-color background-color}
(when cover-image
[:f> display-picture @scroll-height cover-image])
[:f> display-picture @scroll-height logo])
children])]])))
+17 -17
View File
@@ -2,26 +2,26 @@
(:require [quo2.core :as quo]
[react-native.core :as rn]
[react-native.gesture :as gesture]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[reagent.core :as reagent]
[status-im.utils.utils :as utils.utils]
[status-im2.common.toasts.style :as style]
[utils.re-frame :as rf]))
;; (def ^:private slide-out-up-animation
;; (-> ^js reanimated/slide-out-up-animation
;; (-> ^js ra/slide-out-up-animation
;; .springify
;; (.damping 20)
;; (.stiffness 300)))
;; (def ^:private slide-in-up-animation
;; (-> ^js reanimated/slide-in-up-animation
;; (-> ^js ra/slide-in-up-animation
;; .springify
;; (.damping 20)
;; (.stiffness 300)))
;; (def ^:private linear-transition
;; (-> ^js reanimated/linear-transition
;; (-> ^js ra/linear-transition
;; .springify
;; (.damping 20)
;; (.stiffness 300)))
@@ -44,7 +44,7 @@
on-dismissed #((or (rf/sub [:toasts/toast-cursor id :on-dismissed]) identity) id)
create-timer (fn []
(reset! timer (utils.utils/set-timeout close! duration)))
translate-y (reanimated/use-shared-value 0)
translate-y (ra/use-val 0)
pan
(->
(gesture/gesture-pan)
@@ -56,38 +56,38 @@
(cond
;; reset translate y on pan down
(> evt-translation-y 100)
(reanimated/animate-shared-value-with-spring translate-y
0
{:mass 1
:damping 20
:stiffness 300})
(ra/animate-spring translate-y
0
{:mass 1
:damping 20
:stiffness 300})
;; dismiss on pan up
(< evt-translation-y -30)
(do (reanimated/animate-shared-value-with-spring
(do (ra/animate-spring
translate-y
-500
{:mass 1 :damping 20 :stiffness 300})
(reset! dismissed-locally? true)
(close!))
:else
(reanimated/set-shared-value translate-y
evt-translation-y)))))
(ra/set-val translate-y
evt-translation-y)))))
(gesture/on-end (fn [_]
(when-not @dismissed-locally?
(reanimated/set-shared-value translate-y 0)
(ra/set-val translate-y 0)
(create-timer)))))]
;; create auto dismiss timer, clear timer when unmount or duration changed
(rn/use-effect (fn [] (create-timer) clear-timer) [duration])
(rn/use-unmount on-dismissed)
[gesture/gesture-detector {:gesture pan}
[reanimated/view
[ra/view
{;; TODO: this will eanble layout animation at runtime and causing flicker on android
;; we need to resolve this and re-enable layout animation
;; issue at https://github.com/status-im/status-mobile/issues/14752
;; :entering slide-in-up-animation
;; :exiting slide-out-up-animation
;; :layout reanimated/linear-transition
:style (reanimated/apply-animations-to-style
;; :layout ra/linear-transition
:style (ra/apply-animations-to-style
{:transform [{:translateY translate-y}]}
style/each-toast-container)}
[toast id]]]))])))
+3 -3
View File
@@ -215,9 +215,9 @@
(def album-image-sizes ; sometimes we subtract 1 or 0.5 for padding
{2 {0 image-size
1 image-size}
3 {0 [(* image-size 2) (* image-size 1.5)]
1 [(- image-size 0.5) (- (* image-size 0.67) 1)]
2 [(- image-size 0.5) (- (* image-size 0.67) 1)]}
3 {0 [(* image-size 2) (* image-size 1.25)]
1 [(- image-size 0.5) (- (* image-size 0.75) 1)]
2 [(- image-size 0.5) (- (* image-size 0.75) 1)]}
4 {0 image-size
1 image-size
2 image-size
@@ -1,6 +1,8 @@
(ns status-im2.contexts.activity-center.notification.admin.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[status-im2.constants :as constants]
[status-im2.contexts.activity-center.notification.common.style :as style]
[status-im2.contexts.activity-center.notification.common.view :as common]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
@@ -36,7 +38,11 @@
:context [[common/user-avatar-tag author]
(i18n/label :t/wants-to-join)
[quo/context-tag
common/tag-params
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/user-avatar-tag
:text-style style/user-avatar-tag-text}
{:uri community-image} community-name]]
:items (case membership-status
constants/activity-center-membership-status-accepted
@@ -4,10 +4,10 @@
(def swipe-action-width 72)
(def swipe-button-border-radius 16)
(def tag
(def user-avatar-tag
{:background-color colors/white-opa-10})
(def tag-text
(def user-avatar-tag-text
{:color colors/white})
(def left-swipe-opacity-interpolation-js
@@ -8,17 +8,15 @@
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def tag-params
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/tag
:text-style style/tag-text})
(defn user-avatar-tag
[user-id]
(let [contact (rf/sub [:contacts/contact-by-identity user-id])]
[quo/user-avatar-tag tag-params
[quo/user-avatar-tag
{:color :purple
:override-theme :dark
:size :small
:style style/user-avatar-tag
:text-style style/user-avatar-tag-text}
(:primary-name contact)
(multiaccounts/displayed-photo contact)]))
@@ -1,50 +0,0 @@
(ns status-im2.contexts.activity-center.notification.community-request.view
(:require [quo2.core :as quo]
[status-im2.constants :as constants]
[status-im2.contexts.activity-center.notification.common.style :as common-style]
[status-im2.contexts.activity-center.notification.common.view :as common]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn- get-header-text-and-context
[community membership-status timestamp]
(let [community-name (:name community)
community-image (get-in community [:images :thumbnail :uri])
community-context-tag [quo/context-tag common/tag-params {:uri community-image}
community-name]
requested-within-a-week? (datetime/within-last-n-days? (datetime/to-date timestamp) 7)]
(cond
(= membership-status constants/activity-center-membership-status-pending)
(if requested-within-a-week?
{:header-text (i18n/label :t/community-request-pending)
:context [[quo/text {:style common-style/tag-text}
(i18n/label :t/community-request-pending-body-text)]
community-context-tag]}
{:header-text (i18n/label :t/community-request-not-accepted)
:context [[quo/text {:style common-style/tag-text}
(i18n/label :t/community-request-not-accepted-body-text-prefix)]
community-context-tag
[quo/text {:style common-style/tag-text}
(i18n/label :t/community-request-not-accepted-body-text-suffix)]]})
(= membership-status constants/activity-center-membership-status-accepted)
{:header-text (i18n/label :t/community-request-accepted)
:context [[quo/text {:style common-style/tag-text}
(i18n/label :t/community-request-accepted-body-text)]
community-context-tag]}
:else nil)))
(defn view
[{:keys [community-id membership-status read timestamp]}]
(let [community (rf/sub [:communities/community community-id])
{:keys [header-text context]} (get-header-text-and-context community
membership-status
timestamp)]
[quo/activity-log
{:title header-text
:icon :i/communities
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context context}]))
@@ -1,6 +1,12 @@
(ns status-im2.contexts.activity-center.notification.mentions.style
(:require [quo2.foundations.colors :as colors]))
(def tag
{:background-color colors/white-opa-10})
(def tag-text
{:color colors/white})
(def mention-text
{:color colors/white
:border-radius 6
@@ -1,21 +1,28 @@
(ns status-im2.contexts.activity-center.notification.mentions.view
(:require [clojure.string :as string]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.gesture :as gesture]
[status-im2.contexts.activity-center.notification.common.view :as common]
[status-im2.contexts.activity-center.notification.common.style :as common-style]
[status-im2.contexts.activity-center.notification.mentions.style :as style]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def tag-params
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/tag
:text-style style/tag-text})
(defn message-body
[message]
(let [parsed-text (get-in message [:content :parsed-text])
parsed-text-children (:children (first parsed-text))]
(into [quo/text
{:number-of-lines 1
:style common-style/tag-text
:style style/tag-text
:accessibility-label :activity-message-body
:size :paragraph-1}]
(map-indexed (fn [index {:keys [type literal]}]
@@ -57,8 +64,8 @@
:timestamp (datetime/timestamp->relative timestamp)
:unread? (not read)
:context [[common/user-avatar-tag author]
[quo/text {:style common-style/tag-text} (string/lower-case (i18n/label :t/on))]
[quo/text {:style style/tag-text} (string/lower-case (i18n/label :t/on))]
(if community-chat?
[quo/context-tag common/tag-params {:uri community-image} community-name chat-name]
[quo/group-avatar-tag chat-name common/tag-params])]
[quo/context-tag tag-params {:uri community-image} community-name chat-name]
[quo/group-avatar-tag chat-name tag-params])]
:message {:body (message-body message)}}]]))
@@ -1,6 +1,12 @@
(ns status-im2.contexts.activity-center.notification.reply.style
(:require [quo2.foundations.colors :as colors]))
(def tag
{:background-color colors/white-opa-10})
(def tag-text
{:color colors/white})
(def lowercase-text
{:color colors/white
:text-transform :lowercase})
@@ -1,17 +1,24 @@
(ns status-im2.contexts.activity-center.notification.reply.view
(:require [clojure.string :as string]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[react-native.gesture :as gesture]
[status-im.ui2.screens.chat.messages.message :as old-message]
[status-im2.common.not-implemented :as not-implemented]
[status-im2.constants :as constants]
[status-im2.contexts.activity-center.notification.common.view :as common]
[status-im2.contexts.activity-center.notification.common.style :as common-style]
[status-im2.contexts.activity-center.notification.reply.style :as style]
[utils.datetime :as datetime]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(def tag-params
{:size :small
:override-theme :dark
:color colors/primary-50
:style style/tag
:text-style style/tag-text})
;; NOTE: Replies support text, image and stickers only.
(defn get-message-content
[{:keys [content-type] :as message}]
@@ -25,7 +32,7 @@
;; NOTE: The following type (system-text) doesn't have a design yet.
;; https://github.com/status-im/status-mobile/issues/14915
constants/content-type-system-text [not-implemented/not-implemented
[quo/text {:style common-style/tag-text}
[quo/text {:style style/tag-text}
(get-in message [:content :text])]]
nil))
@@ -61,7 +68,7 @@
:context [[common/user-avatar-tag author]
[quo/text {:style style/lowercase-text} (i18n/label :t/on)]
(if community-chat?
[quo/context-tag common/tag-params {:uri community-image} community-name chat-name]
[quo/group-avatar-tag chat-name common/tag-params])]
[quo/context-tag tag-params {:uri community-image} community-name chat-name]
[quo/group-avatar-tag chat-name tag-params])]
:message {:body-number-of-lines 1
:body (get-message-content message)}}]]))
@@ -6,7 +6,6 @@
(def ^:const mention 3)
(def ^:const reply 4)
(def ^:const contact-request 5)
(def ^:const community-request 7)
(def ^:const admin 8)
(def ^:const contact-verification 10)
@@ -16,7 +15,6 @@
mention
reply
contact-request
community-request
admin
contact-verification})
@@ -28,5 +26,4 @@
"Membership is like a logical group of notifications with different types, i.e.
it doesn't have a corresponding type in the backend. Think of the collection
as a composite key of actual types."
#{private-group-chat
community-request})
#{private-group-chat})
@@ -12,8 +12,6 @@
[status-im2.contexts.activity-center.notification.membership.view :as membership]
[status-im2.contexts.activity-center.notification.mentions.view :as mentions]
[status-im2.contexts.activity-center.notification.reply.view :as reply]
[status-im2.contexts.activity-center.notification.community-request.view :as
community-request]
[status-im2.contexts.activity-center.style :as style]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
@@ -198,12 +196,7 @@
[admin/view notification set-swipeable-height]]
(some types/membership [type])
(case type
types/private-group-chat [membership/view notification]
types/community-request [community-request/view notification]
nil)
[membership/view notification]
:else
nil)]))))
+5
View File
@@ -353,3 +353,8 @@
[{:keys [db]} value]
{:db (assoc db :lightbox/orientation value)})
(rf/defn lightbox-scale
{:events [:chat.ui/lightbox-scale]}
[{:keys [db]} value]
{:db (assoc db :lightbox/scale value)})
@@ -2,10 +2,9 @@
(:require
[react-native.core :as rn]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[status-im2.contexts.chat.lightbox.style :as style]
[utils.re-frame :as rf]
[status-im2.contexts.chat.lightbox.common :as common]))
[utils.re-frame :as rf]))
(def small-image-size 40)
@@ -25,10 +24,10 @@
[:f>
(fn []
(let [size (if (= @scroll-index index) focused-image-size small-image-size)
size-value (common/use-val size)
size-value (ra/use-val size)
{:keys [scroll-index-lock? small-list-ref
flat-list-ref]} atoms]
(common/set-val-timing size-value size)
(ra/animate size-value size)
[rn/touchable-opacity
{:active-opacity 1
:on-press (fn []
@@ -44,11 +43,11 @@
#js {:animated true :index index}))
(if platform/ios? 50 150))
(rf/dispatch [:chat.ui/update-shared-element-id (:message-id item)]))}
[reanimated/fast-image
[ra/fast-image
{:source {:uri (:image (:content item))}
:style (reanimated/apply-animations-to-style {:width size-value
:height size-value}
{:border-radius 10})}]]))])
:style (ra/apply-animations-to-style {:width size-value
:height size-value}
{:border-radius 10})}]]))])
(defn bottom-view
[messages index scroll-index insets animations item-width atoms]
@@ -56,23 +55,25 @@
(fn []
(let [text (get-in (first messages) [:content :text])
padding-horizontal (- (/ item-width 2) (/ focused-image-size 2))]
[reanimated/linear-gradient
[ra/linear-gradient
{:colors [:black :transparent]
:start {:x 0 :y 1}
:end {:x 0 :y 0}
:style (style/gradient-container insets animations)}
[rn/text
{:style style/text-style} text]
(when (not= text "placeholder")
[rn/text {:style style/text-style} text])
[rn/flat-list
{:ref #(reset! (:small-list-ref atoms) %)
:key-fn :message-id
:style {:height small-list-height}
:data messages
:render-fn small-image
:render-data {:scroll-index scroll-index
:atoms atoms}
:horizontal true
:get-item-layout get-small-item-layout
:separator [rn/view {:style {:width 8}}]
:initial-scroll-index index
:content-container-style (style/content-container padding-horizontal)}]]))])
{:ref #(reset! (:small-list-ref atoms) %)
:key-fn :message-id
:style {:height small-list-height}
:data messages
:render-fn small-image
:render-data {:scroll-index scroll-index
:atoms atoms}
:horizontal true
:shows-horizontal-scroll-indicator false
:get-item-layout get-small-item-layout
:separator [rn/view {:style {:width 8}}]
:initial-scroll-index index
:content-container-style (style/content-container padding-horizontal)}]]))])
@@ -1,14 +0,0 @@
(ns status-im2.contexts.chat.lightbox.common
(:require [react-native.reanimated :as reanimated]))
(def top-view-height 56)
;; TODO: Abstract Reanimated methods in a better way, issue:
;; https://github.com/status-im/status-mobile/issues/15176
(defn set-val-timing
[animation value]
(reanimated/set-shared-value animation (reanimated/with-timing value)))
(defn use-val
[value]
(reanimated/use-shared-value value))
@@ -1,8 +1,7 @@
(ns status-im2.contexts.chat.lightbox.style
(:require [quo2.foundations.colors :as colors]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.lightbox.common :as common]))
[react-native.reanimated :as ra]))
;;;; MAIN-VIEW
(def container-view
@@ -10,24 +9,25 @@
;;;; TOP-VIEW
(defn top-view-container
[top-inset {:keys [opacity rotate top-view-y top-view-x top-view-width top-view-bg]} window-width
[top-inset {:keys [opacity rotate top-view-y top-view-x top-view-width top-view-bg top-layout]}
window-width
bg-color]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
(if platform/ios?
{:transform [{:rotate rotate}
{:transform [{:translateY top-layout}
{:rotate rotate}
{:translateY top-view-y}
{:translateX top-view-x}]
:opacity opacity
:width top-view-width
:background-color top-view-bg}
{:transform [{:rotate rotate}
{:translateY top-view-y}
{:translateX top-view-x}]
{:transform [{:translateY top-layout}]
:opacity opacity})
{:position :absolute
:padding-horizontal 20
:top (if platform/ios? top-inset 0)
:height common/top-view-height
;; height defined in top_view.cljs, but can't import due to circular dependency
:height 56
:z-index 4
:flex-direction :row
:justify-content :space-between
@@ -48,9 +48,10 @@
;;;; BOTTOM-VIEW
(defn gradient-container
[insets {:keys [opacity]}]
(reanimated/apply-animations-to-style
{:opacity opacity}
[insets {:keys [opacity bottom-layout]}]
(ra/apply-animations-to-style
{:transform [{:translateY bottom-layout}]
:opacity opacity}
{:position :absolute
:bottom 0
:padding-bottom (:bottom insets)
@@ -5,38 +5,39 @@
[react-native.core :as rn]
[react-native.orientation :as orientation]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.lightbox.common :as common]
[react-native.reanimated :as ra]
[status-im2.contexts.chat.lightbox.style :as style]
[utils.datetime :as datetime]
[utils.re-frame :as rf]))
(def ^:const top-view-height 56)
(defn animate-rotation
[result screen-width screen-height insets-atom
{:keys [rotate top-view-y top-view-x top-view-width top-view-bg]}]
(let [top-x (+ (/ common/top-view-height 2) (:top insets-atom))]
(let [top-x (+ (/ top-view-height 2) (:top insets-atom))]
(cond
(= result orientation/landscape-left)
(do
(common/set-val-timing rotate "90deg")
(common/set-val-timing top-view-y 60)
(common/set-val-timing top-view-x (- (/ screen-height 2) top-x))
(common/set-val-timing top-view-width screen-height)
(common/set-val-timing top-view-bg colors/neutral-100-opa-70))
(ra/animate rotate "90deg")
(ra/animate top-view-y 60)
(ra/animate top-view-x (- (/ screen-height 2) top-x))
(ra/animate top-view-width screen-height)
(ra/animate top-view-bg colors/neutral-100-opa-70))
(= result orientation/landscape-right)
(do
(common/set-val-timing rotate "-90deg")
(common/set-val-timing top-view-y (- (- screen-width) 4))
(common/set-val-timing top-view-x (+ (/ screen-height -2) top-x))
(common/set-val-timing top-view-width screen-height)
(common/set-val-timing top-view-bg colors/neutral-100-opa-70))
(ra/animate rotate "-90deg")
(ra/animate top-view-y (- (- screen-width) 4))
(ra/animate top-view-x (+ (/ screen-height -2) top-x))
(ra/animate top-view-width screen-height)
(ra/animate top-view-bg colors/neutral-100-opa-70))
(= result orientation/portrait)
(do
(common/set-val-timing rotate "0deg")
(common/set-val-timing top-view-y 0)
(common/set-val-timing top-view-x 0)
(common/set-val-timing top-view-width screen-width)
(common/set-val-timing top-view-bg colors/neutral-100-opa-0)))))
(ra/animate rotate "0deg")
(ra/animate top-view-y 0)
(ra/animate top-view-x 0)
(ra/animate top-view-width screen-width)
(ra/animate top-view-bg colors/neutral-100-opa-0)))))
(defn top-view
[{:keys [from timestamp]} insets index animations landscape? screen-width]
@@ -44,15 +45,17 @@
(fn []
(let [display-name (first (rf/sub [:contacts/contact-two-names-by-identity from]))
bg-color (if landscape? colors/neutral-100-opa-70 colors/neutral-100-opa-0)]
[reanimated/view
[ra/view
{:style (style/top-view-container (:top insets) animations screen-width bg-color)}
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[rn/touchable-opacity
{:on-press #(rf/dispatch (if platform/ios?
[:chat.ui/exit-lightbox-signal @index]
[:navigate-back]))
{:on-press (fn []
(ra/animate (:opacity animations) 0)
(rf/dispatch (if platform/ios?
[:chat.ui/exit-lightbox-signal @index]
[:navigate-back])))
:style style/close-container}
[quo/icon :close {:size 20 :color colors/white}]]
[rn/view {:style {:margin-left 12}}
+31 -19
View File
@@ -5,8 +5,7 @@
[react-native.core :as rn]
[react-native.orientation :as orientation]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.lightbox.common :as common]
[react-native.reanimated :as ra]
[utils.re-frame :as rf]
[react-native.safe-area :as safe-area]
[reagent.core :as reagent]
@@ -20,18 +19,18 @@
(defn toggle-opacity
[opacity-value border-value transparent? index {:keys [small-list-ref]}]
(let [opacity (reanimated/get-shared-value opacity-value)]
(let [opacity (ra/get-val opacity-value)]
(if (= opacity 1)
(do
(common/set-val-timing opacity-value 0)
(ra/animate opacity-value 0)
(js/setTimeout #(reset! transparent? (not @transparent?)) 400))
(do
(reset! transparent? (not @transparent?))
(reanimated/animate-shared-value-with-delay-default-easing opacity-value 1 300 50)
(ra/animate-delay opacity-value 1 50)
(js/setTimeout #(when @small-list-ref
(.scrollToIndex ^js @small-list-ref #js {:animated false :index index}))
100)))
(common/set-val-timing border-value (if (= opacity 1) 0 12))))
(ra/animate border-value (if (= opacity 1) 0 12))))
(defn handle-orientation
[result index window animations {:keys [flat-list-ref insets-atom]}]
@@ -94,7 +93,7 @@
(let [{:keys [messages index]} (rf/sub [:get-screen-params])
atoms {:flat-list-ref (atom nil)
:small-list-ref (atom nil)
:scroll-index-lock? (atom false)
:scroll-index-lock? (atom true)
:insets-atom (atom nil)}
;; The initial value of data is the image that was pressed (and not the whole album) in order
;; for the transition animation to execute properly, otherwise it would animate towards
@@ -103,16 +102,19 @@
scroll-index (reagent/atom index)
transparent? (reagent/atom false)
window (rf/sub [:dimensions/window])
animations {:border (common/use-val 12)
:opacity (common/use-val 1)
:rotate (common/use-val "0deg")
:top-view-y (common/use-val 0)
:top-view-x (common/use-val 0)
:top-view-width (common/use-val (:width window))
:top-view-bg (common/use-val colors/neutral-100-opa-0)}
animations {:border (ra/use-val (if platform/ios? 0 12))
:opacity (ra/use-val 0)
:rotate (ra/use-val "0deg")
:top-layout (ra/use-val -10)
:bottom-layout (ra/use-val 10)
:top-view-y (ra/use-val 0)
:top-view-x (ra/use-val 0)
:top-view-width (ra/use-val (:width window))
:top-view-bg (ra/use-val colors/neutral-100-opa-0)}
callback (fn [e]
(on-viewable-items-changed e scroll-index atoms))]
(println "aims" (ra/get-val (:opacity animations)))
(reset! data messages)
(orientation/use-device-orientation-change
(fn [result]
@@ -124,11 +126,21 @@
;; RNN does not support landscape-right
(when (and enabled? (not= result orientation/landscape-right))
(handle-orientation result scroll-index window animations atoms)))))))
(rn/use-effect-once (fn []
(when @(:flat-list-ref atoms)
(.scrollToIndex ^js @(:flat-list-ref atoms)
#js {:animated false :index index}))
js/undefined))
(rn/use-effect (fn []
(when @(:flat-list-ref atoms)
(.scrollToIndex ^js @(:flat-list-ref atoms)
#js {:animated false :index index}))
(js/setTimeout (fn []
(ra/animate (:opacity animations) 1)
(ra/animate (:top-layout animations) 0)
(ra/animate (:bottom-layout animations) 0)
(ra/animate (:border animations) 12))
(if platform/ios? 250 100))
(js/setTimeout #(reset! (:scroll-index-lock? atoms) false) 300)
(fn []
(rf/dispatch [:chat.ui/zoom-out-signal nil])
(when platform/android?
(rf/dispatch [:chat.ui/lightbox-scale 1])))))
[safe-area/consumer
(fn [insets]
(let [curr-orientation (or (rf/sub [:lightbox/orientation]) orientation/portrait)
@@ -1,10 +1,13 @@
(ns status-im2.contexts.chat.lightbox.zoomable-image.style
(:require [react-native.reanimated :as reanimated]))
(:require
[react-native.platform :as platform]
[react-native.reanimated :as ra]))
(defn container
[{:keys [width height]}
{:keys [pan-x pan-y pinch-x pinch-y scale]}]
(reanimated/apply-animations-to-style
{:keys [pan-x pan-y pinch-x pinch-y scale]}
set-full-height?]
(ra/apply-animations-to-style
{:transform [{:translateX pan-x}
{:translateY pan-y}
{:translateX pinch-x}
@@ -12,14 +15,14 @@
{:scale scale}]}
{:justify-content :center
:align-items :center
:width width
:height height}))
:width (if platform/ios? width "100%")
:height (if set-full-height? "100%" height)}))
(defn image
[{:keys [image-width image-height]}
{:keys [rotate rotate-scale]}
border-radius]
(reanimated/apply-animations-to-style
(ra/apply-animations-to-style
{:transform [{:rotate rotate}
{:scale rotate-scale}]
:border-radius border-radius}
@@ -3,10 +3,96 @@
[clojure.string :as string]
[react-native.orientation :as orientation]
[react-native.platform :as platform]
[react-native.reanimated :as ra]
[status-im2.contexts.chat.lightbox.zoomable-image.constants :as c]
[utils.re-frame :as rf]))
;;; Helpers
(defn center-x
[{:keys [pinch-x pinch-x-start pan-x pan-x-start]} exit?]
(let [duration (if exit? 100 c/default-duration)]
(ra/animate pinch-x c/init-offset duration)
(ra/set-val pinch-x-start c/init-offset)
(ra/animate pan-x c/init-offset duration)
(ra/set-val pan-x-start c/init-offset)))
(defn center-y
[{:keys [pinch-y pinch-y-start pan-y pan-y-start]} exit?]
(let [duration (if exit? 100 c/default-duration)]
(ra/animate pinch-y c/init-offset duration)
(ra/set-val pinch-y-start c/init-offset)
(ra/animate pan-y c/init-offset duration)
(ra/set-val pan-y-start c/init-offset)))
(defn reset-values
[exit? animations {:keys [focal-x focal-y]}]
(center-x animations exit?)
(center-y animations exit?)
(reset! focal-x nil)
(reset! focal-y nil))
(defn rescale-image
[value
exit?
{:keys [x-threshold-scale y-threshold-scale]}
{:keys [scale saved-scale] :as animations}
{:keys [pan-x-enabled? pan-y-enabled?] :as props}]
(ra/animate scale value (if exit? 100 c/default-duration))
(ra/set-val saved-scale value)
(when (= value c/min-scale)
(reset-values exit? animations props))
(reset! pan-x-enabled? (> value x-threshold-scale))
(reset! pan-y-enabled? (> value y-threshold-scale))
(when platform/android?
(rf/dispatch [:chat.ui/lightbox-scale value])))
;;; Handlers
(defn handle-orientation-change
[curr-orientation
focused?
{:keys [landscape-scale-val x-threshold-scale y-threshold-scale]}
{:keys [rotate rotate-scale scale] :as animations}
{:keys [pan-x-enabled? pan-y-enabled?]}]
(let [duration (when focused? c/default-duration)]
(cond
(= curr-orientation orientation/landscape-left)
(do
(ra/animate rotate "90deg" duration)
(ra/animate rotate-scale landscape-scale-val duration))
(= curr-orientation orientation/landscape-right)
(do
(ra/animate rotate "-90deg" duration)
(ra/animate rotate-scale landscape-scale-val duration))
(= curr-orientation orientation/portrait)
(do
(ra/animate rotate c/init-rotation duration)
(ra/animate rotate-scale c/min-scale duration)))
(center-x animations false)
(center-y animations false)
(reset! pan-x-enabled? (> (ra/get-val scale) x-threshold-scale))
(reset! pan-y-enabled? (> (ra/get-val scale) y-threshold-scale))))
(defn handle-exit-lightbox-signal
"On ios, when attempting to navigate back while zoomed in, the shared-element transition animation
doesn't execute properly, so we need to zoom out first"
[exit-lightbox-signal index scale rescale set-full-height?]
(when (= exit-lightbox-signal index)
(reset! set-full-height? false)
(if (> scale c/min-scale)
(do
(rescale c/min-scale true)
(js/setTimeout #(rf/dispatch [:navigate-back]) 70))
(rf/dispatch [:navigate-back]))
(js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500)))
(defn handle-zoom-out-signal
"Zooms out when pressing on another photo from the small bottom list"
[zoom-out-signal index scale rescale]
(when (and (= zoom-out-signal index) (> scale c/min-scale))
(rescale c/min-scale true)))
;;; Dimensions
(defn get-dimensions
"Calculates all required dimensions. Dimensions calculations are different on iOS and Android because landscape
mode is implemented differently.On Android, we just need to resize the content, and the OS takes care of the
@@ -39,24 +125,6 @@
:y-threshold-scale (/ screen-height (min screen-height container-height))
:landscape-scale-val (/ portrait-image-width portrait-image-height)}))
(defn handle-exit-lightbox-signal
"On ios, when attempting to navigate back while zoomed in, the shared-element transition animation
doesn't execute properly, so we need to zoom out first"
[exit-lightbox-signal index scale rescale]
(when (= exit-lightbox-signal index)
(if (> scale c/min-scale)
(do
(rescale c/min-scale true)
(js/setTimeout #(rf/dispatch [:navigate-back]) 70))
(rf/dispatch [:navigate-back]))
(js/setTimeout #(rf/dispatch [:chat.ui/exit-lightbox-signal nil]) 500)))
(defn handle-zoom-out-signal
"Zooms out when pressing on another photo from the small bottom list"
[zoom-out-signal index scale rescale]
(when (and (= zoom-out-signal index) (> scale c/min-scale))
(rescale c/min-scale true)))
;;; MATH
(defn get-max-offset
@@ -81,3 +149,11 @@
(defn get-pinch-position
[scale-diff size focal]
(* (- (/ size 2) focal) scale-diff))
(defn get-focal
[focal size screen-size]
(let [min (/ (- screen-size size) 2)
max (+ min size)]
(if (or (> focal max) (< focal min))
(/ screen-size 2)
focal)))
@@ -1,5 +1,6 @@
(ns status-im2.contexts.chat.lightbox.zoomable-image.view
(:require
[react-native.core :as rn]
[react-native.gesture :as gesture]
[react-native.platform :as platform]
[react-native.reanimated :as reanimated]
@@ -11,96 +12,6 @@
[status-im2.contexts.chat.lightbox.zoomable-image.style :as style]
[status-im2.contexts.chat.lightbox.zoomable-image.utils :as utils]))
;;;; Some aliases for reanimated methods, as they are used 10s of times in this file
;; TODO: Abstract Reanimated methods in a better way, issue:
;; https://github.com/status-im/status-mobile/issues/15176
(defn get-val
[animation]
(reanimated/get-shared-value animation))
(defn set-val
[animation value]
(reanimated/set-shared-value animation value))
(defn use-val
[value]
(reanimated/use-shared-value value))
(defn timing
([value]
(timing value c/default-duration))
([value duration]
(if (= duration nil)
value
(reanimated/with-timing-duration value duration))))
(defn set-val-decay
[animation velocity bounds]
(reanimated/animate-shared-value-with-decay animation (* velocity c/velocity-factor) bounds))
;;;; Helpers
(defn center-x
[{:keys [pinch-x pinch-x-start pan-x pan-x-start]} exit?]
(let [duration (if exit? 100 c/default-duration)]
(set-val pinch-x (timing c/init-offset duration))
(set-val pinch-x-start c/init-offset)
(set-val pan-x (timing c/init-offset duration))
(set-val pan-x-start c/init-offset)))
(defn center-y
[{:keys [pinch-y pinch-y-start pan-y pan-y-start]} exit?]
(let [duration (if exit? 100 c/default-duration)]
(set-val pinch-y (timing c/init-offset duration))
(set-val pinch-y-start c/init-offset)
(set-val pan-y (timing c/init-offset duration))
(set-val pan-y-start c/init-offset)))
(defn reset-values
[exit? animations {:keys [focal-x focal-y]}]
(center-x animations exit?)
(center-y animations exit?)
(reset! focal-x nil)
(reset! focal-y nil))
(defn rescale-image
[value
exit?
{:keys [x-threshold-scale y-threshold-scale]}
{:keys [scale saved-scale] :as animations}
{:keys [pan-x-enabled? pan-y-enabled?] :as props}]
(set-val scale (timing value (if exit? 100 c/default-duration)))
(set-val saved-scale value)
(when (= value c/min-scale)
(reset-values exit? animations props))
(reset! pan-x-enabled? (> value x-threshold-scale))
(reset! pan-y-enabled? (> value y-threshold-scale)))
(defn handle-orientation-change
[curr-orientation
focused?
{:keys [landscape-scale-val x-threshold-scale y-threshold-scale]}
{:keys [rotate rotate-scale scale] :as animations}
{:keys [pan-x-enabled? pan-y-enabled?]}]
(let [duration (when focused? c/default-duration)]
(cond
(= curr-orientation orientation/landscape-left)
(do
(set-val rotate (timing "90deg" duration))
(set-val rotate-scale (timing landscape-scale-val duration)))
(= curr-orientation orientation/landscape-right)
(do
(set-val rotate (timing "-90deg" duration))
(set-val rotate-scale (timing landscape-scale-val duration)))
(= curr-orientation orientation/portrait)
(do
(set-val rotate (timing c/init-rotation duration))
(set-val rotate-scale (timing c/min-scale duration))))
(center-x animations false)
(center-y animations false)
(reset! pan-x-enabled? (> (get-val scale) x-threshold-scale))
(reset! pan-y-enabled? (> (get-val scale) y-threshold-scale))))
;;;; Gestures
(defn tap-gesture
[on-tap]
(->
@@ -116,92 +27,109 @@
(gesture/number-of-taps 2)
(gesture/on-start
(fn [e]
(if (= (get-val scale) c/min-scale)
(if (= (reanimated/get-shared-value scale) c/min-scale)
(let [translate-x (utils/get-double-tap-offset width screen-width (oget e "x"))
translate-y (utils/get-double-tap-offset height screen-height (oget e "y"))]
(when (> c/double-tap-scale x-threshold-scale)
(set-val pan-x (timing translate-x))
(set-val pan-x-start translate-x))
(reanimated/set-shared-value pan-x (reanimated/with-timing translate-x))
(reanimated/set-shared-value pan-x-start translate-x))
(when (> c/double-tap-scale y-threshold-scale)
(set-val pan-y (timing translate-y))
(set-val pan-y-start translate-y))
(reanimated/set-shared-value pan-y (reanimated/with-timing translate-y))
(reanimated/set-shared-value pan-y-start translate-y))
(rescale c/double-tap-scale))
(rescale c/min-scale))))))
(defn pinch-gesture
;; not using on-finalize because on-finalize gets called always regardless the gesture executed or not
(defn finalize-pinch
[{:keys [width height screen-height screen-width x-threshold-scale y-threshold-scale]}
{:keys [saved-scale scale pinch-x pinch-y pinch-x-start pinch-y-start pinch-x-max pinch-y-max pan-y
pan-y-start pan-x pan-x-start]
{:keys [saved-scale scale pinch-x pinch-y pinch-x-start pinch-y-start pan-y pan-y-start pan-x
pan-x-start]}
{:keys [pan-x-enabled? pan-y-enabled?]}]
(let [curr-offset-y (+ (reanimated/get-shared-value pan-y) (reanimated/get-shared-value pinch-y))
max-offset-y (utils/get-max-offset height screen-height (reanimated/get-shared-value scale))
max-offset-y (if (neg? curr-offset-y) (- max-offset-y) max-offset-y)
curr-offset-x (+ (reanimated/get-shared-value pan-x) (reanimated/get-shared-value pinch-x))
max-offset-x (utils/get-max-offset width screen-width (reanimated/get-shared-value scale))
max-offset-x (if (neg? curr-offset-x) (- max-offset-x) max-offset-x)]
(when (and (> (reanimated/get-shared-value scale) y-threshold-scale)
(< (reanimated/get-shared-value scale) c/max-scale)
(> (Math/abs curr-offset-y) (Math/abs max-offset-y)))
(reanimated/set-shared-value pinch-y (reanimated/with-timing c/init-offset))
(reanimated/set-shared-value pinch-y-start c/init-offset)
(reanimated/set-shared-value pan-y (reanimated/with-timing max-offset-y))
(reanimated/set-shared-value pan-y-start max-offset-y))
(when (and (> (reanimated/get-shared-value scale) x-threshold-scale)
(< (reanimated/get-shared-value scale) c/max-scale)
(> (Math/abs curr-offset-x) (Math/abs max-offset-x)))
(reanimated/set-shared-value pinch-x (reanimated/with-timing c/init-offset))
(reanimated/set-shared-value pinch-x-start c/init-offset)
(reanimated/set-shared-value pan-x (reanimated/with-timing max-offset-x))
(reanimated/set-shared-value pan-x-start max-offset-x))
(reset! pan-x-enabled? (> (reanimated/get-shared-value scale) x-threshold-scale))
(reset! pan-y-enabled? (> (reanimated/get-shared-value scale) y-threshold-scale))
(when platform/android?
(rf/dispatch [:chat.ui/lightbox-scale (reanimated/get-shared-value saved-scale)]))))
(defn pinch-gesture
[{:keys [width height screen-height screen-width x-threshold-scale y-threshold-scale] :as dimensions}
{:keys [saved-scale scale pinch-x pinch-y pinch-x-start pinch-y-start pinch-x-max pinch-y-max]
:as animations}
{:keys [pan-x-enabled? pan-y-enabled? focal-x focal-y]}
{:keys [focal-x focal-y] :as props}
rescale]
(->
(gesture/gesture-pinch)
(gesture/on-begin (fn [e]
(when platform/ios?
(reset! focal-x (oget e "focalX"))
(reset! focal-y (oget e "focalY")))))
(reset! focal-y (utils/get-focal (oget e "focalY") height screen-height)))))
(gesture/on-start (fn [e]
(when platform/android?
(reset! focal-x (oget e "focalX"))
(reset! focal-y (oget e "focalY")))))
(gesture/on-update (fn [e]
(let [new-scale (* (oget e "scale") (get-val saved-scale))
scale-diff (utils/get-scale-diff new-scale (get-val saved-scale))
new-pinch-x (utils/get-pinch-position scale-diff width @focal-x)
new-pinch-y (utils/get-pinch-position scale-diff height @focal-y)]
(when (and (>= new-scale c/max-scale) (= (get-val pinch-x-max) js/Infinity))
(set-val pinch-x-max (get-val pinch-x))
(set-val pinch-y-max (get-val pinch-y)))
(set-val pinch-x (+ new-pinch-x (get-val pinch-x-start)))
(set-val pinch-y (+ new-pinch-y (get-val pinch-y-start)))
(set-val scale new-scale))))
(reset! focal-x (utils/get-focal (oget e "focalX") width screen-width))
(reset! focal-y (utils/get-focal (oget e "focalY") height screen-height)))))
(gesture/on-update
(fn [e]
(let [new-scale (* (oget e "scale") (reanimated/get-shared-value saved-scale))
scale-diff (utils/get-scale-diff new-scale (reanimated/get-shared-value saved-scale))
new-pinch-x (utils/get-pinch-position scale-diff screen-width @focal-x)
new-pinch-y (utils/get-pinch-position scale-diff screen-height @focal-y)]
(when (and (>= new-scale c/max-scale)
(= (reanimated/get-shared-value pinch-x-max) js/Infinity))
(reanimated/set-shared-value pinch-x-max (reanimated/get-shared-value pinch-x))
(reanimated/set-shared-value pinch-y-max (reanimated/get-shared-value pinch-y)))
(reanimated/set-shared-value pinch-x
(+ new-pinch-x (reanimated/get-shared-value pinch-x-start)))
(reanimated/set-shared-value pinch-y
(+ new-pinch-y (reanimated/get-shared-value pinch-y-start)))
(reanimated/set-shared-value scale new-scale))))
(gesture/on-end
(fn []
(cond
(< (get-val scale) c/min-scale)
(< (reanimated/get-shared-value scale) c/min-scale)
(rescale c/min-scale)
(> (get-val scale) c/max-scale)
(> (reanimated/get-shared-value scale) c/max-scale)
(do
(set-val pinch-x (timing (get-val pinch-x-max)))
(set-val pinch-x-start (get-val pinch-x-max))
(set-val pinch-x-max js/Infinity)
(set-val pinch-y (timing (get-val pinch-y-max)))
(set-val pinch-y-start (get-val pinch-y-max))
(set-val pinch-y-max js/Infinity)
(set-val scale (timing c/max-scale))
(set-val saved-scale c/max-scale))
(reanimated/set-shared-value pinch-x
(reanimated/with-timing (reanimated/get-shared-value
pinch-x-max)))
(reanimated/set-shared-value pinch-x-start (reanimated/get-shared-value pinch-x-max))
(reanimated/set-shared-value pinch-x-max js/Infinity)
(reanimated/set-shared-value pinch-y
(reanimated/with-timing (reanimated/get-shared-value
pinch-y-max)))
(reanimated/set-shared-value pinch-y-start (reanimated/get-shared-value pinch-y-max))
(reanimated/set-shared-value pinch-y-max js/Infinity)
(reanimated/set-shared-value scale (reanimated/with-timing c/max-scale))
(reanimated/set-shared-value saved-scale c/max-scale))
:else
(do
(set-val saved-scale (get-val scale))
(set-val pinch-x-start (get-val pinch-x))
(set-val pinch-y-start (get-val pinch-y))
(when (< (get-val scale) x-threshold-scale)
(center-x animations false))
(when (< (get-val scale) y-threshold-scale)
(center-y animations false))))))
(gesture/on-finalize
(fn []
(let [curr-offset-y (+ (get-val pan-y) (get-val pinch-y))
max-offset-y (utils/get-max-offset height screen-height (get-val scale))
max-offset-y (if (neg? curr-offset-y) (- max-offset-y) max-offset-y)
curr-offset-x (+ (get-val pan-x) (get-val pinch-x))
max-offset-x (utils/get-max-offset width screen-width (get-val scale))
max-offset-x (if (neg? curr-offset-x) (- max-offset-x) max-offset-x)]
(when (and (> (get-val scale) y-threshold-scale)
(> (Math/abs curr-offset-y) (Math/abs max-offset-y)))
(set-val pinch-y (timing c/init-offset))
(set-val pinch-y-start c/init-offset)
(set-val pan-y (timing max-offset-y))
(set-val pan-y-start max-offset-y))
(when (and (> (get-val scale) x-threshold-scale)
(> (Math/abs curr-offset-x) (Math/abs max-offset-x)))
(set-val pinch-x (timing c/init-offset))
(set-val pinch-x-start c/init-offset)
(set-val pan-x (timing max-offset-x))
(set-val pan-x-start max-offset-x))
(reset! pan-x-enabled? (> (get-val scale) x-threshold-scale))
(reset! pan-y-enabled? (> (get-val scale) y-threshold-scale)))))))
(reanimated/set-shared-value saved-scale (reanimated/get-shared-value scale))
(reanimated/set-shared-value pinch-x-start (reanimated/get-shared-value pinch-x))
(reanimated/set-shared-value pinch-y-start (reanimated/get-shared-value pinch-y))
(when (< (reanimated/get-shared-value scale) x-threshold-scale)
(utils/center-x animations false))
(when (< (reanimated/get-shared-value scale) y-threshold-scale)
(utils/center-y animations false))))
(finalize-pinch dimensions animations props)))))
(defn pan-x-gesture
[{:keys [width screen-width x-threshold-scale]}
@@ -213,27 +141,33 @@
(gesture/enabled @pan-x-enabled?)
(gesture/average-touches false)
(gesture/on-update (fn [e]
(set-val pan-x (+ (get-val pan-x-start) (oget e "translationX")))))
(reanimated/set-shared-value pan-x
(+ (reanimated/get-shared-value pan-x-start)
(oget e "translationX")))))
(gesture/on-end
(fn [e]
(let [curr-offset (+ (get-val pan-x) (get-val pinch-x-start))
max-offset (utils/get-max-offset width screen-width (get-val scale))
max-offset (if (neg? curr-offset) (- max-offset) max-offset)]
(let [curr-offset (+ (reanimated/get-shared-value pan-x)
(reanimated/get-shared-value pinch-x-start))
max-offset (utils/get-max-offset width screen-width (reanimated/get-shared-value scale))
max-offset (if (neg? curr-offset) (- max-offset) max-offset)
velocity (* (oget e "velocityX") c/velocity-factor)]
(cond
(< (get-val scale) x-threshold-scale)
(< (reanimated/get-shared-value scale) x-threshold-scale)
(rescale c/min-scale)
(> (Math/abs curr-offset) (Math/abs max-offset))
(do
(set-val pan-x (timing max-offset))
(set-val pan-x-start max-offset)
(set-val pinch-x (timing c/init-offset))
(set-val pinch-x-start c/init-offset))
(reanimated/set-shared-value pan-x (reanimated/with-timing max-offset))
(reanimated/set-shared-value pan-x-start max-offset)
(reanimated/set-shared-value pinch-x (reanimated/with-timing c/init-offset))
(reanimated/set-shared-value pinch-x-start c/init-offset))
:else
(let [lower-bound (- (- (Math/abs max-offset)) (get-val pinch-x-start))
upper-bound (- (Math/abs max-offset) (get-val pinch-x-start))]
(set-val pan-x-start (get-val pan-x))
(set-val-decay pan-x (oget e "velocityX") [lower-bound upper-bound])
(set-val-decay pan-x-start (oget e "velocityX") [lower-bound upper-bound]))))))))
(let [lower-bound (- (- (Math/abs max-offset)) (reanimated/get-shared-value pinch-x-start))
upper-bound (- (Math/abs max-offset) (reanimated/get-shared-value pinch-x-start))]
(reanimated/set-shared-value pan-x-start (reanimated/get-shared-value pan-x))
(reanimated/animate-shared-value-with-decay pan-x velocity [lower-bound upper-bound])
(reanimated/animate-shared-value-with-decay pan-x-start
velocity
[lower-bound upper-bound]))))))))
(defn pan-y-gesture
@@ -246,81 +180,94 @@
(gesture/enabled @pan-y-enabled?)
(gesture/average-touches false)
(gesture/on-update (fn [e]
(set-val pan-y (+ (get-val pan-y-start) (oget e "translationY")))))
(reanimated/set-shared-value pan-y
(+ (reanimated/get-shared-value pan-y-start)
(oget e "translationY")))))
(gesture/on-end
(fn [e]
(let [curr-offset (+ (get-val pan-y) (get-val pinch-y-start))
max-offset (utils/get-max-offset height screen-height (get-val scale))
max-offset (if (neg? curr-offset) (- max-offset) max-offset)]
(let [curr-offset (+ (reanimated/get-shared-value pan-y)
(reanimated/get-shared-value pinch-y-start))
max-offset (utils/get-max-offset height screen-height (reanimated/get-shared-value scale))
max-offset (if (neg? curr-offset) (- max-offset) max-offset)
velocity (* (oget e "velocityY") c/velocity-factor)]
(cond
(< (get-val scale) y-threshold-scale)
(< (reanimated/get-shared-value scale) y-threshold-scale)
(rescale c/min-scale)
(> (Math/abs curr-offset) (Math/abs max-offset))
(do
(set-val pan-y (timing max-offset))
(set-val pan-y-start max-offset)
(set-val pinch-y (timing c/init-offset))
(set-val pinch-y-start c/init-offset))
(reanimated/set-shared-value pan-y (reanimated/with-timing max-offset))
(reanimated/set-shared-value pan-y-start max-offset)
(reanimated/set-shared-value pinch-y (reanimated/with-timing c/init-offset))
(reanimated/set-shared-value pinch-y-start c/init-offset))
:else
(let [lower-bound (- (- (Math/abs max-offset)) (get-val pinch-y-start))
upper-bound (- (Math/abs max-offset) (get-val pinch-y-start))]
(set-val pan-y-start (get-val pan-y))
(set-val-decay pan-y (oget e "velocityY") [lower-bound upper-bound])
(set-val-decay pan-y-start (oget e "velocityY") [lower-bound upper-bound]))))))))
(let [lower-bound (- (- (Math/abs max-offset)) (reanimated/get-shared-value pinch-y-start))
upper-bound (- (Math/abs max-offset) (reanimated/get-shared-value pinch-y-start))]
(reanimated/set-shared-value pan-y-start (reanimated/get-shared-value pan-y))
(reanimated/animate-shared-value-with-decay pan-y velocity [lower-bound upper-bound])
(reanimated/animate-shared-value-with-decay pan-y-start
velocity
[lower-bound upper-bound]))))))))
;;;; Finally, the component
(defn zoomable-image
[{:keys [image-width image-height content message-id]} index border-radius on-tap]
[:f>
(fn []
(let [shared-element-id (rf/sub [:shared-element-id])
exit-lightbox-signal (rf/sub [:lightbox/exit-signal])
zoom-out-signal (rf/sub [:lightbox/zoom-out-signal])
curr-orientation (or (rf/sub [:lightbox/orientation]) orientation/portrait)
focused? (= shared-element-id message-id)
dimensions (utils/get-dimensions image-width image-height curr-orientation)
animations {:scale (use-val c/min-scale)
:saved-scale (use-val c/min-scale)
:pan-x-start (use-val c/init-offset)
:pan-x (use-val c/init-offset)
:pan-y-start (use-val c/init-offset)
:pan-y (use-val c/init-offset)
:pinch-x-start (use-val c/init-offset)
:pinch-x (use-val c/init-offset)
:pinch-y-start (use-val c/init-offset)
:pinch-y (use-val c/init-offset)
:pinch-x-max (use-val js/Infinity)
:pinch-y-max (use-val js/Infinity)
:rotate (use-val c/init-rotation)
:rotate-scale (use-val c/min-scale)}
props {:pan-x-enabled? (reagent/atom false)
:pan-y-enabled? (reagent/atom false)
:focal-x (reagent/atom nil)
:focal-y (reagent/atom nil)}
rescale (fn [value exit?]
(rescale-image value exit? dimensions animations props))]
(when platform/ios?
(handle-orientation-change curr-orientation focused? dimensions animations props)
(utils/handle-exit-lightbox-signal exit-lightbox-signal
index
(get-val (:scale animations))
rescale))
(utils/handle-zoom-out-signal zoom-out-signal index (get-val (:scale animations)) rescale)
[:f>
(fn []
(let [tap (tap-gesture on-tap)
double-tap (double-tap-gesture dimensions animations rescale)
pinch (pinch-gesture dimensions animations props rescale)
pan-x (pan-x-gesture dimensions animations props rescale)
pan-y (pan-y-gesture dimensions animations props rescale)
composed-gestures (gesture/exclusive
(gesture/simultaneous pinch pan-x pan-y)
(gesture/exclusive double-tap tap))]
[gesture/gesture-detector {:gesture composed-gestures}
[reanimated/view
{:style (style/container dimensions animations)}
[reanimated/fast-image
{:source {:uri (:image content)}
:native-ID (when focused? :shared-element)
:style (style/image dimensions animations border-radius)}]]]))]))])
(let [set-full-height? (reagent/atom false)]
[:f>
(fn []
(let [shared-element-id (rf/sub [:shared-element-id])
exit-lightbox-signal (rf/sub [:lightbox/exit-signal])
zoom-out-signal (rf/sub [:lightbox/zoom-out-signal])
initial-scale (if platform/ios? c/min-scale (rf/sub [:lightbox/scale]))
curr-orientation (or (rf/sub [:lightbox/orientation]) orientation/portrait)
focused? (= shared-element-id message-id)
dimensions (utils/get-dimensions image-width image-height curr-orientation)
animations {:scale (reanimated/use-shared-value initial-scale)
:saved-scale (reanimated/use-shared-value initial-scale)
:pan-x-start (reanimated/use-shared-value c/init-offset)
:pan-x (reanimated/use-shared-value c/init-offset)
:pan-y-start (reanimated/use-shared-value c/init-offset)
:pan-y (reanimated/use-shared-value c/init-offset)
:pinch-x-start (reanimated/use-shared-value c/init-offset)
:pinch-x (reanimated/use-shared-value c/init-offset)
:pinch-y-start (reanimated/use-shared-value c/init-offset)
:pinch-y (reanimated/use-shared-value c/init-offset)
:pinch-x-max (reanimated/use-shared-value js/Infinity)
:pinch-y-max (reanimated/use-shared-value js/Infinity)
:rotate (reanimated/use-shared-value c/init-rotation)
:rotate-scale (reanimated/use-shared-value c/min-scale)}
props {:pan-x-enabled? (reagent/atom false)
:pan-y-enabled? (reagent/atom false)
:focal-x (reagent/atom nil)
:focal-y (reagent/atom nil)}
rescale (fn [value exit?]
(utils/rescale-image value exit? dimensions animations props))]
(rn/use-effect-once (fn []
(js/setTimeout #(reset! set-full-height? true) 500)
js/undefined))
(when platform/ios?
(utils/handle-orientation-change curr-orientation focused? dimensions animations props)
(utils/handle-exit-lightbox-signal exit-lightbox-signal
index
(reanimated/get-shared-value (:scale animations))
rescale
set-full-height?))
(utils/handle-zoom-out-signal zoom-out-signal
index
(reanimated/get-shared-value (:scale animations))
rescale)
[:f>
(fn []
(let [tap (tap-gesture on-tap)
double-tap (double-tap-gesture dimensions animations rescale)
pinch (pinch-gesture dimensions animations props rescale)
pan-x (pan-x-gesture dimensions animations props rescale)
pan-y (pan-y-gesture dimensions animations props rescale)
composed-gestures (gesture/exclusive
(gesture/simultaneous pinch pan-x pan-y)
(gesture/exclusive double-tap tap))]
[gesture/gesture-detector {:gesture composed-gestures}
[ra/view
{:style (style/container dimensions animations @set-full-height?)}
[ra/fast-image
{:source {:uri (:image content)}
:native-ID (when focused? :shared-element)
:style (style/image dimensions animations border-radius)}]]]))]))]))
@@ -1,7 +1,7 @@
(ns status-im2.contexts.chat.messages.composer.mentions.view
(:require [utils.re-frame :as rf]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[status-im2.common.contact-list-item.view :as contact-list-item]))
(defn mention-item
@@ -13,13 +13,13 @@
[{:keys [refs suggestions max-y]} insets]
[:f>
(fn []
(let [translate-y (reanimated/use-shared-value 0)]
(let [translate-y (ra/use-val 0)]
(rn/use-effect
(fn []
(reanimated/set-shared-value translate-y
(reanimated/with-timing (if (seq suggestions) 0 200)))))
[reanimated/view
{:style (reanimated/apply-animations-to-style
(ra/set-val translate-y
(ra/with-timing (if (seq suggestions) 0 200)))))
[ra/view
{:style (ra/apply-animations-to-style
{:transform [{:translateY translate-y}]}
{:bottom (or (:bottom insets) 0)
:position :absolute
@@ -4,7 +4,7 @@
[react-native.core :as rn]
[react-native.hooks :as hooks]
[react-native.gesture :as gesture]
[react-native.reanimated :as reanimated]
[react-native.reanimated :as ra]
[react-native.background-timer :as background-timer]
[utils.re-frame :as rf]
[status-im2.contexts.chat.messages.composer.style :as style]
@@ -43,7 +43,7 @@
(gesture/on-start
(fn [_]
(if keyboard-shown
(swap! gesture-values assoc :pan-y (reanimated/get-shared-value translate-y))
(swap! gesture-values assoc :pan-y (ra/get-val translate-y))
(input/input-focus text-input-ref))))
(gesture/on-update
(fn [evt]
@@ -51,7 +51,7 @@
(let [tY (oget evt "translationY")]
(swap! gesture-values assoc :dy (- tY (:pdy @gesture-values)))
(swap! gesture-values assoc :pdy tY)
(reanimated/set-shared-value
(ra/set-val
translate-y
(max (min (+ tY (:pan-y @gesture-values)) (- min-y)) (- max-y)))))))
(gesture/on-end
@@ -129,12 +129,12 @@
:bg-bottom bg-bottom
:window-height window-height
:set-bg-opacity (fn [value]
(reanimated/set-shared-value bg-bottom (if (= value 1) 0 (- window-height)))
(reanimated/set-shared-value bg-opacity (reanimated/with-timing value)))
(ra/set-val bg-bottom (if (= value 1) 0 (- window-height)))
(ra/set-val bg-opacity (ra/with-timing value)))
:set-translate-y (fn [value]
(reanimated/set-shared-value translate-y (reanimated/with-timing value)))
(ra/set-val translate-y (ra/with-timing value)))
:set-parent-height (fn [value]
(reanimated/set-shared-value parent-height (reanimated/with-timing value)))})
(ra/set-val parent-height (ra/with-timing value)))})
;; IMPORTANT! PLEASE READ BEFORE MAKING CHANGES
@@ -165,9 +165,9 @@
{window-height :height} (rn/use-window-dimensions)
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
translate-y (reanimated/use-shared-value 0)
bg-opacity (reanimated/use-shared-value 0)
bg-bottom (reanimated/use-shared-value (- window-height))
translate-y (ra/use-val 0)
bg-opacity (ra/use-val 0)
bg-bottom (ra/use-val (- window-height))
suggestions? (and (seq suggestions)
keyboard-shown
@@ -190,7 +190,7 @@
(when (or edit reply) 38)
(when (seq images) 80))))
parent-height (reanimated/use-shared-value min-y)
parent-height (ra/use-val min-y)
max-parent-height (Math/abs (- max-y 110 (:bottom insets)))
params
@@ -201,14 +201,14 @@
input-content-change (get-input-content-change params)
bottom-sheet-gesture (get-bottom-sheet-gesture params)]
(effect! params)
[reanimated/view
{:style (reanimated/apply-animations-to-style
[ra/view
{:style (ra/apply-animations-to-style
{:height parent-height}
{})}
;;;;input
[gesture/gesture-detector {:gesture bottom-sheet-gesture}
[reanimated/view
{:style (reanimated/apply-animations-to-style
[ra/view
{:style (ra/apply-animations-to-style
{:transform [{:translateY translate-y}]}
(style/input-bottom-sheet window-height))}
[rn/view {:style (style/bottom-sheet-handle)}]
@@ -225,8 +225,8 @@
[mentions/mentions params insets]
[controls/view send-ref params insets chat-id images #(clean-and-minimize params)])
;;;;black background
[reanimated/view
{:style (reanimated/apply-animations-to-style
[ra/view
{:style (ra/apply-animations-to-style
{:opacity bg-opacity
:transform [{:translateY bg-bottom}]}
(style/bottom-sheet-background window-height))}]]))])))
@@ -45,7 +45,6 @@
[rn/touchable-opacity
{:key (:message-id item)
:active-opacity 1
;; issue: https://github.com/status-im/status-mobile/issues/14995
:on-long-press #(on-long-press message context)
:on-press (fn []
(rf/dispatch [:chat.ui/update-shared-element-id (:message-id item)])
@@ -21,7 +21,7 @@
[rn/touchable-opacity
{:active-opacity 1
:key message-id
:style {:margin-top (when (> index 0) 20)}
:style {:margin-top (when (> index 0) 10)}
:on-long-press on-long-press
:on-press (fn []
(rf/dispatch [:chat.ui/update-shared-element-id message-id])
@@ -2,9 +2,10 @@
(:require [react-native.platform :as platform]))
(def screen-title-container
{:height 56
:padding-vertical 12
:justify-content :center})
{:height 56
:padding-vertical 12
:justify-content :center
:margin-horizontal 20})
(def featured-communities-header
{:flex-direction :row
@@ -12,6 +13,7 @@
:padding-top 8
:margin-bottom 8
:padding-right 20
:margin-left 20
:justify-content :space-between})
(def featured-communities-title-container
@@ -21,7 +23,13 @@
(def featured-list-container
{:flex-direction :row
:overflow :hidden
:margin-bottom 24})
:margin-bottom 24
:margin-left 20
:padding-right 20})
(def other-communities-container
{:flex 1
:margin-horizontal 20})
(defn discover-communities-segments
[fixed?]
@@ -30,8 +38,9 @@
:height 56
:background-color :transparent}
(when-not fixed?
{:margin-top 12
:margin-bottom 4})))
{:margin-top 12
:margin-horizontal 20
:margin-bottom 4})))
(defn discover-screen-container
[background-color]
@@ -47,8 +56,7 @@
:justify-content :center})
(def render-communities-container
{:padding-horizontal 20
:margin-top 100})
{:margin-top 100})
(defn blur-tabs-header
[]
@@ -18,26 +18,17 @@
{:data {:community-color "#0052FF"
:status :gated
:locked? true
:cover (resources/get-mock-image :community-cover)
:tokens [{:id 1
:group [{:id 1
:token-icon (resources/get-mock-image :status-logo)}]}]
:tags [{:id 1
:tag-label (i18n/label :t/music)
:resource (resources/get-image :music)}
{:id 2
:tag-label (i18n/label :t/lifestyle)
:resource (resources/get-image :lifestyle)}
{:id 3
:tag-label (i18n/label :t/podcasts)
:resource (resources/get-image :podcasts)}]}})
:token-icon (resources/get-mock-image :status-logo)}]}]}})
(defn render-fn
[community-item _ _ {:keys [width view-type]}]
(let [item (merge community-item
(get mock-community-item-data :data))]
(let [item (merge community-item
(get mock-community-item-data :data))
cover {:uri (get-in (:images item) [:banner :uri])}]
(if (= view-type :card-view)
[quo/community-card-view-item (assoc item :width width)
[quo/community-card-view-item (assoc item :width width :cover cover)
#(rf/dispatch [:navigate-to :community-overview (:id item)])]
[quo/communities-list-view-item
{:on-press (fn []
@@ -134,7 +125,7 @@
(defn other-communities-list
[{:keys [communities communities-ids view-type]}]
[rn/view {:flex 1}
[rn/view {:style style/other-communities-container}
(map-indexed
(fn [inner-index item]
(let [community-id (when communities-ids item)
@@ -288,10 +288,12 @@
(let [categories-heights (reagent/atom [])
first-channel-height (reagent/atom 0)
scroll-height (reagent/atom 0)
cover {:uri (get-in images [:large :uri])}]
cover {:uri (get-in images [:banner :uri])}
logo {:uri (get-in images [:thumbnail :uri])}]
(fn [community]
[scroll-page/scroll-page
{:cover-image cover
:logo logo
:page-nav-right-section-buttons (page-nav-right-section-buttons id)
:name name
:on-scroll #(reset! scroll-height %)
@@ -1,19 +0,0 @@
(ns status-im2.contexts.emoji-hash.events
(:require [utils.re-frame :as rf]
[status-im.native-module.core :as native-module]
[utils.transforms :as transform]))
(defn fetch-for-current-public-key
[]
(let [public-key (rf/sub [:multiaccount/public-key])]
(native-module/public-key->emoji-hash
public-key
(fn [response]
(let [response-clj (transform/json->clj response)
emoji-hash (get response-clj :result)]
(rf/dispatch [:emoji-hash/add-to-multiaccount emoji-hash]))))))
(rf/defn add-emoji-hash-to-multiaccount
{:events [:emoji-hash/add-to-multiaccount]}
[{:keys [db]} emoji-hash]
{:db (assoc db :multiaccount/emoji-hash emoji-hash)})
@@ -0,0 +1,26 @@
(ns status-im2.contexts.onboarding.common.background
(:require [react-native.core :as rn]
[quo2.foundations.colors :as colors]
[status-im2.common.resources :as resources]
[react-native.linear-gradient :as linear-gradient]
[status-im2.contexts.onboarding.common.style :as style]))
(defn view
[dark-overlay?]
[rn/view
{:style style/background-container}
;; Todo - add carousel component as background once ready
;; https://github.com/status-im/status-mobile/issues/15012
[rn/image
{:blur-radius (if dark-overlay? 13 0)
:style {:flex 1}
:source (resources/get-image :onboarding-bg-1)}]
[linear-gradient/linear-gradient
{:colors [(if dark-overlay? (colors/custom-color :yin 50) "#000716")
(if dark-overlay? (colors/custom-color :yin 50 0) "#000716")]
:start {:x 0 :y 0}
:end {:x 0 :y 1}
:style (style/background-gradient-overlay dark-overlay?)}]
(when dark-overlay?
[rn/view
{:style style/background-blur-overlay}])])
@@ -0,0 +1,61 @@
(ns status-im2.contexts.onboarding.common.intro.style
(:require
[react-native.platform :as platform]
[quo2.foundations.colors :as colors]))
(def progress-bar-container
{:background-color colors/neutral-100
:flex-direction :row
:margin-vertical 16})
(defn progress-bar-item
[index position end?]
{:height 2
:flex 1
:border-width 1
:border-color (if (= index position) colors/white colors/white-opa-10)
:margin-right (if end? 0 8)})
(def carousel
{:height 92
;; (padding-top) This insets issue needs a consistent implementation across all screens.
:padding-top (if platform/android? 0 44)
:position :absolute
:top 0
:bottom 0
:left 0
:right 0
:z-index 2
:background-color colors/neutral-100
:padding-vertical 12
:padding-horizontal 20})
(def carousel-text
{:background-color colors/neutral-100
:color colors/white})
(def page-container
{:flex 1
:justify-content :flex-end})
(def page-image
{:position :absolute
:background-color colors/neutral-100
:top 0
:bottom 0
:left 0
:right 0
:width "100%"
:aspect-ratio 1})
(def text-container
{:flex 1
:flex-wrap :wrap})
(def plain-text
{:flex 1
:color (colors/alpha colors/white 0.7)})
(def highlighted-text
{:flex 1
:color colors/white})

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