Compare commits

...
34 Commits
Author SHA1 Message Date
Siddarth Kumar f63cd8913b commit : stage wip stuff 2024-04-01 11:45:41 +05:30
Jamie Caprani e9bbb34797 chore(wallet): clean up root folder (#19417) 2024-03-29 13:21:01 +00:00
jakub 28aeb2dad0 ci: use new Alchemy API tokens from env file
I have created separate API tokens for Mobile project and changed how
they are passed in Jenkins by using a single file.

Depends on:
https://github.com/status-im/status-jenkins-lib/pull/88

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-03-29 00:31:36 +01:00
Ibrahem Khalil fef3165f24 Link preview follow up bug fixes (#19359) 2024-03-28 23:54:20 +02:00
Jamie Caprani 88d1a17a94 chore(wallet): move bridge to its own folder (#19414) 2024-03-28 19:42:43 +00:00
Andrea Maria Piana ed824bdb06 Check permissions even if there's an inflight request 2024-03-28 17:08:16 +00:00
Sean Hagstrom 932fee2857 Update usage of Login/Create/Restore account (#19420)
* update status-go version to v0.178.0

* chore: add fetchBackup as true when restoring account
2024-03-28 16:51:48 +00:00
Jamie Caprani 53874c8343 chore: rename alias of promesa to be more verbose (#19332) 2024-03-28 09:33:16 -07:00
Ibrahem Khalil e6d9ef0298 Add toggle instead of checkbox for addresses for permissions sheet (#19424) 2024-03-28 17:40:50 +02:00
Volodymyr Kozieiev 4aee5af791 Flow for sending multiple collectibles (#19386) 2024-03-28 15:14:17 +00:00
NikolayandJamie Caprani 3ee004afab chore(quo): implement drawer action component (#19289)
Co-authored-by: Jamie Caprani <jamiecaprani@gmail.com>
2024-03-28 14:39:48 +00:00
John Ngeiandbalogunofafrica 6c07fac28b fix: avatar alignment (#19073)
Co-authored-by: balogunofafrica <balogunakanbi.k@gmail.com>
2024-03-28 12:13:23 +01:00
Andrea Maria Piana 98deaa4459 Disable button when request is in flight 2024-03-27 22:42:21 +00:00
Ulises Manuel 7de1f95054 [#18934] universal scanner in wallet receive (#19409)
* Fix linear-gradient breaking when `customization-color` is unknown

* Fix exception when scanning an address due to non-existing navigation route

* Dispatches universal QR code scanner on share address modal
2024-03-27 10:01:28 -06:00
jakub 9e71fc2d14 ci: make contract tests stage optional
Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-03-27 14:12:28 +01:00
jakub e44b29f3a6 ci: bump jenkins-lib to fix sepolia token typo
Depends on:
https://github.com/status-im/status-jenkins-lib/commit/8331a433

Also replaces `TARGET` with `PLATFORM` to not conflict with Nix shell.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2024-03-27 13:10:49 +01:00
Ibrahem Khalil e5ed5e624b Communities - Address for airdrops/permissions screen issues (#19296) 2024-03-27 11:46:42 +02:00
Mohsen f075cd0bdc [#19117] fix: setting over scroll shows gap (#19352) 2024-03-26 19:34:16 +03:00
Mohamed Javid 1d44472aa6 [Feature] Enable Test Networks by default on Dev, E2E and PR builds (#19365)
This commit enables Test Networks in Dev, E2E and PR Builds by default and disables in Release/Nightly Builds.

This enables in create account or restore account flow. If you upgrade the app from the old build with an existing profile, it will use the last saved (test networks enabled) state of that profile.

Signed-off-by: Mohamed Javid <19339952+smohamedjavid@users.noreply.github.com>
2024-03-26 20:55:22 +05:30
Sean Hagstrom 495bc91989 fix: re-route a user's own profile link to their settings page (#19389) 2024-03-26 15:04:49 +00:00
Jamie Caprani bcf8e39e84 chore(onboarding): qualify screen keywords (#19285) 2024-03-26 14:06:43 +00:00
Ibrahem Khalil c86cdf9ac8 Hide community channels when hide channels option is enabled 2024-03-26 12:08:19 +00:00
Andrea Maria Piana 1948c11508 Use env for bash 2024-03-26 12:00:54 +00:00
Ajay SivanandYevheniia Berdnyk 02d4618997 Remove 'Community admins will review your request' text from community overview screen (#19361)
* Remove 'Community admins will review your request' text from community overview screen

* Use the button label 'Request to join' for all communities

* e2e: updated test

---------

Co-authored-by: Yevheniia Berdnyk <ie.berdnyk@gmail.com>
2024-03-26 04:56:39 -07:00
Lungu Cristian fd4d64c53e Fix chat spacings (#19015)
* fix: chat system messages spacing

* fix: spacing between chat actions and time header

* fix: distance from last message to shell button

* fix: addressed review comment

* fix: conflict bug

* fix: chat spacings
2024-03-26 12:07:48 +02:00
Lungu Cristian 17b64ab3ba Remove not-implemented box from sticker/emoji messages (#19255)
* feat: replaced old emoji component with new one

* feat: replaced old sticker component with the new one

* ref: pass only url to sticker

* fix: renamed ns and passing only needed props

* fix: destructuring instead of select-keys & assoc

* fix: formatting
2024-03-26 11:53:33 +02:00
Parvesh Monu 6a88a34d34 add empty check for keychain credentials server (#19242) 2024-03-26 12:15:35 +05:30
Ibrahem Khalil 3be1532b32 All addresses text is not updated when changing accounts (#19379) 2024-03-25 22:14:40 +02:00
Ibrahem Khalil 44846c80c8 Error when marking a community notification as read in the activity center #19388 (#19390) 2024-03-25 21:36:24 +02:00
Ulises Manuel a405de62e6 [#18833] Confirm button disappearing while editing address (#19186)
* Fix button disappearing when keyboard is hidden

* Improve keyboard scrolling
2024-03-25 09:00:10 -06:00
flexsurfer 06dc9ea1d3 Unable to enter/clear smoothly the data into contacts field #19384 (#19385) 2024-03-25 15:17:08 +01:00
Ajay Sivan 32a4bb1153 fix: very small token values are being displayed in scientific format (#19349) 2024-03-25 06:05:53 -07:00
Sean Hagstrom 418053b21e Tweak UI for contact request notifications (#19337)
* fix: ensure contact-request notifications are displayed as notifications

* fix: provide context-theme for notification sub-components

* fix: adjust font weight for notification text

* fix: adjust alignment of user-avatar inside a notification with a header and body

* tidy: rename override-theme to theme inside notifications

* fix: update notifications component to use `user` prop instead of `avatar`

* tweak: adapt notification to avatar to vertically center when only displaying header or title

* fix: use title font-size for contact-request-accepted notification

* fix: allow for custom avatar component prop in quo notification component

* fix: ensure we use the correct font-weight for contact-request-accepted notification

* tidy: fix formatting
2024-03-25 10:17:47 +00:00
flexsurfer 2528efb538 fix input issues (#19341) 2024-03-25 10:42:20 +01:00
160 changed files with 1923 additions and 1313 deletions
+1 -1
View File
@@ -26,7 +26,7 @@
malli.generator malli.generator
malli.transform malli.transform
malli.util malli.util
promesa.core p
promesa.core promesa
schema.core schema
status-im.feature-flags ff
taoensso.timbre log}}
+1
View File
@@ -34,3 +34,4 @@ STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
TEST_STATEOFUS=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
+1
View File
@@ -33,3 +33,4 @@ TWO_MINUTES_SYNCING=1
STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
+1
View File
@@ -35,3 +35,4 @@ ENABLE_QUO_PREVIEW=1
STICKERS_TEST_ENABLED=1
LOCAL_PAIRING_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=1
TEST_NETWORKS_ENABLED=1
+1
View File
@@ -22,3 +22,4 @@ COMMUNITIES_ENABLED=1
DATABASE_MANAGEMENT_ENABLED=1
DELETE_MESSAGE_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
+1
View File
@@ -20,3 +20,4 @@ MAX_IMAGES_BATCH=1
DELETE_MESSAGE_ENABLED=1
COLLECTIBLES_ENABLED=1
FAST_CREATE_COMMUNITY_ENABLED=0
TEST_NETWORKS_ENABLED=0
+13 -13
View File
@@ -375,25 +375,25 @@ test-contract: export SHADOW_NS_REGEXP := ^tests\.contract-test.*$$
test-contract: ##@test Run contract tests
test-contract: _test-clojure
android-test: jsbundle
android-test: export TARGET := android
android-test:
test-android: jsbundle
test-android: export TARGET := android
test-android: ##@test Android Gradle test
cd android && ./gradlew test
component-test-watch: export TARGET := clojure
component-test-watch: export COMPONENT_TEST := true
component-test-watch: export BABEL_ENV := test
component-test-watch: export JEST_USE_SILENT_REPORTER := false
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
test-component-watch: export TARGET := clojure
test-component-watch: export COMPONENT_TEST := true
test-component-watch: export BABEL_ENV := test
test-component-watch: export JEST_USE_SILENT_REPORTER := false
test-component-watch: ##@ Watch tests and re-run no changes to cljs files
@scripts/check-metro-shadow-process.sh
rm -rf ./component-spec
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js --testEnvironment node ' -e cljs
component-test: export TARGET := clojure
component-test: export COMPONENT_TEST := true
component-test: export BABEL_ENV := test
component-test: export JEST_USE_SILENT_REPORTER := false
component-test: ##@test Run component tests once in NodeJS
test-component: export TARGET := clojure
test-component: export COMPONENT_TEST := true
test-component: export BABEL_ENV := test
test-component: export JEST_USE_SILENT_REPORTER := false
test-component: ##@test Run component tests once in NodeJS
@scripts/check-metro-shadow-process.sh
rm -rf ./component-spec
yarn shadow-cljs compile component-test && \
+5 -5
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -34,10 +34,10 @@ pipeline {
}
environment {
LANG = "en_US.UTF-8"
LC_ALL = "en_US.UTF-8"
LANGUAGE = "en_US.UTF-8"
TARGET = "android${utils.isE2EBuild() ? "-e2e" : ""}"
LANG = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
PLATFORM = "android${utils.isE2EBuild() ? "-e2e" : ""}"
BUILD_ENV = 'prod'
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
FASTLANE_DISABLE_COLORS = 1
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label 'linux' }
+5 -5
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -34,10 +34,10 @@ pipeline {
}
environment {
LANG = "en_US.UTF-8"
LC_ALL = "en_US.UTF-8"
LANGUAGE = "en_US.UTF-8"
TARGET = 'ios'
LANG = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
PLATFORM = 'ios'
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
FASTLANE_DISABLE_COLORS = 1
BUNDLE_PATH = "${HOME}/.bundle"
+34 -41
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -29,61 +29,47 @@ pipeline {
description: 'Specify build type. Values: pr / e2e / nightly / release',
defaultValue: 'pr',
)
booleanParam(
name: 'RUN_CONTRACT_TESTS',
description: 'Whether to run optional and slow contract tests.',
defaultValue: false,
)
}
environment {
LANG = "en_US.UTF-8"
LC_ALL = "en_US.UTF-8"
LANGUAGE = "en_US.UTF-8"
TARGET = 'tests'
LANG = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
PLATFORM = 'tests'
BUILD_ENV = 'prod'
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
LOG_FILE = utils.pkgFilename(ext: 'log', arch: 'tests')
CLJ_LINTER_PRINT_WARNINGS = 'true'
}
stages {
stage('Checks') {
stage('Test') {
parallel {
stage('Lint') {
steps {
sh """#!/bin/bash
set -eo pipefail
make lint CLJ_LINTER_PRINT_WARNINGS=true 2>&1 | tee ${LOG_FILE}
"""
}
steps { make('lint') }
}
stage('Unit Tests') {
steps {
sh """#!/bin/bash
set -eo pipefail
make test-unit 2>&1 | tee -a ${LOG_FILE}
"""
}
stage('Unit') {
steps { make('test-unit') }
}
stage('Component') {
steps { make('test-component') }
}
}
}
stage('Contract Tests') {
steps {
sh """#!/bin/bash
set -eo pipefail
make test-contract 2>&1 | tee -a ${LOG_FILE}
"""
}
}
stage('Integration Tests') {
steps {
sh """#!/bin/bash
set -eo pipefail
make test-integration 2>&1 | tee -a ${LOG_FILE}
"""
}
}
stage('Component Tests') {
steps {
sh """#!/bin/bash
set -eo pipefail
make component-test 2>&1 | tee -a ${LOG_FILE}
"""
stage('Heavy Test') {
parallel {
stage('Contract') {
when { expression { params.RUN_CONTRACT_TESTS } }
steps { make('test-contract') }
}
stage('Integration') {
steps { make('test-integration') }
}
}
}
stage('Upload') {
@@ -100,3 +86,10 @@ pipeline {
always { sh 'make purge' }
}
}
def make(target) {
sh """#!/bin/bash
set -eo pipefail
make ${target} 2>&1 | tee -a ${LOG_FILE}
"""
}
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
+5 -5
View File
@@ -1,14 +1,14 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label 'macos' }
environment {
LANG = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
TARGET = 'ios'
LANG = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
PLATFORM = 'ios'
FASTLANE_DISABLE_COLORS = 1
/* avoid writing to r/o /nix */
GEM_HOME = '~/.rubygems'
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label params.AGENT_LABEL }
+5 -5
View File
@@ -1,14 +1,14 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent { label 'linux' }
environment {
LANG = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
TARGET = 'ios'
LANG = 'en_US.UTF-8'
LANGUAGE = 'en_US.UTF-8'
LC_ALL = 'en_US.UTF-8'
PLATFORM = 'ios'
FASTLANE_DISABLE_COLORS = 1
/* avoid writing to r/o /nix */
GEM_HOME = '~/.rubygems'
+1 -1
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env groovy
library 'status-jenkins-lib@v1.8.7'
library 'status-jenkins-lib@v1.8.12'
pipeline {
agent {
+5 -5
View File
@@ -16,10 +16,10 @@ Both of these links are showing it for React-Testing-Library (not Native) howeve
## Running the tests
To run these tests there are two methods.
`make component-test`
`make test-component`
setups and runs the test suite once.
`make component-test-watch`
`make test-component-watch`
setups and runs the test suite and watches for code changes will then retrigger the test suite.
## Writing Tests
@@ -38,7 +38,7 @@ There is a file of utility functions defined in "src/test_helpers/component.cljs
## Configuration
Status Mobile has a bespoke tech stack, as such there is more complexities to configuring the tests.
### Shadow-CLJS
### Shadow-CLJS
the configuration for compiling our tests are defined in the "shadow-cljs.edn" file.
The three main parts of this are
`:target :npm-module`
@@ -47,9 +47,9 @@ Needed for the configuration we are using
a vector of entry points for the test files.
and the `ns-regexp` to specify what tests to find. Since we have multiple forms of tests we decided that "component-spec" is the least likely to detect the wrong file type.
It's worth knowing that our tests are compiled to JS and then run in the temporary folder `component-tests`.
It's worth knowing that our tests are compiled to JS and then run in the temporary folder `component-tests`.
### Jest
There is also further configuration for Jest in "test/jest". There is a jest config file which has some mostly standard configuration pieces, where the tests live, what environment variables are set etc. This is documented by Jest here: https://jestjs.io/docs/configuration
There is also a setup file which is used to set some global and default values. Additionally this file is used to mock some of the react native (among other) dependencies
There is also a setup file which is used to set some global and default values. Additionally this file is used to mock some of the react native (among other) dependencies.
+2 -2
View File
@@ -54,13 +54,13 @@ Here I'm showing a terminal-only experience using Tmux (left pane Emacs, right p
To run tests:
```
make component-test
make test-component
```
Also test watcher can be launched. It will re-run the entire test suite when any file is modified
```
make component-test-watch
make test-component-watch
```
Check [component tests doc](./component-tests-overview.md) for more.
+8
View File
@@ -61,6 +61,8 @@
D1786306E0184916B11F4C37 /* Inter-Medium.otf in Resources */ = {isa = PBXBuildFile; fileRef = B2A38FC3D3954DE7B2B171F8 /* Inter-Medium.otf */; };
D84616FB563A48EBB1678699 /* Inter-Bold.otf in Resources */ = {isa = PBXBuildFile; fileRef = CD4A2C27D6D5473184DC1F7E /* Inter-Bold.otf */; };
D99C50E5E18942A39C8DDF61 /* Inter-BoldItalic.otf in Resources */ = {isa = PBXBuildFile; fileRef = B321D25F4493470980039457 /* Inter-BoldItalic.otf */; };
E9AC7FD92BB8FDAB0024A0AF /* HelloWorldJSI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */; };
E9AC7FDA2BB8FDAB0024A0AF /* HelloWorldJSI.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
@@ -154,6 +156,8 @@
CD4A2C27D6D5473184DC1F7E /* Inter-Bold.otf */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 9; includeInIndex = 0; lastKnownFileType = unknown; name = "Inter-Bold.otf"; path = "../resources/fonts/Inter-Bold.otf"; sourceTree = "<group>"; };
CE4E31B21D8695250033ED64 /* Statusgo.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = Statusgo.xcframework; path = "../modules/react-native-status/ios/RCTStatus/Statusgo.xcframework"; sourceTree = "<group>"; };
D1CE733E3486B3A8B9185945 /* Pods-Status-StatusIm-StatusImTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; path = "Target Support Files/Pods-Status-StatusIm-StatusImTests/Pods-Status-StatusIm-StatusImTests.debug.xcconfig"; sourceTree = "<group>"; };
E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HelloWorldJSI.cpp; path = "../modules/react-native-status/jsi/HelloWorldJSI.cpp"; sourceTree = "<group>"; };
E9AC7FD82BB8FDAB0024A0AF /* HelloWorldJSI.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HelloWorldJSI.h; path = "../modules/react-native-status/jsi/HelloWorldJSI.h"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@@ -268,6 +272,8 @@
83CBB9F61A601CBA00E9B192 = {
isa = PBXGroup;
children = (
E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */,
E9AC7FD82BB8FDAB0024A0AF /* HelloWorldJSI.h */,
65F6941825780A4F00A45E76 /* Bridge.swift */,
3AAD2AB624A3A5F10075D594 /* StatusImPR */,
13B07FAE1A68108700A75B9A /* StatusIm */,
@@ -737,6 +743,7 @@
65F6941925780A4F00A45E76 /* Bridge.swift in Sources */,
13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */,
3A2626CF245C3F2200D5F94B /* Dummy.swift in Sources */,
E9AC7FD92BB8FDAB0024A0AF /* HelloWorldJSI.cpp in Sources */,
13B07FC11A68108700A75B9A /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -748,6 +755,7 @@
65F6941B25780A4F00A45E76 /* Bridge.swift in Sources */,
3AAD2ABC24A3A60E0075D594 /* AppDelegate.mm in Sources */,
3AAD2ABD24A3A60E0075D594 /* Dummy.swift in Sources */,
E9AC7FDA2BB8FDAB0024A0AF /* HelloWorldJSI.cpp in Sources */,
3AAD2ABE24A3A60E0075D594 /* main.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
+11
View File
@@ -73,6 +73,17 @@ extern "C" NSString* StatusgoImageServerTLSCert();
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
[RNSplashScreen show];
RCTCxxBridge *bridge = (RCTCxxBridge *)[[_bridge batchedBridge] valueForKey:@"_batchedBridge"];
facebook::react::RCTJSIExecutorFactory *executorFactory = [bridge jsExecutorFactoryForBridge:bridge];
if (executorFactory) {
bridge.jsiExecutorFactory = ^{
facebook::jsi::Runtime *runtime = executorFactory();
HelloWorldJSI::install(*runtime);
return runtime;
};
}
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
@@ -0,0 +1,17 @@
#include "HelloWorldJSI.h"
#include <jsi/jsi.h>
#include <iostream>
using namespace facebook::jsi;
void HelloWorldJSI::install(Runtime& runtime) {
auto helloWorldFunction = Function::createFromHostFunction(runtime,
PropNameID::forAscii(runtime, "helloWorld"),
0,
[](Runtime& runtime, Value thisValue, Value* arguments, size_t count) -> Value {
std::cout << "Hello, World! from C++" << std::endl;
return Value::undefined();
});
runtime.global().setProperty(runtime, "helloWorld", std::move(helloWorldFunction));
}
@@ -0,0 +1,13 @@
#pragma once
#include <jsi/jsi.h>
using namespace facebook::jsi;
class HelloWorldJSI {
public:
static void install(Runtime& runtime);
private:
static void helloWorld(Runtime& runtime, Value thisValue, Value* arguments, size_t count);
};
Binary file not shown.

After

Width:  |  Height:  |  Size: 181 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 203 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

+1 -1
View File
@@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# Increment a version string using Semantic Versioning (SemVer) terminology.
+53 -47
View File
@@ -62,25 +62,29 @@
(defn <-color
[value]
(if (string/starts-with? value "#") value (keyword value)))
(if (and (some? value)
(string/starts-with? value "#"))
value
(keyword value)))
(defn <-rpc
[chat]
(-> chat
(set/rename-keys {:id :chat-id
:communityId :community-id
:syncedFrom :synced-from
:syncedTo :synced-to
:membershipUpdateEvents :membership-update-events
:deletedAtClockValue :deleted-at-clock-value
:chatType :chat-type
:unviewedMessagesCount :unviewed-messages-count
:unviewedMentionsCount :unviewed-mentions-count
:lastMessage :last-message
:lastClockValue :last-clock-value
:invitationAdmin :invitation-admin
:profile :profile-public-key
:muteTill :muted-till})
(set/rename-keys {:id :chat-id
:communityId :community-id
:syncedFrom :synced-from
:syncedTo :synced-to
:membershipUpdateEvents :membership-update-events
:deletedAtClockValue :deleted-at-clock-value
:chatType :chat-type
:unviewedMessagesCount :unviewed-messages-count
:unviewedMentionsCount :unviewed-mentions-count
:lastMessage :last-message
:lastClockValue :last-clock-value
:invitationAdmin :invitation-admin
:profile :profile-public-key
:muteTill :muted-till
:hideIfPermissionsNotMet :hide-if-permissions-not-met?})
rpc->type
unmarshal-members
(update :last-message #(when % (messages/<-rpc %)))
@@ -89,38 +93,40 @@
(defn <-rpc-js
[^js chat]
(-> {:name (.-name chat)
:description (.-description chat)
:color (<-color (.-color chat))
:emoji (.-emoji chat)
:timestamp (.-timestamp chat)
:alias (.-alias chat)
:muted (.-muted chat)
:joined (.-joined chat)
:muted-till (.-muteTill chat)
:chat-id (.-id chat)
:community-id (.-communityId chat)
:synced-from (.-syncedFrom chat)
:synced-to (.-syncedTo chat)
:deleted-at-clock-value (.-deletedAtClockValue chat)
:chat-type (.-chatType chat)
:unviewed-messages-count (.-unviewedMessagesCount chat)
:unviewed-mentions-count (.-unviewedMentionsCount chat)
:last-message {:content {:text (.-text chat)
:parsed-text (types/js->clj (.-parsedText chat))
:response-to (.-responseTo chat)}
:content-type (.-contentType chat)
:community-id (.-contentCommunityId chat)
:outgoing (boolean (.-outgoingStatus chat))
:album-images-count (.-albumImagesCount chat)
:from (.-from chat)
:deleted? (.-deleted chat)
:deleted-for-me? (.-deletedForMe chat)}
:last-clock-value (.-lastClockValue chat)
:profile-public-key (.-profile chat)
:highlight (.-highlight chat)
:active (.-active chat)
:members (types/js->clj (.-members chat))}
(-> {:name (.-name chat)
:description (.-description chat)
:color (<-color (.-color chat))
:emoji (.-emoji chat)
:timestamp (.-timestamp chat)
:alias (.-alias chat)
:muted (.-muted chat)
:joined (.-joined chat)
:muted-till (.-muteTill chat)
:chat-id (.-id chat)
:community-id (.-communityId chat)
:synced-from (.-syncedFrom chat)
:synced-to (.-syncedTo chat)
:deleted-at-clock-value (.-deletedAtClockValue chat)
:chat-type (.-chatType chat)
:unviewed-messages-count (.-unviewedMessagesCount chat)
:unviewed-mentions-count (.-unviewedMentionsCount chat)
:last-message {:content {:text (.-text chat)
:parsed-text (types/js->clj (.-parsedText
chat))
:response-to (.-responseTo chat)}
:content-type (.-contentType chat)
:community-id (.-contentCommunityId chat)
:outgoing (boolean (.-outgoingStatus chat))
:album-images-count (.-albumImagesCount chat)
:from (.-from chat)
:deleted? (.-deleted chat)
:deleted-for-me? (.-deletedForMe chat)}
:last-clock-value (.-lastClockValue chat)
:profile-public-key (.-profile chat)
:highlight (.-highlight chat)
:active (.-active chat)
:members (types/js->clj (.-members chat))
:hide-if-permissions-not-met (.-hideIfPermissionsNotMet chat)}
rpc->type
unmarshal-members))
@@ -27,10 +27,11 @@
(assoc acc
(name k)
(-> v
(assoc :token-gated? (:tokenGated v)
:can-post? (:canPost v)
:can-view? (:canView v))
(dissoc :canPost :tokenGated :canView)
(assoc :token-gated? (:tokenGated v)
:can-post? (:canPost v)
:can-view? (:canView v)
:hide-if-permissions-not-met? (:hideIfPermissionsNotMet v))
(dissoc :canPost :tokenGated :canView :hideIfPermissionsNotMet)
(update :members walk/stringify-keys))))
{}
chats))
@@ -63,6 +64,7 @@
:canJoin :can-join?
:requestedToJoinAt :requested-to-join-at
:isMember :is-member?
:outroMessage :outro-message
:adminSettings :admin-settings
:tokenPermissions :token-permissions
:communityTokensMetadata :tokens-metadata
+1 -1
View File
@@ -18,7 +18,7 @@
[{:keys [db] :as cofx}]
(rf/merge cofx
{:db db}
(navigation/pop-to-root :profiles)))
(navigation/pop-to-root :screen/profile.profiles)))
(rf/defn login-pin-more-icon-pressed
{:events [:keycard.login.pin.ui/more-icon-pressed]}
+3 -2
View File
@@ -74,7 +74,8 @@
(assoc :recovered-account? true))
:keycard/check-nfc-enabled nil}
(bottom-sheet/hide-bottom-sheet-old)
(navigation/navigate-to-within-stack [:keycard-recovery-intro :new-to-status])))
(navigation/navigate-to-within-stack [:keycard-recovery-intro
:screen/onboarding.new-to-status])))
(rf/defn access-key-pressed
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
@@ -127,7 +128,7 @@
:multiaccount-whisper-public-key)}
(navigation/navigate-to (if platform/android?
:notifications-settings
:welcome)
:screen/onboarding.welcome)
nil)))
(rf/defn intro-wizard
@@ -2,7 +2,6 @@
(:require
[legacy.status-im.react-native.resources :as resources]
[legacy.status-im.ui.components.colors :as quo.colors]
[legacy.status-im.ui.components.fast-image :as fast-image]
[legacy.status-im.ui.screens.chat.message.legacy-style :as style]
[quo.core :as quo]
[quo.foundations.colors :as colors]
@@ -145,23 +144,6 @@
[rn/text {:style (style/status-text)}]
(-> content :parsed-text peek :children))]])
;; EMOJI
(defn emoji
[]
(fn [{:keys [content] :as message}]
[rn/view (style/message-view message)
[rn/view {:style (style/message-view-content)}
[rn/view {:style (style/style-message-text)}
[rn/text {:style (style/emoji-message message)}
(:text content)]]]]))
;; STICKER
(defn sticker
[{:keys [content]}]
[fast-image/fast-image
{:style {:margin 10 :width 140 :height 140}
:source {:uri (str (-> content :sticker :url) "&download=true")}}])
(defn contact-request-status-pending
[]
[rn/view {:style {:flex-direction :row}}
@@ -13,6 +13,7 @@
[{:keys [color pressed? theme]}]
{:height 102
:padding 12
:padding-bottom 10
:border-radius 16
:background-color (colors/resolve-color color theme (if pressed? 20 10))
:justify-content :space-between})
@@ -20,4 +21,5 @@
(def channel-action-row
{:flex-direction :row
:justify-content :space-between
:align-items :center})
:align-items :center
:padding-right 2})
+4 -3
View File
@@ -8,9 +8,10 @@
(defn date
[value]
[rn/view
{:margin-vertical 12
:padding-right 20
:padding-left 60}
{:padding-top 8
:padding-bottom 12
:padding-right 20
:padding-left 60}
[text/text
{:weight :medium
:accessibility-label :divider-date-text
@@ -0,0 +1,54 @@
(ns quo.components.drawers.drawer-action.component-spec
(:require
[quo.components.drawers.drawer-action.view :as drawer-action]
[quo.foundations.colors :as colors]
[test-helpers.component :as h]))
(h/describe "Drawers: drawer-action"
(h/test "default render"
(h/render-with-theme-provider [drawer-action/view {}])
(h/is-truthy (h/query-by-label-text :container)))
(h/test "on-press-in changes internal state to :pressed"
(h/render-with-theme-provider [drawer-action/view {}])
(h/fire-event :on-press-in (h/get-by-label-text :container))
(h/wait-for #(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})))
(h/test "render default action with state :selected"
(h/render-with-theme-provider [drawer-action/view {:state :selected}])
(h/has-style (h/query-by-label-text :container)
{:backgroundColor (colors/resolve-color :blue :light 5)})
(h/is-truthy (h/query-by-label-text :check-icon)))
(h/test "call on-press"
(let [on-press (h/mock-fn)]
(h/render-with-theme-provider [drawer-action/view {:on-press on-press}])
(h/fire-event :on-press (h/get-by-label-text :container))
(h/was-called on-press)))
(h/test "render :arrow action"
(h/render-with-theme-provider [drawer-action/view {:action :arrow}])
(h/is-truthy (h/query-by-label-text :arrow-icon)))
(h/test "render :toggle action"
(h/render-with-theme-provider [drawer-action/view {:action :toggle}])
(h/is-truthy (h/query-by-label-text "toggle-off")))
(h/test "render :toggle action with state :selected"
(h/render-with-theme-provider [drawer-action/view
{:action :toggle
:state :selected}])
(h/is-truthy (h/query-by-label-text "toggle-on"))
(h/has-style (h/query-by-label-text :container)
{:backgroundColor :transparent}))
(h/test "render default action with icon, title, description"
(h/render-with-theme-provider [drawer-action/view
{:icon :i/contact
:title "Check contact"
:description "Just a small desc"}])
(h/is-truthy (h/query-by-label-text :left-icon))
(h/is-truthy (h/query-by-text "Check contact"))
(h/is-truthy (h/query-by-text "Just a small desc"))))
@@ -0,0 +1,16 @@
(ns quo.components.drawers.drawer-action.schema)
(def ?schema
[:=>
[:cat
[:map {:closed true}
[:action {:optional true} [:maybe [:enum :arrow :toggle]]]
[:icon {:optional true} [:maybe :keyword]]
[:description {:optional true} [:maybe :string]]
[:state {:optional true} [:maybe [:enum :selected]]]
[:title {:optional true} :string]
[:on-press {:optional true} [:maybe fn?]]
[:customization-color {:optional true}
[:maybe :schema.common/customization-color]]
[:blur? {:optional true} [:maybe :boolean]]]]
:any])
@@ -0,0 +1,55 @@
(ns quo.components.drawers.drawer-action.style
(:require
[quo.foundations.colors :as colors]))
(defn- background-color
[{:keys [state action customization-color theme pressed? blur?]}]
(let [checked? (and (= :selected state) (nil? action))]
(cond
(and (or checked? pressed?) blur?)
colors/white-opa-5
(or pressed? checked?)
(colors/resolve-color customization-color theme 5)
:else :transparent)))
(defn container
[{:keys [description?] :as props}]
{:flex-direction :row
:align-items :center
:padding-vertical (if description? 8 13)
:padding-horizontal 13
:border-radius 12
:background-color (background-color props)})
(defn text-container
[]
{:flex 1
:margin-right 12})
(defn- neutral-color
[theme blur?]
(if blur?
colors/white-70-blur
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme)))
(defn left-icon
[]
{:align-self :flex-start
:margin-right 13
:margin-top 1})
(defn icon-color
[{:keys [theme blur?]}]
(neutral-color theme blur?))
(defn desc
[{:keys [theme blur?]}]
{:color (neutral-color theme blur?)})
(defn check-color
[{:keys [theme blur? customization-color]}]
(if blur?
colors/white-70-blur
(colors/resolve-color customization-color theme)))
@@ -0,0 +1,73 @@
(ns quo.components.drawers.drawer-action.view
(:require
[quo.components.drawers.drawer-action.schema :as component-schema]
[quo.components.drawers.drawer-action.style :as style]
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
[quo.components.selectors.selectors.view :as selectors]
[quo.theme :as theme]
[react-native.core :as rn]
[schema.core :as schema]))
(defn view-internal
[{:keys [action icon description state title on-press
customization-color blur?]
:or {customization-color :blue
blur? false}}]
(let [theme (theme/use-theme-value)
[pressed? set-pressed] (rn/use-state false)
on-press-in (rn/use-callback #(set-pressed true))
on-press-out (rn/use-callback #(set-pressed false))]
[rn/pressable
{:on-press on-press
:on-press-in on-press-in
:on-press-out on-press-out
:style (style/container {:state state
:action action
:customization-color customization-color
:theme theme
:pressed? pressed?
:description? (not-empty description)
:blur? blur?})
:accessibility-label :container}
(when icon
[icon/icon icon
{:accessibility-label :left-icon
:container-style (style/left-icon)
:color (style/icon-color {:theme theme
:blur? blur?})}])
[rn/view {:style (style/text-container)}
[text/text {:weight :medium}
title]
(when (seq description)
[text/text
{:size :paragraph-2
:style (style/desc {:theme theme
:blur? blur?})}
description])]
(cond
(= action :toggle)
[selectors/view
{:theme theme
:label-prefix "toggle"
:customization-color customization-color
:type :toggle
:checked? (= state :selected)}]
(= action :arrow)
[icon/icon :i/chevron-right
{:accessibility-label :arrow-icon
:color (style/icon-color {:theme theme
:blur? blur?})}]
(= state :selected)
[icon/icon :i/check
{:accessibility-label :check-icon
:color (style/check-color {:theme theme
:blur? blur?
:customization-color customization-color})}])]))
(def view (schema/instrument #'view-internal component-schema/?schema))
@@ -81,7 +81,8 @@
(let [tag-type (or context-tag-type :account)]
[rn/view
{:accessibility-label :context-tag-wrapper
:style {:flex-wrap :wrap}}
:style {:flex-wrap :wrap
:margin-top 4}}
[context-tag/view
{:type tag-type
:account-name account-name
@@ -12,9 +12,9 @@
;; the `:or` destructuring won't work because it's only applied when the
;; `:customization-color` key is non-existent. While deleting an account the key exists
;; and has a `nil` value.
(when customization-color
(let [color-top (colors/resolve-color customization-color 50 20)
color-bottom (colors/resolve-color customization-color 50 0)]
(let [color-top (colors/resolve-color customization-color 50 20)
color-bottom (colors/resolve-color customization-color 50 0)]
(when (and color-top color-bottom)
[linear-gradient/linear-gradient
{:accessibility-label :gradient-cover
:colors [color-top color-bottom]
@@ -61,7 +61,7 @@
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
(h/has-prop (h/get-by-label-text :address-text-input)
:placeholder-text-color
colors/neutral-30))))))
colors/neutral-40))))))
(h/test "on blur with text blur? true"
(with-redefs [clipboard/get-string #(% "")]
@@ -75,7 +75,7 @@
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
(h/has-prop (h/get-by-label-text :address-text-input)
:placeholder-text-color
colors/neutral-80-opa-20))))))
colors/neutral-80-opa-40))))))
(h/test "on blur with no text and blur? false"
(with-redefs [clipboard/get-string #(% "")]
@@ -58,78 +58,64 @@
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
valid-ens-or-address? container-style]}]
(let [theme (quo.theme/use-theme-value)
[status set-status] (rn/use-state :default)
value (rn/use-ref-atom nil)
[_ trigger-render-value] (rn/use-state @value)
[focused? set-focused] (rn/use-state false)
on-change (rn/use-callback
(fn [text]
(let [address? (when address-regex
(boolean (re-matches address-regex text)))
ens? (when ens-regex
(boolean (re-matches ens-regex text)))]
(reset! value text)
(if (> (count text) 0)
(set-status :typing)
(set-status :active))
(when on-change-text
(on-change-text text))
(when (and on-detect-ens ens?)
(set-status :loading)
(on-detect-ens text #(set-status :typing)))
(when (and address? on-detect-address)
(set-status :loading)
(on-detect-address text))
(when (and (not address?)
(not ens?)
on-detect-unclassified)
(on-detect-unclassified text)))))
set-value (rn/use-callback
(fn [new-value]
(reset! value new-value)
(on-change new-value)
(trigger-render-value new-value)))
on-paste (rn/use-callback
(fn []
(clipboard/get-string
(fn [clipboard]
(when-not (empty? clipboard)
(set-value clipboard))))))
on-clear (rn/use-callback
(fn []
(set-value "")
(set-status (if focused? :active :default))
(when on-change-text
(on-change-text ""))
(when on-clear
(on-clear)))
[focused?])
on-clear (rn/use-callback
(fn []
(set-value "")
(set-status (if focused? :active :default))
(when on-change-text
(on-change-text ""))
(when on-clear
(on-clear)))
[focused?])
on-scan (when on-scan (rn/use-callback #(on-scan set-value)))
on-focus (rn/use-callback
(fn []
(when (= (count @value) 0)
(let [theme (quo.theme/use-theme-value)
[status set-status] (rn/use-state :default)
[value set-value] (rn/use-state nil)
[focused? set-focused] (rn/use-state false)
on-change (rn/use-callback
(fn [text]
(let [address? (when address-regex
(boolean (re-matches address-regex text)))
ens? (when ens-regex
(boolean (re-matches ens-regex text)))]
(set-value text)
(if (> (count text) 0)
(set-status :typing)
(set-status :active))
(set-focused true)
(when on-focus (on-focus))))
on-blur (rn/use-callback
(fn []
(when (= status :active)
(set-status :default))
(set-focused false)
(when on-blur (on-blur)))
[status])
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
[status theme blur?])]
(when on-change-text
(on-change-text text))
(when (and on-detect-ens ens?)
(set-status :loading)
(on-detect-ens text #(set-status :typing)))
(when (and address? on-detect-address)
(set-status :loading)
(on-detect-address text))
(when (and (not address?)
(not ens?)
on-detect-unclassified)
(on-detect-unclassified text)))))
on-paste (rn/use-callback
(fn []
(clipboard/get-string
(fn [clipboard]
(when-not (empty? clipboard)
(on-change clipboard))))))
on-clear (rn/use-callback
(fn []
(on-change "")
(set-status (if focused? :active :default))
(when on-change-text
(on-change-text ""))
(when on-clear
(on-clear)))
[focused?])
on-scan (rn/use-callback #(when on-scan (on-scan on-change))
[on-scan])
on-focus (rn/use-callback
(fn []
(when (= (count value) 0)
(set-status :active))
(set-focused true)
(when on-focus (on-focus))))
on-blur (rn/use-callback
(fn []
(when (= status :active)
(set-status :default))
(set-focused false)
(when on-blur (on-blur)))
[status])
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
[status theme blur?])]
(rn/use-mount #(on-change (or default-value "")))
[rn/view {:style (style/container container-style)}
[rn/text-input
@@ -137,7 +123,7 @@
:style (style/input-text theme)
:placeholder (i18n/label :t/name-ens-or-address)
:placeholder-text-color placeholder-text-color
:value @value
:value value
:auto-complete (when platform/ios? :off)
:auto-capitalize :none
:auto-correct false
+25 -11
View File
@@ -57,14 +57,19 @@
"Custom properties that must be removed from properties map passed to InputText."
[:type :blur? :error? :right-icon :left-icon :disabled? :small? :button
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur
:container-style])
:container-style :ref])
(defn- base-input
[{:keys [blur? error? right-icon left-icon disabled? small? button
label char-limit multiline? clearable? on-focus on-blur container-style
on-change-text on-char-limit-reach weight default-value]
on-change-text on-char-limit-reach weight default-value on-clear]
:as props}]
(let [theme (quo.theme/use-theme-value)
ref (rn/use-ref-atom nil)
on-ref (rn/use-callback (fn [value]
(when (:ref props)
((:ref props) value))
(reset! ref value)))
[status set-status] (rn/use-state :default)
internal-on-focus (rn/use-callback #(set-status :focus))
internal-on-blur (rn/use-callback #(set-status :default))
@@ -93,6 +98,15 @@
:else status)
colors-by-status (style/status-colors status-kw blur? theme)
variant-colors (style/variants-colors blur? theme)
clear-on-press (rn/use-callback (fn []
(.clear ^js @ref)
(when on-clear (on-clear)))
[on-clear])
right-icon (or right-icon
(when clearable?
{:style-fn style/clear-icon
:icon-name :i/clear
:on-press clear-on-press}))
clean-props (apply dissoc props custom-props)]
[rn/view {:style container-style}
(when (or label char-limit)
@@ -108,7 +122,8 @@
:small? small?
:icon-name icon-name}])
[rn/text-input
(cond-> {:style (style/input colors-by-status small? multiple-lines? weight)
(cond-> {:ref on-ref
:style (style/input colors-by-status small? multiple-lines? weight)
:accessibility-label :input
:placeholder-text-color (:placeholder colors-by-status)
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
@@ -147,7 +162,10 @@
[{:keys [default-shown?]
:or {default-shown? false}
:as props}]
(let [[password-shown? set-password-shown] (rn/use-state default-shown?)]
(let [[password-shown?
set-password-shown] (rn/use-state default-shown?)
on-press (rn/use-callback #(set-password-shown (not password-shown?))
[password-shown?])]
[base-input
(assoc props
:accessibility-label :password-input
@@ -156,7 +174,7 @@
:secure-text-entry (not password-shown?)
:right-icon {:style-fn style/password-icon
:icon-name (if password-shown? :i/hide-password :i/reveal)
:on-press #(set-password-shown (not password-shown?))})]))
:on-press on-press})]))
(defn input
"This input supports the following properties:
@@ -182,15 +200,11 @@
- :on-change-text
...
"
[{:keys [type clearable? on-clear icon-name]
[{:keys [type 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))}))]
icon-name (assoc-in [:left-icon :icon-name] icon-name))]
(if (= type :password)
[password-input base-props]
[base-input base-props])))
@@ -26,14 +26,20 @@
:padding-vertical 8
:padding-horizontal 12}))
(def right-side-container {:flex 1})
(def right-side-container
{:flex 1
:justify-content :center})
(defn title
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
[theme]
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
(defn text
[override-theme]
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
[theme]
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
(def avatar-container {:margin-right 8 :margin-top 4})
(defn avatar-container
[{:keys [multiline?]}]
{:margin-right 8
:align-self (when-not multiline? :center)
:margin-top (if multiline? 4 0)})
@@ -1,7 +1,9 @@
(ns quo.components.notifications.notification.view
(:require
[quo.components.avatars.user-avatar.view :as user-avatar]
[quo.components.markdown.text :as text]
[quo.components.notifications.notification.style :as style]
[quo.theme]
[react-native.blur :as blur]
[react-native.core :as rn]))
@@ -15,33 +17,33 @@
[into [rn/view {:accessibility-label :notification-body}] children])
(defn avatar-container
[& children]
[{:keys [multiline?]} & children]
[into
[rn/view
{:style style/avatar-container
{:style (style/avatar-container {:multiline? multiline?})
:accessibility-label :notification-avatar}]
children])
(defn title
([text weight] (title text weight nil))
([text weight override-theme]
([{:keys [text weight theme multiline?]}]
[text/text
{:size :paragraph-1
:weight (or weight :semi-bold)
:style (style/title override-theme)
:weight (or weight (if multiline? :semi-bold :medium))
:style (style/title theme)
:accessibility-label :notification-title}
text]))
(defn message
[text override-theme]
[text theme]
[text/text
{:size :paragraph-2
:style (style/text override-theme)
:weight :medium
:style (style/text theme)
:accessibility-label :notification-content}
text])
(defn- notification-container
[{:keys [avatar header body container-style override-theme]}]
[{:keys [avatar header body container-style theme]}]
[rn/view
{:style (merge style/box-container container-style)}
[blur/view
@@ -51,7 +53,7 @@
:blur-type :transparent
:overlay-color :transparent}]
[rn/view
{:style (style/content-container override-theme)}
{:style (style/content-container theme)}
avatar
[rn/view
{:style style/right-side-container}
@@ -59,17 +61,27 @@
body]]])
(defn notification
[{title-text :title :keys [avatar header title-weight text body container-style override-theme]}]
(let [header (or header
(when title-text
[title title-text title-weight override-theme]))
header (when header [header-container header])
body (or body (when text [message text override-theme]))
body (when body [body-container body])
avatar (when avatar [avatar-container avatar])]
[notification-container
{:avatar avatar
:header header
:body body
:container-style container-style
:override-theme override-theme}]))
[{title-text :title :keys [avatar user header title-weight text body container-style theme]}]
(let [theme (or theme (quo.theme/get-theme))
body (or body (when text [message text theme]))
header (or header
(when title-text
[title
{:text title-text
:weight title-weight
:theme theme
:multiline? (some? body)}]))
header (when header [header-container header])
body (when body [body-container body])
user-avatar (or avatar (when user (user-avatar/user-avatar user)))
avatar (when user-avatar
[avatar-container
{:multiline? (and header body)}
user-avatar])]
[quo.theme/provider {:theme theme}
[notification-container
{:avatar avatar
:header header
:body body
:container-style container-style
:theme theme}]]))
@@ -15,9 +15,9 @@
[{:keys [disabled? blur? on-press on-long-press type]} label]
(let [theme (quo.theme/use-theme-value)
[pressed? set-pressed?] (rn/use-state false)
on-press (rn/use-callback #(when on-press (on-press label)) [label])
on-press (rn/use-callback #(when on-press (on-press label)) [on-press label])
on-long-press (rn/use-callback #(when (fn? on-long-press) (on-long-press label))
[label])
[on-long-press label])
on-press-in (rn/use-callback #(set-pressed? true))
on-press-out (rn/use-callback #(set-pressed? false))
label-color (style/get-label-color disabled? theme blur?)
@@ -4,8 +4,7 @@
(def container
(merge (shadows/get 2)
{:flex 1
:align-items :center
{:align-items :center
:justify-content :center
:border-radius 16}))
@@ -1,6 +1,6 @@
(ns quo.components.profile.expanded-collectible.view
(:require
[promesa.core :as p]
[promesa.core :as promesa]
[quo.components.counter.collectible-counter.view :as collectible-counter]
[quo.components.icon :as icon]
[quo.components.markdown.text :as text]
@@ -37,7 +37,7 @@
[image-size set-image-size] (rn/use-state {})]
(rn/use-effect
(fn []
(p/let [[image-width image-height] (rn/image-get-size image-src)]
(promesa/let [[image-width image-height] (rn/image-get-size image-src)]
(set-image-size {:width image-width
:height image-height
:aspect-ratio (/ image-width image-height)})))
@@ -55,7 +55,7 @@
{:label (i18n/label :t/cant-fetch-info)
:counter counter
:theme theme}]
[rn/view {:style {:flex 1}}
[rn/view
[rn/image
{:style (style/image square? (:aspect-ratio image-size))
:source image-src}]
@@ -66,7 +66,7 @@
[:catn
[:props
[:map {:closed true}
[:image-src {:optional true} string?]
[:image-src {:optional true} [:maybe string?]]
[:container-style {:optional true} [:maybe :map]]
[:square? {:optional true} [:maybe boolean?]]
[:counter {:optional true} [:maybe string?]]
@@ -0,0 +1,11 @@
(ns quo.components.settings.page-setting.component-spec
(:require
[quo.core :as quo]
[test-helpers.component :as h]))
(h/describe
"renders basic text"
(h/test "title is visible"
(h/render [quo/page-setting
{:setting-text "sample text"}])
(h/is-truthy (h/get-by-text "sample text"))))
@@ -0,0 +1,14 @@
(ns quo.components.settings.page-setting.style
(:require
[quo.foundations.colors :as colors]))
(defn container
[theme]
{:flex-direction :row
:justify-content :space-between
:background-color (colors/theme-colors colors/neutral-2_5 colors/neutral-90 theme)
:padding-vertical 13
:padding-horizontal 12
:border-width 1
:border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)
:border-radius 16})
@@ -0,0 +1,24 @@
(ns quo.components.settings.page-setting.view
(:require
[quo.components.markdown.text :as text]
[quo.components.selectors.selectors.view :as selectors]
[quo.components.settings.page-setting.style :as style]
[quo.theme]
[react-native.core :as rn]))
(defn page-setting
[{:keys [setting-text customization-color checked? container-style on-change disabled?]}]
(let [theme (quo.theme/use-theme-value)]
[rn/view
{:style (merge (style/container theme)
container-style)}
[text/text
{:weight :medium
:number-of-lines 1} setting-text]
[selectors/view
{:type :toggle
:checked? checked?
:customization-color customization-color
:accessibility-label :user-list-toggle-check
:disabled? disabled?
:on-change (when on-change on-change)}]]))
@@ -7,11 +7,12 @@
[react-native.core :as rn]))
(defn- view-internal
[{:keys [title networks status theme blur?] :or {status :default}}]
[{:keys [title networks status theme blur? container-style] :or {status :default}}]
[rn/view
{:style (style/container {:status status
:theme theme
:blur? blur?})}
{:style (merge (style/container {:status status
:theme theme
:blur? blur?})
container-style)}
[preview-list/view
{:type :network
:number (count networks)
@@ -100,8 +100,7 @@
:or {customization-color :blue}}]
(let [time-frame-string (time-string time-frame time-frame-string)
up? (= metrics :positive)]
[rn/view
{:style style/account-overview-wrapper}
[rn/view {:style style/account-overview-wrapper}
(if (= :loading state)
[loading-state (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)]
[rn/view
@@ -113,19 +112,17 @@
:size :heading-1
:style style/current-value}
current-value]
[rn/view
{:style style/row-centered}
[:<>
(when (seq time-frame-string)
[text/text
{:weight :medium
:size :paragraph-2
:style (style/bottom-time-text (and (not= :custom time-frame)
(seq time-frame-to-string)))}
time-frame-string])
(when (and (= :custom time-frame)
(seq time-frame-to-string))
[custom-time-frame time-frame-to-string])]
[rn/view {:style style/row-centered}
(when (seq time-frame-string)
[text/text
{:weight :medium
:size :paragraph-2
:style (style/bottom-time-text (and (not= :custom time-frame)
(seq time-frame-to-string)))}
time-frame-string])
(when (and (= :custom time-frame)
(seq time-frame-to-string))
[custom-time-frame time-frame-to-string])
(when (and (seq percentage-change)
(seq currency-change))
[numeric-changes percentage-change currency-change customization-color theme up?])]])]))
@@ -12,32 +12,24 @@
(h/describe "Amount input component"
(h/test "Renders with default value"
(let [text-expected 0]
(render [amount-input/view {:init-value text-expected}])
(h/is-truthy (h/query-by-label-text :amount-input))
(h/is-equal (oops/oget (h/get-by-label-text :amount-input) "props" "value")
(str text-expected))))
(render [amount-input/view {:value text-expected}])
(h/is-truthy (h/query-by-label-text :amount-input))))
(h/test "When the value = minimum dec button is disabled"
(render [amount-input/view
{:init-value 0
:min-value 0}])
{:value 0
:min-value 0}])
(h/is-truthy
(oops/oget (h/get-by-label-text :amount-input-dec-button) "props" "accessibilityState" "disabled")))
(h/test "When the value = maximum inc button is disabled"
(render [amount-input/view
{:init-value 100
:max-value 100}])
{:value 100
:max-value 100}])
(h/is-truthy
(oops/oget (h/get-by-label-text :amount-input-inc-button) "props" "accessibilityState" "disabled")))
(h/test "Renders the error state"
(render [amount-input/view {:status :error}])
(render [amount-input/view {:status :error :value 10}])
(h/is-equal (colors/resolve-color :danger :light)
(oops/oget (h/get-by-label-text :amount-input) "props" "style" "color")))
(h/test "on-change-text function is fired"
(let [on-change-text (h/mock-fn)]
(render [amount-input/view {:on-change-text on-change-text}])
(h/fire-event :change-text (h/get-by-label-text :amount-input) "100")
(h/was-called on-change-text))))
(oops/oget (h/get-by-label-text :amount-input) "props" "style" "color"))))
@@ -1,9 +1,5 @@
(ns quo.components.wallet.amount-input.schema)
(def return-key-types
[:enum :done :go :next :search :send :none :previous :default
:emergency-call :google :join :route :yahoo])
(def ?schema
[:=>
[:catn
@@ -11,11 +7,10 @@
[:map {:closed true}
[:status {:optional true} [:maybe [:enum :default :error]]]
[:theme :schema.common/theme]
[:on-change-text {:optional true} [:maybe fn?]]
[:on-inc-press {:optional true} [:maybe fn?]]
[:on-dec-press {:optional true} [:maybe fn?]]
[:container-style {:optional true} [:maybe :map]]
[:auto-focus? {:optional true} [:maybe :boolean]]
[:min-value {:optional true} [:maybe :int]]
[:max-value {:optional true} [:maybe :int]]
[:return-key-type {:optional true} [:maybe return-key-types]]
[:init-value {:optional true} [:maybe :int]]]]]
[:value [:maybe :int]]]]]
:any])
@@ -12,6 +12,7 @@
(defn input-text
[theme type]
{:padding 0
:align :center
:color (if (= type :error)
(colors/resolve-color :danger theme)
(colors/theme-colors colors/neutral-100 colors/white theme))})
@@ -6,7 +6,6 @@
[quo.components.wallet.amount-input.style :as style]
[quo.theme :as quo.theme]
[react-native.core :as rn]
[reagent.core :as reagent]
[schema.core :as schema]))
(defn- amount-button
@@ -21,60 +20,35 @@
:on-press on-press}
icon])
(defn- process-amount
[input-value min-value max-value]
(let [parsed-input-value (parse-double input-value)]
(cond
(nil? parsed-input-value) min-value
(>= input-value max-value) max-value
(<= input-value min-value) min-value
:else parsed-input-value)))
(defn- view-internal
[{:keys [init-value]}]
(let [init-value (or init-value 0)
value (reagent/atom init-value)
on-dec-press #(swap! value dec)
on-inc-press #(swap! value inc)]
(fn [{:keys [theme status min-value max-value auto-focus?
return-key-type container-style on-change-text]}]
(let [min-value (or min-value 0)
max-value (or max-value 999999999)]
[rn/view
{:style (merge style/container container-style)}
[amount-button
{:theme theme
:accessibility-label :amount-input-dec-button
:icon :i/remove
:on-press on-dec-press
:disabled? (>= min-value @value)}]
[rn/view {:style style/input-container}
[rn/text-input
{:style
(text/text-style
{:size :heading-1
:weight :semi-bold
:align :center
:style (style/input-text theme (or status :default))})
:accessibility-label :amount-input
:editable true
:auto-focus (or auto-focus? false)
:value (str @value)
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
:return-key-type (or return-key-type :done)
:input-mode :numeric
:on-change-text (fn [input-value]
(let [processed-amount (process-amount input-value min-value max-value)]
(reset! value processed-amount)
(when on-change-text
(on-change-text processed-amount))
(reagent/flush)))}]] ; Fixes the input flickering issue when typing.
[amount-button
{:theme theme
:icon :i/add
:accessibility-label :amount-input-inc-button
:on-press on-inc-press
:disabled? (>= @value max-value)}]]))))
[{:keys [on-inc-press on-dec-press theme status value min-value max-value
container-style]
:or {value 0
min-value 0
max-value 999999999}}]
[rn/view
{:style (merge style/container container-style)}
[amount-button
{:theme theme
:accessibility-label :amount-input-dec-button
:icon :i/remove
:on-press on-dec-press
:disabled? (>= min-value value)}]
[rn/view {:style style/input-container}
[text/text
{:number-of-lines 1
:accessibility-label :amount-input
:weight :semi-bold
:size :heading-1
:align-self :center
:style (style/input-text theme (or status :default))}
value]]
[amount-button
{:theme theme
:icon :i/add
:accessibility-label :amount-input-inc-button
:on-press on-inc-press
:disabled? (>= value max-value)}]])
(def view
(quo.theme/with-theme
+4
View File
@@ -48,6 +48,7 @@
quo.components.drawers.action-drawers.view
quo.components.drawers.bottom-actions.view
quo.components.drawers.documentation-drawers.view
quo.components.drawers.drawer-action.view
quo.components.drawers.drawer-buttons.view
quo.components.drawers.drawer-top.view
quo.components.drawers.permission-context.view
@@ -128,6 +129,7 @@
quo.components.settings.accounts.view
quo.components.settings.category.view
quo.components.settings.data-item.view
quo.components.settings.page-setting.view
quo.components.settings.privacy-option.view
quo.components.settings.reorder-item.view
quo.components.settings.section-label.view
@@ -249,6 +251,7 @@
;;;; Drawers
(def action-drawer quo.components.drawers.action-drawers.view/action-drawer)
(def drawer-action quo.components.drawers.drawer-action.view/view)
(def documentation-drawers quo.components.drawers.documentation-drawers.view/view)
(def drawer-buttons quo.components.drawers.drawer-buttons.view/view)
(def drawer-top quo.components.drawers.drawer-top.view/view)
@@ -377,6 +380,7 @@
(def account quo.components.settings.accounts.view/account)
(def category quo.components.settings.category.view/category)
(def data-item quo.components.settings.data-item.view/view)
(def page-setting quo.components.settings.page-setting.view/page-setting)
(def privacy-option quo.components.settings.privacy-option.view/view)
(def reorder-item quo.components.settings.reorder-item.view/reorder-item)
(def section-label quo.components.settings.section-label.view/view)
+1
View File
@@ -25,6 +25,7 @@
quo.components.drawers.action-drawers.component-spec
quo.components.drawers.bottom-actions.component-spec
quo.components.drawers.documentation-drawers.component-spec
quo.components.drawers.drawer-action.component-spec
quo.components.drawers.drawer-buttons.component-spec
quo.components.drawers.drawer-top.component-spec
quo.components.drawers.permission-context.component-spec
+6 -6
View File
@@ -3,7 +3,7 @@
["react" :as react]
["react-native" :as react-native]
[oops.core :as oops]
[promesa.core :as p]
[promesa.core :as promesa]
[react-native.flat-list :as flat-list]
[react-native.platform :as platform]
[react-native.section-list :as section-list]
@@ -37,11 +37,11 @@
(defn image-get-size
[uri]
(p/create (fn [res rej]
(.getSize ^js (.-Image ^js react-native)
uri
(fn [width height] (res [width height]))
rej))))
(promesa/create (fn [res rej]
(.getSize ^js (.-Image ^js react-native)
uri
(fn [width height] (res [width height]))
rej))))
(def text (reagent/adapt-react-class (.-Text ^js react-native)))
(def text-input (reagent/adapt-react-class (.-TextInput ^js react-native)))
+14 -11
View File
@@ -62,23 +62,26 @@
([server username password]
(save-credentials server username password identity))
([server username password callback]
(-> (.setInternetCredentials ^js react-native-keychain
(string/lower-case server)
username
password
keychain-secure-hardware
keychain-restricted-availability)
(.then callback))))
(when-not (empty? server)
(-> (.setInternetCredentials ^js react-native-keychain
(string/lower-case server)
username
password
keychain-secure-hardware
keychain-restricted-availability)
(.then callback)))))
(defn get-credentials
"Gets the credentials for a specified server from the Keychain"
([server]
(get-credentials server identity))
([server callback]
(-> (.getInternetCredentials ^js react-native-keychain (string/lower-case server))
(.then callback))))
(when-not (empty? server)
(-> (.getInternetCredentials ^js react-native-keychain (string/lower-case server))
(.then callback)))))
(defn reset-credentials
[server]
(-> (.resetInternetCredentials ^js react-native-keychain (string/lower-case server))
(.then #(when-not % (log/error (str "Error while clearing saved password."))))))
(when-not (empty? server)
(-> (.resetInternetCredentials ^js react-native-keychain (string/lower-case server))
(.then #(when-not % (log/error (str "Error while clearing saved password.")))))))
+20 -22
View File
@@ -148,28 +148,26 @@
(reset! search-text ""))
(defn f-view
[{:keys [search-text on-change-text clear-states active-category scroll-ref theme]
[{:keys [search-active? on-change-text clear-states active-category scroll-ref theme]
:as sheet-opts}]
(let [search-active? (pos? (count @search-text))]
[rn/keyboard-avoiding-view
{:style style/flex-spacer
:keyboard-vertical-offset 8}
[rn/view {:style style/flex-spacer}
[rn/view {:style style/search-input-container}
[quo/input
{:small? true
:placeholder (i18n/label :t/emoji-search-placeholder)
:icon-name :i/search
:value @search-text
:on-change-text on-change-text
:clearable? search-active?
:on-clear clear-states}]]
[render-list sheet-opts]
(when-not search-active?
[footer
{:theme theme
:active-category active-category
:scroll-ref scroll-ref}])]]))
[rn/keyboard-avoiding-view
{:style style/flex-spacer
:keyboard-vertical-offset 8}
[rn/view {:style style/flex-spacer}
[rn/view {:style style/search-input-container}
[quo/input
{:small? true
:placeholder (i18n/label :t/emoji-search-placeholder)
:icon-name :i/search
:on-change-text on-change-text
:clearable? search-active?
:on-clear clear-states}]]
[render-list sheet-opts]
(when-not search-active?
[footer
{:theme theme
:active-category active-category
:scroll-ref scroll-ref}])]])
(defn- view-internal
[_]
@@ -202,7 +200,7 @@
(fn [sheet-opts]
[:f> f-view
(assoc sheet-opts
:search-text search-text
:search-active? (pos? (count @search-text))
:on-change-text on-change-text
:clear-states clear-states
:filtered-data @filtered-data
@@ -29,7 +29,7 @@
(reset! ratom height))))
(defn- init-keyboard-listeners
[{:keys [on-did-show]}]
[{:keys [on-did-show scroll-view-ref]}]
(let [keyboard-will-show? (reagent/atom false)
keyboard-did-show? (reagent/atom false)
add-listener (fn [listener callback]
@@ -41,7 +41,10 @@
(reset! keyboard-did-show? true)
(when on-did-show (on-did-show e))))
will-hide-listener (add-listener "keyboardWillHide"
#(reset! keyboard-will-show? false))
(fn []
(reset! keyboard-will-show? false)
(reagent/flush)
(.scrollTo @scroll-view-ref #js {:x 0 :y 0 :animated true})))
did-hide-listener (add-listener "keyboardDidHide"
#(reset! keyboard-did-show? false))
remove-listeners (fn []
@@ -55,9 +58,11 @@
(defn view
[{:keys [header footer customization-color footer-container-padding header-container-style
gradient-cover?]
:or {footer-container-padding (safe-area/get-top)}} &
children]
(reagent/with-let [window-height (:height (rn/get-window))
:or {footer-container-padding (safe-area/get-top)}}
& children]
(reagent/with-let [scroll-view-ref (atom nil)
set-scroll-ref #(reset! scroll-view-ref %)
window-height (:height (rn/get-window))
footer-container-height (reagent/atom 0)
header-height (reagent/atom 0)
content-container-height (reagent/atom 0)
@@ -66,7 +71,8 @@
{:keys [keyboard-will-show?
keyboard-did-show?
remove-listeners]} (init-keyboard-listeners
{:on-did-show
{:scroll-view-ref scroll-view-ref
:on-did-show
(fn [e]
(reset! keyboard-height
(oops/oget e "endCoordinates.height")))})
@@ -85,16 +91,22 @@
:header-height @header-height
:keyboard-shown? keyboard-shown?})]
[:<>
(when gradient-cover? [quo/gradient-cover {:customization-color customization-color}])
(when gradient-cover?
[quo/gradient-cover {:customization-color customization-color}])
[rn/view {:style style/page-container}
[rn/view
{:on-layout set-header-height
:style header-container-style}
header]
[gesture/scroll-view
{:on-scroll set-content-y-scroll
:scroll-event-throttle 64
:content-container-style {:flex-grow 1}}
{:ref set-scroll-ref
:on-scroll set-content-y-scroll
:scroll-event-throttle 64
:content-container-style {:flex-grow 1
:padding-bottom (when @keyboard-did-show?
@footer-container-height)}
:always-bounce-vertical @keyboard-did-show?
:shows-vertical-scroll-indicator false}
(into [rn/view {:on-layout set-content-container-height}]
children)]
[rn/keyboard-avoiding-view
+3 -2
View File
@@ -1,6 +1,6 @@
(ns status-im.common.log
(:require
[clojure.pprint :as p]
[clojure.pprint :as promesa]
[clojure.string :as string]
[native-module.core :as native-module]
[re-frame.core :as re-frame]
@@ -43,7 +43,8 @@
:middleware [(fn [data]
(update data
:vargs
(partial mapv #(if (string? %) % (with-out-str (p/pprint %))))))]})
(partial mapv
#(if (string? %) % (with-out-str (promesa/pprint %))))))]})
(native-module/init-status-go-logging logging-params)))))
(re-frame/reg-fx
+7 -6
View File
@@ -32,10 +32,10 @@
multiaccount-data (when received-account?
(merge account {:password password}))
navigate-to-syncing-devices? (and (or connection-success? connection-error?) receiver?)
user-in-syncing-devices-screen? (or (= (:view-id db) :syncing-progress)
(= (:view-id db) :profiles)
(= (:view-id db) :syncing-progress-intro))
user-in-sign-in-intro-screen? (= (:view-id db) :sign-in-intro)]
user-in-syncing-devices-screen? (or (= (:view-id db) :screen/onboarding.syncing-progress)
(= (:view-id db) :screen/profile.profiles)
(= (:view-id db) :screen/onboarding.syncing-progress-intro))
user-in-sign-in-intro-screen? (= (:view-id db) :screen/onboarding.sign-in-intro)]
(merge {:db (cond-> db
connection-success?
(assoc-in [:syncing :pairing-status] :connected)
@@ -51,8 +51,9 @@
(cond
(and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?))
{:dispatch (if user-in-sign-in-intro-screen?
[:navigate-to-within-stack [:syncing-progress-intro :sign-in-intro]]
[:navigate-to :syncing-progress])}
[:navigate-to-within-stack
[:screen/onboarding.syncing-progress-intro :screen/onboarding.sign-in-intro]]
[:navigate-to :screen/onboarding.syncing-progress])}
(and completed-pairing? sender?)
{:dispatch [:syncing/clear-states]}
+1 -1
View File
@@ -75,7 +75,7 @@
(and public-key (own-public-key? db public-key))
(rf/merge cofx
{:pop-to-root-fx :shell-stack}
(navigation/navigate-to :my-profile nil))
(navigation/navigate-to :settings nil))
public-key
{:dispatch [:chat.ui/show-profile public-key ens-name]}))
+1
View File
@@ -169,3 +169,4 @@
(def community-accounts-selection-enabled? true)
(def fetch-messages-enabled? (enabled? (get-config :FETCH_MESSAGES_ENABLED "1")))
(def test-networks-enabled? (enabled? (get-config :TEST_NETWORKS_ENABLED "0")))
@@ -3,7 +3,6 @@
[quo.core :as quo]
[react-native.clipboard :as clipboard]
[react-native.core :as rn]
[reagent.core :as reagent]
[status-im.contexts.chat.home.add-new-contact.style :as style]
[utils.address :as address]
[utils.debounce :as debounce]
@@ -51,57 +50,66 @@
(defn- search-input
[]
(reagent/with-let [input-value (reagent/atom nil)
input-ref (atom nil)
clear-input (fn []
(reset! input-value nil)
(rf/dispatch [:contacts/clear-new-identity]))
paste-on-input #(clipboard/get-string
(fn [clipboard-text]
(reset! input-value clipboard-text)
(rf/dispatch [:contacts/set-new-identity
{:input clipboard-text}])))]
(let [{:keys [scanned] contact-public-key :id} (rf/sub [:contacts/new-identity])
contact-public-key-or-scanned (or contact-public-key scanned)
empty-input? (and (string/blank? @input-value)
(string/blank? contact-public-key-or-scanned))]
[rn/view {:style style/input-and-scan-container}
[quo/input
{:accessibility-label :enter-contact-code-input
:ref #(reset! input-ref %)
:container-style {:flex 1}
:auto-capitalize :none
:multiline? true
:blur-on-submit true
:return-key-type :done
:label (i18n/label :t/ens-or-chat-key)
:placeholder (i18n/label :t/type-some-chat-key)
:clearable? (not empty-input?)
:on-clear clear-input
:button (when empty-input?
{:on-press paste-on-input
:text (i18n/label :t/paste)})
;; NOTE: `contact-public-key-or-scanned` has priority over `@input-value`,
;; we clean it when the input is updated so that it's `nil` and
;; `@input-value`is shown. To fastly clean it, we use `dispatch-sync`.
;; This call could be avoided if `::qr-scanner/scan-code` were able to
;; receive a callback function, not only a re-frame event as callback.
:value (or contact-public-key-or-scanned @input-value)
:on-change-text (fn [new-text]
(reset! input-value new-text)
(as-> [:contacts/set-new-identity {:input new-text}] $
(if (string/blank? contact-public-key-or-scanned)
(debounce/debounce-and-dispatch $ 600)
(rf/dispatch-sync $))))}]
[rn/view {:style style/scan-button-container}
[quo/button
{:type :outline
:icon-only? true
:size 40
:on-press #(rf/dispatch [:open-modal :scan-profile-qr-code])}
:i/scan]]])
(finally
(rf/dispatch [:contacts/clear-new-identity]))))
(let [[input-value set-input-value] (rn/use-state nil)
input-ref (rn/use-ref-atom nil)
on-ref (rn/use-callback #(reset! input-ref %))
{:keys [scanned]
contact-public-key :id} (rf/sub [:contacts/new-identity])
contact-public-key-or-scanned (or contact-public-key scanned)
empty-input? (and (string/blank? input-value)
(string/blank? contact-public-key-or-scanned))
clear-input (rn/use-callback
(fn []
(set-input-value nil)
(rf/dispatch [:contacts/clear-new-identity])))
paste-on-input (rn/use-callback
(fn []
(clipboard/get-string
(fn [clipboard-text]
(set-input-value clipboard-text)
(rf/dispatch [:contacts/set-new-identity
{:input clipboard-text}])))))
on-change-text (rn/use-callback
(fn [new-text]
(set-input-value new-text)
(if (string/blank? contact-public-key-or-scanned)
(debounce/debounce-and-dispatch [:contacts/set-new-identity
{:input new-text}]
600)
(rf/dispatch-sync [:contacts/set-new-identity
{:input new-text}])))
[contact-public-key-or-scanned])]
(rn/use-unmount #(rf/dispatch [:contacts/clear-new-identity]))
[rn/view {:style style/input-and-scan-container}
[quo/input
{:accessibility-label :enter-contact-code-input
:ref on-ref
:container-style {:flex 1}
:auto-capitalize :none
:multiline? true
:blur-on-submit true
:return-key-type :done
:label (i18n/label :t/ens-or-chat-key)
:placeholder (i18n/label :t/type-some-chat-key)
:clearable? (not empty-input?)
:on-clear clear-input
:button (when empty-input?
{:on-press paste-on-input
:text (i18n/label :t/paste)})
;; NOTE: `contact-public-key-or-scanned` has priority over `input-value`,
;; we clean it when the input is updated so that it's `nil` and
;; `input-value`is shown. To fastly clean it, we use `dispatch-sync`.
;; This call could be avoided if `::qr-scanner/scan-code` were able to
;; receive a callback function, not only a re-frame event as callback.
:value (or contact-public-key-or-scanned input-value)
:on-change-text on-change-text}]
[rn/view {:style style/scan-button-container}
[quo/button
{:type :outline
:icon-only? true
:size 40
:on-press #(rf/dispatch [:open-modal :scan-profile-qr-code])}
:i/scan]]]))
(defn- invalid-text
[message]
@@ -38,7 +38,8 @@
(let [cache (get-in db [:chat/link-previews :cache])
previews (urls->previews cache urls)
new-urls (->> previews
(filter :loading?)
(filter (fn [{:keys [loading? status-link-preview?]}]
(or loading? status-link-preview?)))
(map :url))
;; `request-id` is a must because we need to process only the last
;; unfurling event, as well as avoid needlessly updating the app db
@@ -139,14 +140,18 @@
sent."
{:events [:link-preview/reset-unfurled]}
[{:keys [db]}]
{:db (update db :chat/link-previews dissoc :unfurled :request-id :cleared)})
{:db (-> db
(update :chat/link-previews dissoc :unfurled :request-id :cleared)
(update :chat/status-link-previews dissoc :unfurled :request-id :cleared))})
(rf/defn reset-all
"Reset all preview state. It is especially important to delete any cached
URLs, as failing to do so results in its unbounded growth."
{:events [:link-preview/reset-all]}
[{:keys [db]}]
{:db (dissoc db :chat/link-previews)})
{:db (-> db
(dissoc :chat/link-previews)
(dissoc :chat/status-link-previews))})
(rf/defn clear-link-previews
"Mark current unfurled URLs as `cleared`, meaning the user won't see previews
@@ -156,4 +161,5 @@
(let [unfurled-urls (set (map :url (get-in db [:chat/link-previews :unfurled])))]
{:db (-> db
(update :chat/link-previews dissoc :unfurled :request-id)
(update :chat/status-link-previews dissoc :unfurled :request-id)
(assoc-in [:chat/link-previews :cleared] unfurled-urls))}))
@@ -0,0 +1,10 @@
(ns status-im.contexts.chat.messenger.messages.content.emoji-message.style)
(defn emoji-container
[margin-top]
{:flex-direction :row
:margin-top margin-top})
(def emoji-text
{:font-size 36
:line-height 42})
@@ -0,0 +1,10 @@
(ns status-im.contexts.chat.messenger.messages.content.emoji-message.view
(:require [react-native.core :as rn]
[status-im.contexts.chat.messenger.messages.content.emoji-message.style :as style]))
(defn view
[{:keys [content last-in-group? pinned in-pinned-view?]}]
(let [margin-top (if (or last-in-group? in-pinned-view? pinned) 8 0)]
[rn/view {:style (style/emoji-container margin-top)}
[rn/text {:style style/emoji-text}
(:text content)]]))
@@ -0,0 +1,10 @@
(ns status-im.contexts.chat.messenger.messages.content.sticker-message.view
(:require [react-native.core :as rn]
[react-native.fast-image :as fast-image]))
(defn view
[{:keys [url]}]
[rn/view {:style {:margin-top 6 :margin-bottom 4}}
[fast-image/fast-image
{:style {:width 120 :height 120}
:source {:uri (str url "&download=true")}}]])
@@ -5,17 +5,15 @@
(def ^:private message-padding-scaling-ratio 4.5)
(defn message-container
([]
(message-container false nil nil false))
([in-pinned-view? pinned-by mentioned last-in-group?]
(cond-> {:border-radius 16
:margin-horizontal 8}
[{:keys [in-pinned-view? pinned-by mentioned last-in-group? system-message?]}]
(cond-> {:border-radius 16
:margin-horizontal 8}
(and (not in-pinned-view?) (or mentioned pinned-by))
(assoc :background-color colors/primary-50-opa-5 :margin-bottom 4)
(and (not in-pinned-view?) (or mentioned pinned-by))
(assoc :background-color colors/primary-50-opa-5 :margin-bottom 4)
(and (not in-pinned-view?) (or mentioned pinned-by last-in-group?))
(assoc :margin-top 4))))
(and (not in-pinned-view?) (not system-message?) (or mentioned pinned-by last-in-group?))
(assoc :margin-top 4)))
(defn user-message-content
[{:keys [outgoing outgoing-status six-reactions? window-scale small-screen?]}]
@@ -17,10 +17,12 @@
[status-im.contexts.chat.messenger.messages.content.album.view :as album]
[status-im.contexts.chat.messenger.messages.content.audio.view :as audio]
[status-im.contexts.chat.messenger.messages.content.deleted.view :as content.deleted]
[status-im.contexts.chat.messenger.messages.content.emoji-message.view :as emoji-message]
[status-im.contexts.chat.messenger.messages.content.image.view :as image]
[status-im.contexts.chat.messenger.messages.content.pin.view :as pin]
[status-im.contexts.chat.messenger.messages.content.reactions.view :as reactions]
[status-im.contexts.chat.messenger.messages.content.status.view :as status]
[status-im.contexts.chat.messenger.messages.content.sticker-message.view :as sticker-message]
[status-im.contexts.chat.messenger.messages.content.style :as style]
[status-im.contexts.chat.messenger.messages.content.system.text.view :as system.text]
[status-im.contexts.chat.messenger.messages.content.text.view :as content.text]
@@ -150,38 +152,37 @@
(let [show-delivery-state? (reagent/atom false)]
(fn [{:keys [message-data context keyboard-shown? show-reactions? in-reaction-and-action-menu?
show-user-info? preview? theme]}]
(let [{:keys [content-type quoted-message content
outgoing outgoing-status pinned-by
message-id chat-id]} message-data
{:keys [disable-message-long-press?]} context
first-image (first (:album message-data))
outgoing-status (if (= content-type
constants/content-type-album)
(:outgoing-status first-image)
outgoing-status)
outgoing (if (= content-type
constants/content-type-album)
(:outgoing first-image)
outgoing)
context (assoc context
:on-long-press
#(on-long-press message-data
context
keyboard-shown?))
response-to (:response-to content)
height (rf/sub [:dimensions/window-height])
(let [{:keys [content-type quoted-message content outgoing outgoing-status pinned-by pinned
last-in-group? message-id chat-id]} message-data
{:keys [disable-message-long-press?]} context
first-image (first (:album message-data))
outgoing-status (if (= content-type
constants/content-type-album)
(:outgoing-status first-image)
outgoing-status)
outgoing (if (= content-type
constants/content-type-album)
(:outgoing first-image)
outgoing)
context (assoc context
:on-long-press
#(on-long-press message-data
context
keyboard-shown?))
response-to (:response-to content)
height (rf/sub [:dimensions/window-height])
{window-width :width
window-scale :scale} (rn/get-window)
message-container-data {:window-width window-width
:padding-right 20
:padding-left 20
:avatar-container-width 32
:message-margin-left 8}
reactions (rf/sub [:chats/message-reactions message-id
chat-id])
six-reactions? (-> reactions
count
(= 6))]
window-scale :scale} (rn/get-window)
message-container-data {:window-width window-width
:padding-right 20
:padding-left 20
:avatar-container-width 32
:message-margin-left 8}
reactions (rf/sub [:chats/message-reactions message-id
chat-id])
six-reactions? (-> reactions
count
(= 6))]
[rn/touchable-highlight
{:accessibility-label (if (and outgoing (= outgoing-status :sending))
:message-sending
@@ -231,10 +232,14 @@
[content.text/text-content message-data context]
constants/content-type-emoji
[not-implemented/not-implemented [old-message/emoji message-data]]
[emoji-message/view
{:content content
:last-in-group? last-in-group?
:pinned pinned
:in-pinned-view? (:in-pinned-view? context)}]
constants/content-type-sticker
[not-implemented/not-implemented [old-message/sticker message-data]]
[sticker-message/view {:url (-> message-data :content :sticker :url)}]
constants/content-type-audio
[audio/audio-message message-data context]
@@ -287,7 +292,7 @@
:show-user-info? false
:show-reactions? true}]]))}]))
(defn system-message?
(defn check-if-system-message?
[content-type]
(#{constants/content-type-system-text
constants/content-type-community
@@ -300,28 +305,35 @@
(defn message
[{:keys [pinned-by mentioned content-type last-in-group? deleted? deleted-for-me?]
:as message-data} {:keys [in-pinned-view?] :as context} keyboard-shown?]
[rn/view
{:style (style/message-container in-pinned-view? pinned-by mentioned last-in-group?)
:accessibility-label :chat-item}
(cond
(system-message? content-type)
[system-message-content message-data]
(let [system-message? (check-if-system-message? content-type)]
[rn/view
{:style (style/message-container
{:in-pinned-view? in-pinned-view?
:pinned-by pinned-by
:mentioned mentioned
:last-in-group? last-in-group?
:system-message? system-message?})
:accessibility-label :chat-item}
(cond
system-message?
[system-message-content message-data]
(or deleted? deleted-for-me?)
[content.deleted/deleted-message
(assoc message-data
:on-long-press
#(on-long-press message-data
context
keyboard-shown?))
context]
(or deleted? deleted-for-me?)
[content.deleted/deleted-message
(assoc message-data
:on-long-press
#(on-long-press message-data
context
keyboard-shown?))
context]
(= content-type constants/content-type-bridge-message)
[bridge-message-content message-data]
:else
[user-message-content
{:message-data message-data
:context context
:keyboard-shown? keyboard-shown?
:show-reactions? true}])])
(= content-type constants/content-type-bridge-message)
[bridge-message-content message-data]
:else
[user-message-content
{:message-data message-data
:context context
:keyboard-shown? keyboard-shown?
:show-reactions? true}])]))
@@ -8,9 +8,6 @@
{:flex 1
:z-index 2})
(def list-container
{:padding-vertical 16})
(defn background-container
[background-color background-opacity top-margin]
(reanimated/apply-animations-to-style
@@ -23,12 +20,12 @@
:height (+ top-margin messages.constants/header-container-radius)}))
(defn header-bottom-part
[border-radius theme top-margin]
[bottom theme top-margin]
(reanimated/apply-animations-to-style
{:border-top-left-radius border-radius
:border-top-right-radius border-radius}
{:bottom bottom}
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
:padding-horizontal 20
:border-radius 20
:margin-top top-margin}))
(defn header-image
@@ -42,5 +39,20 @@
:border-radius 50
:border-color (colors/theme-colors colors/white colors/neutral-95 theme)}))
(def bio
{:margin-top 8})
(defn user-name-container
[top left]
(reanimated/apply-animations-to-style
{:top top
:left left}
{:z-index -1}))
(def user-name
{:align-items :center
:flex-direction :row
:margin-top 52})
(defn bio-and-actions
[top]
(reanimated/apply-animations-to-style
{:top top}
{:row-gap 16}))
@@ -23,6 +23,7 @@
[utils.re-frame :as rf]
[utils.worklets.chat.messenger.messages :as worklets]))
(defonce ^:const distance-from-last-message 4)
(defonce ^:const loading-indicator-extra-spacing 250)
(defonce ^:const loading-indicator-page-loading-height 100)
(defonce ^:const min-message-height 32)
@@ -63,8 +64,7 @@
[{:keys [ens-verified added?]} theme]
(when (or ens-verified added?)
[rn/view
{:style {:margin-left 4
:margin-top 8}}
{:style {:margin-left 4}}
(if ens-verified
[quo/icon :i/verified
{:no-color true
@@ -111,27 +111,55 @@
(- 70 (:bottom insets)))]
[rn/view {:style {:height height}}]))
(defn f-list-footer-avatar
[{:keys [distance-from-list-top display-name online? profile-picture theme]}]
(defn list-footer-avatar
[{:keys [distance-from-list-top display-name online? profile-picture theme group-chat color]}]
(let [scale (reanimated/interpolate distance-from-list-top
[0 messages.constants/header-container-top-margin]
[1 0.4]
messages.constants/default-extrapolation-option)
top (reanimated/interpolate distance-from-list-top
[0 messages.constants/header-container-top-margin]
[-40 -8]
[-44 -12]
messages.constants/default-extrapolation-option)
left (reanimated/interpolate distance-from-list-top
[0 messages.constants/header-container-top-margin]
[20 -4]
[16 -8]
messages.constants/default-extrapolation-option)]
[reanimated/view
{:style (style/header-image scale top left theme)}
[quo/user-avatar
{:full-name display-name
:online? online?
:profile-picture profile-picture
:size :big}]]))
(if group-chat
[quo/group-avatar
{:customization-color color
:size :size-80
:picture profile-picture
:override-theme :dark}]
[quo/user-avatar
{:full-name display-name
:online? online?
:profile-picture profile-picture
:size :big}])]))
(defn chat-display-name
[{:keys [distance-from-list-top display-name contact theme]}]
(let [top (reanimated/interpolate distance-from-list-top
[0 messages.constants/header-container-top-margin]
[0 -35]
messages.constants/default-extrapolation-option)
left (reanimated/interpolate distance-from-list-top
[0 messages.constants/header-container-top-margin]
[0 40]
messages.constants/default-extrapolation-option)]
[reanimated/view
{:style (style/user-name-container top left)}
[rn/view
{:style style/user-name}
[quo/text
{:weight :semi-bold
:size :heading-1
:style {:flex-shrink 1}
:number-of-lines 1}
display-name]
[contact-icon contact theme]]]))
(defn actions
[chat-id cover-bg-color]
@@ -142,89 +170,102 @@
muted? (and muted (some? muted-till))
mute-chat-label (if community-channel? :t/mute-channel :t/mute-chat)
unmute-chat-label (if community-channel? :t/unmute-channel :t/unmute-chat)]
[quo/channel-actions
{:container-style {:margin-top 16}
:actions [{:accessibility-label :action-button-pinned
:big? true
:label (or latest-pin-text (i18n/label :t/no-pinned-messages))
:customization-color cover-bg-color
:icon :i/pin
:counter-value pins-count
:on-press (fn []
(rf/dispatch [:pin-message/show-pins-bottom-sheet
chat-id]))}
{:accessibility-label :action-button-mute
:label (i18n/label (if muted
unmute-chat-label
mute-chat-label))
:customization-color cover-bg-color
:icon (if muted? :i/activity-center :i/muted)
:on-press (fn []
(if muted?
(home.actions/unmute-chat-action chat-id)
(home.actions/mute-chat-action chat-id
chat-type
muted?)))}]}]))
(defn f-list-footer
[quo/channel-actions
{:actions [{:accessibility-label :action-button-pinned
:big? true
:label (or latest-pin-text (i18n/label :t/no-pinned-messages))
:customization-color cover-bg-color
:icon :i/pin
:counter-value pins-count
:on-press (fn []
(rf/dispatch [:pin-message/show-pins-bottom-sheet
chat-id]))}
{:accessibility-label :action-button-mute
:label (i18n/label (if muted
unmute-chat-label
mute-chat-label))
:customization-color cover-bg-color
:icon (if muted? :i/activity-center :i/muted)
:on-press (fn []
(if muted?
(home.actions/unmute-chat-action chat-id)
(home.actions/mute-chat-action chat-id
chat-type
muted?)))}]}]))
(defn bio-and-actions
[{:keys [distance-from-list-top bio chat-id customization-color]}]
(let [has-bio (seq bio)
top (reanimated/interpolate
distance-from-list-top
[0 messages.constants/header-container-top-margin]
[(if has-bio 8 16) (if has-bio -28 -20)]
messages.constants/default-extrapolation-option)]
[reanimated/view
{:style (style/bio-and-actions top)}
(when has-bio
[quo/text bio])
[actions chat-id customization-color]]))
(defn footer-component
[{:keys [chat distance-from-list-top theme customization-color]}]
(let [{:keys [chat-id chat-name emoji chat-type
group-chat]} chat
display-name (cond
(= chat-type constants/one-to-one-chat-type)
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
(= chat-type constants/community-chat-type)
(str (when emoji (str emoji " ")) "# " chat-name)
:else (str emoji chat-name))
{:keys [bio]} (rf/sub [:contacts/contact-by-identity chat-id])
online? (rf/sub [:visibility-status-updates/online? chat-id])
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))
photo-path (rf/sub [:chats/photo-path chat-id])
top-margin (+ (safe-area/get-top)
messages.constants/top-bar-height
messages.constants/header-container-top-margin)
background-color (colors/theme-colors
(colors/resolve-color customization-color theme 20)
(colors/resolve-color customization-color theme 40)
theme)
border-radius (reanimated/interpolate
distance-from-list-top
[0 messages.constants/header-container-top-margin]
[20 0]
messages.constants/default-extrapolation-option)
background-opacity (reanimated/interpolate
distance-from-list-top
[messages.constants/header-container-top-margin
(+ messages.constants/header-animation-distance
messages.constants/header-container-top-margin)]
[1 0]
messages.constants/default-extrapolation-option)]
group-chat color]} chat
display-name (cond
(= chat-type constants/one-to-one-chat-type)
(first (rf/sub [:contacts/contact-two-names-by-identity chat-id]))
(= chat-type constants/community-chat-type)
(str (when emoji (str emoji " ")) "# " chat-name)
:else (str emoji chat-name))
{:keys [bio]} (rf/sub [:contacts/contact-by-identity chat-id])
online? (rf/sub [:visibility-status-updates/online? chat-id])
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address chat-id]))
photo-path (rf/sub [:chats/photo-path chat-id])
top-margin (+ (safe-area/get-top)
messages.constants/top-bar-height
messages.constants/header-container-top-margin
32)
background-color (colors/theme-colors
(colors/resolve-color customization-color theme 20)
(colors/resolve-color customization-color theme 40)
theme)
bottom (reanimated/interpolate
distance-from-list-top
[0 messages.constants/header-container-top-margin]
[32 -4]
messages.constants/default-extrapolation-option)
background-opacity (reanimated/interpolate
distance-from-list-top
[messages.constants/header-container-top-margin
(+ messages.constants/header-animation-distance
messages.constants/header-container-top-margin)]
[1 0]
messages.constants/default-extrapolation-option)]
[:<>
[reanimated/view
{:style (style/background-container background-color background-opacity top-margin)}]
[reanimated/view {:style (style/header-bottom-part border-radius theme top-margin)}
(when-not group-chat
[:f> f-list-footer-avatar
{:distance-from-list-top distance-from-list-top
:display-name display-name
:online? online?
:theme theme
:profile-picture photo-path}])
[rn/view
{:style {:flex-direction :row
:margin-top (if group-chat 94 52)}}
[quo/text
{:weight :semi-bold
:size :heading-1
:style {:flex-shrink 1}
:number-of-lines 1}
display-name]
[contact-icon contact theme]]
(when bio
[quo/text {:style style/bio}
bio])
[actions chat-id customization-color]]]))
[reanimated/view {:style (style/header-bottom-part bottom theme top-margin)}
[list-footer-avatar
{:distance-from-list-top distance-from-list-top
:display-name display-name
:online? online?
:theme theme
:profile-picture photo-path
:group-chat group-chat
:color color}]
[chat-display-name
{:distance-from-list-top distance-from-list-top
:display-name display-name
:theme theme
:contact contact
:group-chat group-chat}]
[bio-and-actions
{:distance-from-list-top distance-from-list-top
:bio bio
:chat-id chat-id
:customization-color customization-color}]]]))
(defn list-footer
[props]
@@ -234,7 +275,7 @@
[:<>
(if (or loading-messages? (not all-loaded?))
[loading-view chat-id props]
[:f> f-list-footer props])]))
[footer-component props])]))
(defn list-group-chat-header
[{:keys [chat-id invitation-admin]}]
@@ -284,7 +325,7 @@
(reset! layout-height-atom layout-height))
(reset! distance-atom new-distance)))
(defn f-messages-list-content
(defn messages-list-content
[{:keys [insets distance-from-list-top content-height layout-height distance-atom
chat-screen-layout-calculations-complete? chat-list-scroll-y]}]
(let [theme (quo.theme/use-theme-value)
@@ -348,6 +389,7 @@
:style {:background-color (colors/theme-colors colors/white
colors/neutral-95
theme)}
:content-container-style {:padding-top distance-from-last-message}
:inverted true
:on-layout #(on-layout
{:event %
@@ -18,37 +18,42 @@
[utils.worklets.chat.messenger.messages :as messages.worklets]
[utils.worklets.chat.messenger.navigation :as worklets]))
(defn f-header-content-container
(defn header-content-container
[{:keys [chat distance-from-list-top all-loaded? chat-screen-layout-calculations-complete?]}]
(let [{:keys [chat-id group-chat chat-type chat-name
emoji]} chat
display-name (cond
(= chat-type constants/one-to-one-chat-type)
(first (rf/sub
[:contacts/contact-two-names-by-identity
chat-id]))
(= chat-type constants/community-chat-type)
(str (when emoji (str emoji " ")) "# " chat-name)
:else (str emoji chat-name))
online? (when-not group-chat (rf/sub [:visibility-status-updates/online? chat-id]))
photo-path (when-not group-chat (rf/sub [:chats/photo-path chat-id]))
header-opacity (worklets/navigation-header-opacity
distance-from-list-top
all-loaded?
chat-screen-layout-calculations-complete?
(if platform/ios?
messages.constants/content-animation-start-position-ios
messages.constants/content-animation-start-position-android))
header-position (worklets/navigation-header-position
distance-from-list-top
all-loaded?
messages.constants/top-bar-height
(if platform/ios?
messages.constants/content-animation-start-position-ios
messages.constants/content-animation-start-position-android))]
emoji color]} chat
display-name (cond
(= chat-type constants/one-to-one-chat-type)
(first (rf/sub
[:contacts/contact-two-names-by-identity
chat-id]))
(= chat-type constants/community-chat-type)
(str (when emoji (str emoji " ")) "# " chat-name)
:else (str emoji chat-name))
online? (when-not group-chat (rf/sub [:visibility-status-updates/online? chat-id]))
photo-path (when-not group-chat (rf/sub [:chats/photo-path chat-id]))
header-opacity (worklets/navigation-header-opacity
distance-from-list-top
all-loaded?
chat-screen-layout-calculations-complete?
(if platform/ios?
messages.constants/content-animation-start-position-ios
messages.constants/content-animation-start-position-android))
header-position (worklets/navigation-header-position
distance-from-list-top
all-loaded?
messages.constants/top-bar-height
(if platform/ios?
messages.constants/content-animation-start-position-ios
messages.constants/content-animation-start-position-android))]
[reanimated/view
{:style (style/header-content-container header-opacity header-position)}
(when-not group-chat
(if group-chat
[quo/group-avatar
{:customization-color color
:size :size-32
:picture photo-path
:override-theme :dark}]
[quo/user-avatar
{:full-name display-name
:online? online?
@@ -70,7 +75,7 @@
(i18n/label
(if online? :t/online :t/offline))])]]))
(defn f-animated-background-and-pinned-banner
(defn animated-background-and-pinned-banner
[{:keys [chat-id navigation-view-height distance-from-list-top all-loaded?]}]
(let [animation-distance messages.constants/header-animation-distance
props {:distance-from-list-top distance-from-list-top
@@ -122,7 +127,7 @@
[all-loaded-sub])
[rn/view
{:style (style/navigation-view navigation-view-height messages.constants/pinned-banner-height)}
[:f> f-animated-background-and-pinned-banner
[animated-background-and-pinned-banner
{:chat-id chat-id
:navigation-view-height navigation-view-height
:distance-from-list-top distance-from-list-top
@@ -137,7 +142,7 @@
:accessibility-label :back-button
:on-press #(rf/dispatch [:navigate-back])}
(if (= chat-type constants/community-chat-type) :i/arrow-left :i/close)]]
[:f> f-header-content-container
[header-content-container
{:chat chat
:distance-from-list-top distance-from-list-top
:all-loaded? all-loaded?
@@ -13,7 +13,7 @@
;; NOTE(parvesh) - I am working on refactoring/optimization of the chat screen for performance
;; improvement. Please avoid refactoring these files. Also if you are not already working on bug
;; fixes related to the composer, please skip them. And ping me, so I can address them while refactoring
(defn- f-chat-screen
(defn- chat-screen
[chat-screen-layout-calculations-complete?]
(let [insets (safe-area/get-insets)
content-height (atom 0)
@@ -27,7 +27,7 @@
[messages.navigation/view
{:distance-from-list-top distance-from-list-top
:chat-screen-layout-calculations-complete? chat-screen-layout-calculations-complete?}]
[:f> list.view/f-messages-list-content
[list.view/messages-list-content
{:insets insets
:layout-height layout-height
:content-height content-height
@@ -46,15 +46,11 @@
(when-not screen-loaded?
(reanimated/set-shared-value chat-screen-layout-calculations-complete? false))
(when screen-loaded?
[:f> f-chat-screen chat-screen-layout-calculations-complete?])))
[chat-screen chat-screen-layout-calculations-complete?])))
(defn- f-chat
(defn chat
[]
(let [chat-screen-layout-calculations-complete? (reanimated/use-shared-value false)]
[:<>
[lazy-chat-screen chat-screen-layout-calculations-complete?]
[:f> placeholder.view/f-view chat-screen-layout-calculations-complete?]]))
(defn chat
[]
[:f> f-chat])
[placeholder.view/view chat-screen-layout-calculations-complete?]]))
@@ -1,7 +1,7 @@
(ns status-im.contexts.chat.messenger.photo-selector.effects
(:require
[clojure.string :as string]
[promesa.core :as p]
[promesa.core :as promesa]
[react-native.cameraroll :as cameraroll]
[react-native.core :as rn]
[react-native.image-resizer :as image-resizer]
@@ -31,19 +31,19 @@
(defn- resize-photo
[uri]
(p/let [[width height] (rn/image-get-size uri)
resize? (> (max width height)
maximum-image-size-px)
resized-uri (-> (image-resizer/resize
{:max-width (if resize? maximum-image-size-px width)
:max-height (if resize? maximum-image-size-px height)
:path uri
:quality 60})
(p/then (fn [^js resized-image]
(let [path (.-path resized-image)]
(if (string/starts-with? path "file")
path
(str "file://" path))))))]
(promesa/let [[width height] (rn/image-get-size uri)
resize? (> (max width height)
maximum-image-size-px)
resized-uri (-> (image-resizer/resize
{:max-width (if resize? maximum-image-size-px width)
:max-height (if resize? maximum-image-size-px height)
:path uri
:quality 60})
(promesa/then (fn [^js resized-image]
(let [path (.-path resized-image)]
(if (string/starts-with? path "file")
path
(str "file://" path))))))]
{:resized-uri resized-uri
:width width
:height height}))
@@ -51,9 +51,9 @@
(rf/reg-fx :effects.camera-roll/image-selected
(fn [[image chat-id]]
(-> (resize-photo (:uri image))
(p/then #(rf/dispatch
[:photo-selector/image-selected chat-id image %]))
(p/catch #(log/error "could not resize image" %)))))
(promesa/then #(rf/dispatch
[:photo-selector/image-selected chat-id image %]))
(promesa/catch #(log/error "could not resize image" %)))))
(defn- get-albums
[callback]
@@ -14,7 +14,7 @@
:parent-height (:height (rn/get-window))
:animated? false}])
(defn f-view
(defn view
[chat-screen-layout-calculations-complete?]
(let [top (safe-area/get-top)
opacity (worklets/placeholder-opacity chat-screen-layout-calculations-complete?)
@@ -1,13 +1,13 @@
(ns status-im.contexts.communities.actions.accounts-selection.effects
(:require
[promesa.core :as p]
[promesa.core :as promesa]
[schema.core :as schema]
[status-im.common.json-rpc.events :as rpc]
[utils.re-frame :as rf]))
(defn- generate-requests-for-signing
[pub-key community-id addresses-to-reveal]
(p/create
(promesa/create
(fn [p-resolve p-reject]
(rpc/call
{:method :wakuext_generateJoiningCommunityRequestsForSigning
@@ -17,7 +17,7 @@
(defn- sign-data
[sign-params password]
(p/create
(promesa/create
(fn [p-resolve p-reject]
(rpc/call
{:method :wakuext_signData
@@ -27,7 +27,7 @@
(defn- edit-shared-addresses-for-community
[community-id signatures addresses-to-reveal airdrop-address]
(p/create
(promesa/create
(fn [p-resolve p-reject]
(rpc/call
{:method :wakuext_editSharedAddressesForCommunity
@@ -41,7 +41,7 @@
(defn- request-to-join
[community-id signatures addresses-to-reveal airdrop-address]
(p/create
(promesa/create
(fn [p-resolve p-reject]
(rpc/call
{:method :wakuext_requestToJoinCommunity
@@ -66,14 +66,14 @@
addresses-to-reveal airdrop-address
on-success on-error
callback]}]
(-> (p/let [sign-params (generate-requests-for-signing pub-key community-id addresses-to-reveal)
signatures (sign-data sign-params password)
result (callback community-id
signatures
addresses-to-reveal
airdrop-address)]
(-> (promesa/let [sign-params (generate-requests-for-signing pub-key community-id addresses-to-reveal)
signatures (sign-data sign-params password)
result (callback community-id
signatures
addresses-to-reveal
airdrop-address)]
(run-callback-or-event on-success result))
(p/catch #(run-callback-or-event on-error %))))
(promesa/catch #(run-callback-or-event on-error %))))
(schema/=> sign-and-call-endpoint
[:=>
@@ -20,6 +20,13 @@
has-permissions? (rf/sub [:communities/has-permissions? id])
airdrop-account (rf/sub [:communities/airdrop-account id])
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
revealed-accounts-count (count revealed-accounts)
wallet-accounts-count (count (rf/sub [:wallet/accounts-without-watched-accounts]))
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
(i18n/label :t/all-addresses)
(i18n/label-pluralize
revealed-accounts-count
:t/address-count))
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
highest-role-text (i18n/label (communities.utils/role->translation-key
highest-permission-role
@@ -108,7 +115,7 @@
:label :preview
:label-props {:type :accounts
:data revealed-accounts}
:description-props {:text (i18n/label :t/all-addresses)}}
:description-props {:text addresses-shared-text}}
{:title (i18n/label :t/for-airdrops)
:on-press show-airdrop-addresses
:description :text
@@ -78,16 +78,14 @@
;; status-go will consider all possible addresses and the user will see the
;; incorrect highest permission role.
{:db (update db :communities/permissions-checks-for-selection dissoc community-id)}
(let [{:keys [checking?]} (get-in db [:communities/permissions-checks-for-selection community-id])]
(when-not checking?
{:db (assoc-in db [:communities/permissions-checks-for-selection community-id :checking?] true)
:fx [[:json-rpc/call
[{:method :wakuext_checkPermissionsToJoinCommunity
:params [{:communityId community-id :addresses addresses}]
:on-success [:communities/check-permissions-to-join-during-selection-success
community-id]
:on-error [:communities/check-permissions-to-join-during-selection-failure
community-id addresses]}]]]}))))
{:db (assoc-in db [:communities/permissions-checks-for-selection community-id :checking?] true)
:fx [[:json-rpc/call
[{:method :wakuext_checkPermissionsToJoinCommunity
:params [{:communityId community-id :addresses addresses}]
:on-success [:communities/check-permissions-to-join-during-selection-success
community-id]
:on-error [:communities/check-permissions-to-join-during-selection-failure
community-id addresses]}]]]}))
;; This event should be used to check permissions temporarily because it won't
;; mutate the state `:communities/permissions-check` (used by many other
@@ -103,11 +103,4 @@
community-id]
:on-error [:communities/check-permissions-to-join-during-selection-failure
community-id addresses]}]]]}
(sut/check-permissions-to-join-for-selection cofx [community-id addresses])))))
(testing "when there are addresses to check permissions, but currently checking, then skip the check"
(let [addresses ["0xA"]
cofx {:db {:communities/permissions-checks-for-selection
{"other-comm-id" {}
community-id {:checking? true}}}}]
(is (nil? (sut/check-permissions-to-join-for-selection cofx [community-id addresses]))))))
(sut/check-permissions-to-join-for-selection cofx [community-id addresses]))))))
@@ -195,41 +195,23 @@
:button-type :grey
:on-button-press open-permission-sheet))])]))
(defn view
[]
(let [{id :community-id} (rf/sub [:get-screen-params])
{:keys [color joined] outro-message :outroMessage} (rf/sub [:communities/community id])
highest-role (rf/sub [:communities/highest-role-for-selection id])
[unmodified-role _] (rn/use-state highest-role)
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
pending? (boolean (rf/sub [:communities/my-pending-request-to-join id]))
wallet-accounts (rf/sub [:wallet/accounts-without-watched-accounts])
unmodified-addresses-to-reveal (rf/sub [:communities/addresses-to-reveal id])
[addresses-to-reveal set-addresses-to-reveal] (rn/use-state unmodified-addresses-to-reveal)
unmodified-flag-share-all-addresses (rf/sub [:communities/share-all-addresses? id])
[flag-share-all-addresses
set-flag-share-all-addresses] (rn/use-state unmodified-flag-share-all-addresses)
identical-choices? (and (= unmodified-addresses-to-reveal addresses-to-reveal)
(= unmodified-flag-share-all-addresses flag-share-all-addresses))
toggle-flag-share-all-addresses
(fn []
(let [new-value (not flag-share-all-addresses)]
(set-flag-share-all-addresses new-value)
(when new-value
(set-addresses-to-reveal (set (map :address wallet-accounts))))))
(defn selection-bottom-actions
[id
{:keys [flag-share-all-addresses
addresses-to-reveal
cancel-selection
can-edit-addresses?
identical-choices?]}]
(let [color (rf/sub [:communities/community-color id])
outro-message (rf/sub [:communities/community-outro-message id])
joined (rf/sub [:communities/community-joined id])
checking? (rf/sub [:communities/permissions-check-for-selection-checking? id])
cancel-join-request
(rn/use-callback
(fn []
(rf/dispatch [:show-bottom-sheet
{:content (fn [] [cancel-join-request-drawer id])}])))
leave-community
(rn/use-callback
(fn []
@@ -237,14 +219,6 @@
{:content (fn [] [leave-community-drawer id outro-message])}]))
[outro-message])
cancel-selection
(fn []
(rf/dispatch [:communities/check-permissions-to-join-community
id
unmodified-addresses-to-reveal
:based-on-client-selection])
(rf/dispatch [:hide-bottom-sheet]))
confirm-changes
(fn []
(if can-edit-addresses?
@@ -263,7 +237,107 @@
(rf/dispatch [:hide-bottom-sheet]))}]))}])
(do
(rf/dispatch [:communities/set-share-all-addresses id flag-share-all-addresses])
(rf/dispatch [:communities/set-addresses-to-reveal id addresses-to-reveal]))))]
(rf/dispatch [:communities/set-addresses-to-reveal id addresses-to-reveal]))))
pending? (rf/sub [:communities/has-pending-request-to-join? id])
highest-role (rf/sub [:communities/highest-role-for-selection id])
[unmodified-role _] (rn/use-state highest-role)]
[quo/bottom-actions
(cond-> {:role (role-keyword highest-role)
:description (if highest-role
:top
:top-error)
:button-one-props {:customization-color color
:on-press confirm-changes
:disabled? (or checking?
(empty? addresses-to-reveal)
(not highest-role)
identical-choices?)}}
can-edit-addresses?
(->
(assoc :actions :one-action
:button-one-label (cond
(and pending? (not highest-role))
(i18n/label :t/cancel-request)
(and joined (not highest-role))
(i18n/label :t/leave-community)
:else
(i18n/label :t/confirm-changes))
:description-top-text (cond
(and pending? highest-role)
(i18n/label :t/eligible-to-join-as)
(and joined (= highest-role unmodified-role))
(i18n/label :t/you-are-a)
(and joined (not= highest-role unmodified-role))
(i18n/label :t/you-will-be-a))
:error-message (cond
(and pending? (not highest-role))
(i18n/label :t/community-join-requirements-not-met)
(and joined (not highest-role))
(i18n/label :t/membership-requirements-not-met)))
(update :button-one-props
merge
(cond (and pending? (not highest-role))
{:type :danger
:disabled? false
:on-press cancel-join-request}
(and joined (not highest-role))
{:type :danger
:disabled? false
:on-press leave-community})))
(not can-edit-addresses?)
(assoc :actions :two-actions
:button-one-label (i18n/label :t/confirm-changes)
:button-two-label (i18n/label :t/cancel)
:button-two-props {:type :grey
:on-press cancel-selection}
:error-message (cond
(empty? addresses-to-reveal)
(i18n/label :t/no-addresses-selected)
(not highest-role)
(i18n/label :t/addresses-dont-contain-tokens-needed))))]))
(defn view
[]
(let [{id :community-id} (rf/sub [:get-screen-params])
color (rf/sub [:communities/community-color id])
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
wallet-accounts (rf/sub [:wallet/accounts-without-watched-accounts])
unmodified-addresses-to-reveal (rf/sub [:communities/addresses-to-reveal id])
[addresses-to-reveal set-addresses-to-reveal] (rn/use-state unmodified-addresses-to-reveal)
unmodified-flag-share-all-addresses (rf/sub [:communities/share-all-addresses? id])
[flag-share-all-addresses
set-flag-share-all-addresses] (rn/use-state unmodified-flag-share-all-addresses)
identical-choices? (and (= unmodified-addresses-to-reveal addresses-to-reveal)
(= unmodified-flag-share-all-addresses flag-share-all-addresses))
cancel-selection
(fn []
(rf/dispatch [:communities/check-permissions-to-join-community
id
unmodified-addresses-to-reveal
:based-on-client-selection])
(rf/dispatch [:hide-bottom-sheet]))
toggle-flag-share-all-addresses
(fn []
(let [new-value (not flag-share-all-addresses)]
(set-flag-share-all-addresses new-value)
(when new-value
(set-addresses-to-reveal (set (map :address wallet-accounts))))))]
(rn/use-mount
(fn []
@@ -274,7 +348,6 @@
(fn []
(rf/dispatch [:communities/check-permissions-to-join-during-selection id addresses-to-reveal]))
[id addresses-to-reveal])
[:<>
[page-top
{:community-id id
@@ -288,79 +361,25 @@
id
color
flag-share-all-addresses]
:header [quo/category
{:list-type :settings
:data [{:title
(i18n/label
:t/share-all-current-and-future-addresses)
:action :selector
:action-props
{:on-change toggle-flag-share-all-addresses
:customization-color color
:checked? flag-share-all-addresses}}]
:container-style {:padding-bottom 16 :padding-horizontal 0}}]
:header [quo/page-setting
{:checked? flag-share-all-addresses
:customization-color color
:on-change toggle-flag-share-all-addresses
:setting-text (i18n/label
:t/share-all-current-and-future-addresses)
:container-style {:margin-bottom 16}}]
:content-container-style {:padding-horizontal 20}
:key-fn :address
:data wallet-accounts}]
[quo/bottom-actions
(cond-> {:role (role-keyword highest-role)
:description (if highest-role
:top
:top-error)
:button-one-props {:customization-color color
:on-press confirm-changes
:disabled? (or (empty? addresses-to-reveal)
(not highest-role)
identical-choices?)}}
can-edit-addresses?
(->
(assoc :actions :one-action
:button-one-label (cond
(and pending? (not highest-role))
(i18n/label :t/cancel-request)
(and joined (not highest-role))
(i18n/label :t/leave-community)
:else
(i18n/label :t/confirm-changes))
:description-top-text (cond
(and pending? highest-role)
(i18n/label :t/eligible-to-join-as)
(and joined (= highest-role unmodified-role))
(i18n/label :t/you-are-a)
(and joined (not= highest-role unmodified-role))
(i18n/label :t/you-will-be-a))
:error-message (cond
(and pending? (not highest-role))
(i18n/label :t/community-join-requirements-not-met)
(and joined (not highest-role))
(i18n/label :t/membership-requirements-not-met)))
(update :button-one-props
merge
(cond (and pending? (not highest-role))
{:type :danger
:disabled? false
:on-press cancel-join-request}
(and joined (not highest-role))
{:type :danger
:disabled? false
:on-press leave-community})))
(not can-edit-addresses?)
(assoc :actions :two-actions
:button-one-label (i18n/label :t/confirm-changes)
:button-two-label (i18n/label :t/cancel)
:button-two-props {:type :grey
:on-press cancel-selection}
:error-message (cond
(empty? addresses-to-reveal)
(i18n/label :t/no-addresses-selected)
(not highest-role)
(i18n/label :t/addresses-dont-contain-tokens-needed))))]]))
[selection-bottom-actions id
{:flag-share-all-addresses
flag-share-all-addresses
:addresses-to-reveal
addresses-to-reveal
:cancel-selection
cancel-selection
:can-edit-addresses?
can-edit-addresses?
:identical-choices?
identical-choices?}]]))
@@ -69,6 +69,7 @@
:title (i18n/label :t/airdrop-addresses)
:community-name name
:button-icon :i/info
:button-type :grey
:on-button-press not-implemented/alert
:community-logo logo
:customization-color color}])
@@ -3,7 +3,7 @@
[taoensso.timbre :as log]
[utils.re-frame :as rf]))
(def commmunity-keys-renamed
(def community-keys-renamed
{:requestedAccessAt :requested-access-at
:fileSize :file-size
:communityTokensMetadata :community-tokens-metadata
@@ -35,7 +35,7 @@
[k]
(let [s (name k)
starts-with-digit? (re-matches #"^\d.*" s)
existing-rename (k commmunity-keys-renamed)]
existing-rename (k community-keys-renamed)]
(cond starts-with-digit? s
existing-rename existing-rename
:else (keyword s))))
@@ -178,23 +178,16 @@
:container-style {:margin-horizontal 12 :margin-top 12 :margin-bottom 12}
:disabled? (not can-request-access?)
:icon-left (if can-request-access? :i/unlocked :i/locked)}
(i18n/label :t/join-open-community)]])))
(i18n/label :t/request-to-join)]])))
(defn- join-community
[{:keys [id joined permissions can-request-access?] :as community}]
[{:keys [id joined permissions] :as community}]
(let [pending? (rf/sub [:communities/my-pending-request-to-join id])
access-type (get-access-type (:access permissions))
unknown-access? (= access-type :unknown-access)
invite-only? (= access-type :invite-only)]
[:<>
(when-not (or joined pending? invite-only? unknown-access?)
[token-requirements community])
(when (and can-request-access? (not joined))
[quo/text
{:size :paragraph-2
:weight :regular
:style style/review-notice}
(i18n/label :t/community-admins-will-review-your-request)])]))
(when-not (or joined pending? invite-only? unknown-access?)
[token-requirements community])))
(defn- status-tag
[community-id joined]
@@ -69,9 +69,9 @@
(rn/use-effect
(fn []
(reanimated/set-shared-value @paused? (not= view-id :intro))
(reanimated/set-shared-value @paused? (not= view-id :screen/onboarding.intro))
(fn []
(when (= view-id :generating-keys)
(when (= view-id :screen/onboarding.generating-keys)
(carousel.animation/cleanup-animation progress paused?))))
[view-id])
@@ -153,7 +153,7 @@
@full-name
(i18n/label :t/your-name))
:customization-color @custom-color}
:title-input-props {:default-value @full-name
:title-input-props {:default-value display-name
:auto-focus true
:max-length c/profile-name-max-length
:on-change-text on-change-text}}]]
@@ -28,7 +28,7 @@
bio-type-label (biometric/get-label-by-type supported-biometric-type)
profile-color (or (:color (rf/sub [:onboarding/profile]))
(rf/sub [:profile/customization-color]))
syncing-results? (= :syncing-results @state/root-id)]
syncing-results? (= :screen/onboarding.syncing-results @state/root-id)]
[rn/view {:style (style/buttons insets)}
[quo/button
{:size 40
@@ -43,7 +43,8 @@
:type :grey
:on-press #(rf/dispatch (if syncing-results?
[:navigate-to-within-stack
[:enable-notifications :enable-biometrics]]
[:screen/onboarding.enable-notifications
:screen/onboarding.enable-biometrics]]
[:onboarding/create-account-and-login]))
:container-style {:margin-top 12}}
(i18n/label :t/maybe-later)]]))
@@ -36,7 +36,8 @@
:on-denied #(log/error "user denied push notification permissions")}])
(rf/dispatch [:push-notifications/switch true platform/ios?])
(rf/dispatch [:navigate-to-within-stack
[:welcome :enable-notifications]]))
[:screen/onboarding.welcome
:screen/onboarding.enable-notifications]]))
:type :primary
:icon-left :i/notifications
:accessibility-label :enable-notifications-button
@@ -46,7 +47,8 @@
{:on-press (fn []
(shell.utils/change-selected-stack-id :communities-stack true nil)
(rf/dispatch [:navigate-to-within-stack
[:welcome :enable-notifications]]))
[:screen/onboarding.welcome
:screen/onboarding.enable-notifications]]))
:accessibility-label :enable-notifications-later-button
:type :grey
:background :blur
+18 -11
View File
@@ -27,7 +27,8 @@
{:events [:onboarding/profile-data-set]}
[{:keys [db]} onboarding-data]
{:db (update db :onboarding/profile merge onboarding-data)
:dispatch [:navigate-to-within-stack [:create-profile-password :new-to-status]]})
:dispatch [:navigate-to-within-stack
[:screen/onboarding.create-profile-password :screen/onboarding.new-to-status]]})
(rf/defn enable-biometrics
{:events [:onboarding/enable-biometrics]}
@@ -42,7 +43,8 @@
[{:keys [db]}]
(let [key-uid (get-in db [:profile/profile :key-uid])]
{:db (dissoc db :onboarding/profile)
:dispatch [:navigate-to-within-stack [:enable-notifications :enable-biometrics]]}))
:dispatch [:navigate-to-within-stack
[:screen/onboarding.enable-notifications :screen/onboarding.enable-biometrics]]}))
(rf/defn biometrics-done
{:events [:onboarding/biometrics-done]}
@@ -64,7 +66,8 @@
(let [{:keys [display-name seed-phrase password image-path color] :as profile}
(:onboarding/profile db)]
(rf/merge cofx
{:dispatch [:navigate-to-within-stack [:generating-keys :new-to-status]]
{:dispatch [:navigate-to-within-stack
[:screen/onboarding.generating-keys :screen/onboarding.new-to-status]]
:dispatch-later [{:ms constants/onboarding-generating-keys-animation-duration-ms
:dispatch [:onboarding/navigate-to-identifiers]}]
:db (-> db
@@ -82,7 +85,7 @@
(merge
{:db (assoc db :profile/profiles-overview multiaccounts)}
(when-not (seq multiaccounts)
{:set-root :intro}))))
{:set-root :screen/onboarding.intro}))))
(rf/defn password-set
{:events [:onboarding/password-set]}
@@ -92,7 +95,8 @@
(assoc-in [:onboarding/profile :password] password)
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
:dispatch (if supported-type
[:navigate-to-within-stack [:enable-biometrics :new-to-status]]
[:navigate-to-within-stack
[:screen/onboarding.enable-biometrics :screen/onboarding.new-to-status]]
[:onboarding/create-account-and-login])}))
(rf/defn navigate-to-enable-biometrics
@@ -100,8 +104,8 @@
[{:keys [db]}]
(let [supported-type (get-in db [:biometrics :supported-type])]
{:dispatch (if supported-type
[:open-modal :enable-biometrics]
[:open-modal :enable-notifications])}))
[:open-modal :screen/onboarding.enable-biometrics]
[:open-modal :screen/onboarding.enable-notifications])}))
(rf/defn seed-phrase-entered
{:events [:onboarding/seed-phrase-entered]}
@@ -121,19 +125,21 @@
:content (i18n/label :t/multiaccount-exists-content)
:confirm-button-text (i18n/label :t/unlock)
:on-accept (fn []
(re-frame/dispatch [:pop-to-root :profiles])
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
(re-frame/dispatch
[:profile/profile-selected key-uid]))
:on-cancel #(re-frame/dispatch [:pop-to-root :multiaccounts])}}
{:db (assoc-in db [:onboarding/profile :seed-phrase] seed-phrase)
:dispatch [:navigate-to-within-stack [:create-profile :new-to-status]]}))
:dispatch [:navigate-to-within-stack
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]}))
(rf/defn navigate-to-create-profile
{:events [:onboarding/navigate-to-create-profile]}
[{:keys [db]}]
;; Restart the flow
{:db (dissoc db :onboarding/profile)
:dispatch [:navigate-to-within-stack [:create-profile :new-to-status]]})
:dispatch [:navigate-to-within-stack
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]})
(rf/reg-event-fx :onboarding/set-auth-method
(fn [{:keys [db]} [auth-method]]
@@ -167,6 +173,7 @@
{:events [:onboarding/navigate-to-identifiers]}
[{:keys [db]}]
(if (:onboarding/generated-keys? db)
{:dispatch [:navigate-to-within-stack [:identifiers :new-to-status]]}
{:dispatch [:navigate-to-within-stack
[:screen/onboarding.identifiers :screen/onboarding.new-to-status]]}
{:dispatch-later [{:ms constants/onboarding-generating-keys-navigation-retry-ms
:dispatch [:onboarding/navigate-to-identifiers]}]}))
@@ -63,7 +63,8 @@
:type :grey
:background :blur
:on-press #(rf/dispatch [:navigate-to-within-stack
[:enable-notifications :new-to-status]])
[:screen/onboarding.enable-notifications
:screen/onboarding.new-to-status]])
:container-style style/button}
(i18n/label :t/continue)]]]]))
@@ -19,9 +19,10 @@
(reset! scan-sync-code/dismiss-animations reset-top-animation-fn))
:animations-duration constants/onboarding-modal-animation-duration
:animations-delay constants/onboarding-modal-animation-delay
:top-card {:on-press #(debounce/throttle-and-dispatch [:open-modal
:sign-in-intro]
2000)
:top-card {:on-press #(debounce/throttle-and-dispatch
[:open-modal
:screen/onboarding.sign-in-intro]
2000)
:heading (i18n/label :t/sign-in)
:animated-heading (i18n/label :t/sign-in-by-syncing)
:accessibility-label :already-use-status-button}
@@ -29,7 +30,7 @@
(when-let [blur-show-fn @overlay/blur-show-fn-atom]
(blur-show-fn))
(debounce/throttle-and-dispatch
[:open-modal :new-to-status]
[:open-modal :screen/onboarding.new-to-status]
1000))
:heading (i18n/label :t/new-to-status)
:accessibility-label :new-to-status-button}}
@@ -45,7 +45,9 @@
:title (i18n/label :t/use-recovery-phrase)
:subtitle (i18n/label :t/use-recovery-phrase-subtitle)
:image (resources/get-image :ethereum-address)
:on-press #(rf/dispatch [:navigate-to-within-stack [:enter-seed-phrase :new-to-status]])}]
:on-press #(rf/dispatch [:navigate-to-within-stack
[:screen/onboarding.enter-seed-phrase
:screen/onboarding.new-to-status]])}]
[rn/view {:style style/space-between-suboptions}]
[quo/small-option-card
{:variant :icon
@@ -32,11 +32,14 @@
(rf/dispatch [:syncing/clear-states])
(cond
logged-in? (rf/dispatch [:navigate-back])
in-onboarding? (rf/dispatch [:navigate-back-to :sign-in-intro])
in-onboarding? (rf/dispatch [:navigate-back-to
:screen/onboarding.sign-in-intro])
:else (do
(rf/dispatch [:navigate-back])
(debounce/throttle-and-dispatch [:open-modal :sign-in]
1000))))
(debounce/throttle-and-dispatch
[:open-modal
:screen/onboarding.sign-in]
1000))))
:accessibility-label :try-again-later-button
:customization-color profile-color
:container-style style/try-again-button}

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