Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9cdeaf6152 |
@@ -26,7 +26,7 @@
|
||||
malli.generator malli.generator
|
||||
malli.transform malli.transform
|
||||
malli.util malli.util
|
||||
promesa.core promesa
|
||||
promesa.core p
|
||||
schema.core schema
|
||||
status-im.feature-flags ff
|
||||
taoensso.timbre log}}
|
||||
|
||||
@@ -34,4 +34,3 @@ STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
TEST_STATEOFUS=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||
TEST_NETWORKS_ENABLED=1
|
||||
|
||||
@@ -33,4 +33,3 @@ TWO_MINUTES_SYNCING=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||
TEST_NETWORKS_ENABLED=1
|
||||
|
||||
@@ -35,4 +35,3 @@ ENABLE_QUO_PREVIEW=1
|
||||
STICKERS_TEST_ENABLED=1
|
||||
LOCAL_PAIRING_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=1
|
||||
TEST_NETWORKS_ENABLED=1
|
||||
|
||||
@@ -22,4 +22,3 @@ COMMUNITIES_ENABLED=1
|
||||
DATABASE_MANAGEMENT_ENABLED=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||
TEST_NETWORKS_ENABLED=0
|
||||
|
||||
@@ -20,4 +20,3 @@ MAX_IMAGES_BATCH=1
|
||||
DELETE_MESSAGE_ENABLED=1
|
||||
COLLECTIBLES_ENABLED=1
|
||||
FAST_CREATE_COMMUNITY_ENABLED=0
|
||||
TEST_NETWORKS_ENABLED=0
|
||||
|
||||
@@ -259,7 +259,7 @@ status-go-library: ##@status-go Compile status-go for node-js
|
||||
|
||||
run-clojure: export TARGET := clojure
|
||||
run-clojure: ##@run Watch for and build Clojure changes for mobile
|
||||
yarn shadow-cljs watch mobile
|
||||
bun shadow-cljs watch mobile
|
||||
|
||||
run-metro: export TARGET := clojure
|
||||
run-metro: ##@run Start Metro to build React Native changes
|
||||
@@ -267,7 +267,7 @@ run-metro: ##@run Start Metro to build React Native changes
|
||||
|
||||
run-re-frisk: export TARGET := clojure
|
||||
run-re-frisk: ##@run Start re-frisk server
|
||||
yarn shadow-cljs run re-frisk-remote.core/start
|
||||
bun shadow-cljs run re-frisk-remote.core/start
|
||||
|
||||
# TODO: Migrate this to a Nix recipe, much the same way as nix/mobile/android/targets/release-android.nix
|
||||
run-android: export TARGET := android
|
||||
@@ -327,20 +327,20 @@ lint-fix: ##@test Run code style checks and fix issues
|
||||
|
||||
shadow-server: export TARGET := clojure
|
||||
shadow-server:##@ Start shadow-cljs in server mode for watching
|
||||
yarn shadow-cljs server
|
||||
bun shadow-cljs server
|
||||
|
||||
_test-clojure: export TARGET := clojure
|
||||
_test-clojure: export WATCH ?= false
|
||||
_test-clojure: status-go-library
|
||||
_test-clojure:
|
||||
ifeq ($(WATCH), true)
|
||||
yarn node-pre-gyp rebuild && \
|
||||
yarn shadow-cljs compile mocks && \
|
||||
nodemon --exec "yarn shadow-cljs compile test && node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO" -e cljs
|
||||
bun node-pre-gyp rebuild && \
|
||||
bun shadow-cljs compile mocks && \
|
||||
nodemon --exec "bun shadow-cljs compile test && node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO" -e cljs
|
||||
else
|
||||
yarn node-pre-gyp rebuild && \
|
||||
yarn shadow-cljs compile mocks && \
|
||||
yarn shadow-cljs compile test && \
|
||||
bun node-pre-gyp rebuild && \
|
||||
bun shadow-cljs compile mocks && \
|
||||
bun shadow-cljs compile test && \
|
||||
node --require ./test-resources/override.js "$$SHADOW_OUTPUT_TO"
|
||||
endif
|
||||
|
||||
@@ -353,11 +353,11 @@ test-watch-for-repl: export SHADOW_OUTPUT_TO := target/test/test.js
|
||||
test-watch-for-repl: export SHADOW_NS_REGEXP := .*-test$$
|
||||
test-watch-for-repl: status-go-library
|
||||
test-watch-for-repl: ##@test Watch all Clojure tests and support REPL connections
|
||||
yarn node-pre-gyp rebuild
|
||||
bun node-pre-gyp rebuild
|
||||
rm -f target/test/test.js
|
||||
yarn shadow-cljs compile mocks && \
|
||||
bun shadow-cljs compile mocks && \
|
||||
concurrently --kill-others --prefix-colors 'auto' --names 'build,repl' \
|
||||
'yarn shadow-cljs watch test --verbose' \
|
||||
'bun shadow-cljs watch test --verbose' \
|
||||
"until [ -f $$SHADOW_OUTPUT_TO ] ; do sleep 1 ; done ; node --require ./test-resources/override.js $$SHADOW_OUTPUT_TO --repl"
|
||||
|
||||
test-unit: export SHADOW_OUTPUT_TO := target/unit_test/test.js
|
||||
@@ -375,28 +375,28 @@ test-contract: export SHADOW_NS_REGEXP := ^tests\.contract-test.*$$
|
||||
test-contract: ##@test Run contract tests
|
||||
test-contract: _test-clojure
|
||||
|
||||
test-android: jsbundle
|
||||
test-android: export TARGET := android
|
||||
test-android: ##@test Android Gradle test
|
||||
android-test: jsbundle
|
||||
android-test: export TARGET := android
|
||||
android-test:
|
||||
cd android && ./gradlew test
|
||||
|
||||
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
|
||||
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
|
||||
@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
|
||||
nodemon --exec 'bun shadow-cljs compile component-test && jest --config=test/jest/jest.config.js --testEnvironment node ' -e cljs
|
||||
|
||||
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
|
||||
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
|
||||
@scripts/check-metro-shadow-process.sh
|
||||
rm -rf ./component-spec
|
||||
yarn shadow-cljs compile component-test && \
|
||||
bun shadow-cljs compile component-test && \
|
||||
jest --clearCache && jest --config=test/jest/jest.config.js --testEnvironment node
|
||||
|
||||
#--------------
|
||||
@@ -447,7 +447,7 @@ _list:
|
||||
|
||||
repl-clojure: export TARGET := clojure
|
||||
repl-clojure: ##@repl Start Clojure repl for mobile App
|
||||
yarn shadow-cljs cljs-repl mobile
|
||||
bun shadow-cljs cljs-repl mobile
|
||||
|
||||
repl-nix: nix-repl ##@repl Start an interactive Nix REPL
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
/* 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'
|
||||
PLATFORM = "android${utils.isE2EBuild() ? "-e2e" : ""}"
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = "android${utils.isE2EBuild() ? "-e2e" : ""}"
|
||||
BUILD_ENV = 'prod'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
/* 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'
|
||||
PLATFORM = 'ios'
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = 'ios'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
BUNDLE_PATH = "${HOME}/.bundle"
|
||||
|
||||
+41
-34
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -29,47 +29,61 @@ 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'
|
||||
PLATFORM = 'tests'
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = '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('Test') {
|
||||
stage('Checks') {
|
||||
parallel {
|
||||
stage('Lint') {
|
||||
steps { make('lint') }
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make lint CLJ_LINTER_PRINT_WARNINGS=true 2>&1 | tee ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('Unit') {
|
||||
steps { make('test-unit') }
|
||||
}
|
||||
stage('Component') {
|
||||
steps { make('test-component') }
|
||||
stage('Unit Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make test-unit 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('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('Upload') {
|
||||
@@ -86,10 +100,3 @@ pipeline {
|
||||
always { sh 'make purge' }
|
||||
}
|
||||
}
|
||||
|
||||
def make(target) {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make ${target} 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
environment {
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
PLATFORM = 'ios'
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
TARGET = 'ios'
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
/* avoid writing to r/o /nix */
|
||||
GEM_HOME = '~/.rubygems'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
environment {
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
PLATFORM = 'ios'
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
TARGET = 'ios'
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
/* avoid writing to r/o /nix */
|
||||
GEM_HOME = '~/.rubygems'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -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 test-component`
|
||||
`make component-test`
|
||||
setups and runs the test suite once.
|
||||
|
||||
`make test-component-watch`
|
||||
`make component-test-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
@@ -54,13 +54,13 @@ Here I'm showing a terminal-only experience using Tmux (left pane Emacs, right p
|
||||
To run tests:
|
||||
|
||||
```
|
||||
make test-component
|
||||
make component-test
|
||||
```
|
||||
|
||||
Also test watcher can be launched. It will re-run the entire test suite when any file is modified
|
||||
|
||||
```
|
||||
make test-component-watch
|
||||
make component-test-watch
|
||||
```
|
||||
|
||||
Check [component tests doc](./component-tests-overview.md) for more.
|
||||
|
||||
@@ -61,8 +61,6 @@
|
||||
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 */
|
||||
@@ -156,8 +154,6 @@
|
||||
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 */
|
||||
@@ -272,8 +268,6 @@
|
||||
83CBB9F61A601CBA00E9B192 = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E9AC7FD72BB8FDAB0024A0AF /* HelloWorldJSI.cpp */,
|
||||
E9AC7FD82BB8FDAB0024A0AF /* HelloWorldJSI.h */,
|
||||
65F6941825780A4F00A45E76 /* Bridge.swift */,
|
||||
3AAD2AB624A3A5F10075D594 /* StatusImPR */,
|
||||
13B07FAE1A68108700A75B9A /* StatusIm */,
|
||||
@@ -743,7 +737,6 @@
|
||||
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;
|
||||
@@ -755,7 +748,6 @@
|
||||
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;
|
||||
|
||||
@@ -73,17 +73,6 @@ 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;
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
#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));
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
#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);
|
||||
};
|
||||
+1
-1
@@ -23,7 +23,7 @@ in mkShell {
|
||||
# build specific utilities
|
||||
clojure maven watchman
|
||||
# other nice to have stuff
|
||||
yarn nodejs python310 maestro
|
||||
bun yarn nodejs python310 maestro
|
||||
] # and some special cases
|
||||
++ lib.optionals stdenv.isDarwin ([ cocoapods clang tcl idb-companion ] ++ appleSDKFrameworks)
|
||||
++ lib.optionals (!stdenv.isDarwin) [ gcc8 ]
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"_comment": "This also prevents 'yarn install' from running outside of nix.",
|
||||
"preinstall": "scripts/check-nix-shell.sh && make status-go-library"
|
||||
"preinstall": "make status-go-library"
|
||||
},
|
||||
"dependencies": {
|
||||
"@babel/preset-typescript": "^7.17.12",
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 181 B |
Binary file not shown.
|
Before Width: | Height: | Size: 203 B |
Binary file not shown.
|
Before Width: | Height: | Size: 1.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
#!/bin/bash
|
||||
|
||||
# Increment a version string using Semantic Versioning (SemVer) terminology.
|
||||
|
||||
|
||||
@@ -62,29 +62,25 @@
|
||||
|
||||
(defn <-color
|
||||
[value]
|
||||
(if (and (some? value)
|
||||
(string/starts-with? value "#"))
|
||||
value
|
||||
(keyword value)))
|
||||
(if (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
|
||||
:hideIfPermissionsNotMet :hide-if-permissions-not-met?})
|
||||
(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})
|
||||
rpc->type
|
||||
unmarshal-members
|
||||
(update :last-message #(when % (messages/<-rpc %)))
|
||||
@@ -93,40 +89,38 @@
|
||||
|
||||
(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))
|
||||
:hide-if-permissions-not-met (.-hideIfPermissionsNotMet 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))}
|
||||
rpc->type
|
||||
unmarshal-members))
|
||||
|
||||
|
||||
@@ -27,11 +27,10 @@
|
||||
(assoc acc
|
||||
(name k)
|
||||
(-> v
|
||||
(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)
|
||||
(assoc :token-gated? (:tokenGated v)
|
||||
:can-post? (:canPost v)
|
||||
:can-view? (:canView v))
|
||||
(dissoc :canPost :tokenGated :canView)
|
||||
(update :members walk/stringify-keys))))
|
||||
{}
|
||||
chats))
|
||||
@@ -64,7 +63,6 @@
|
||||
:canJoin :can-join?
|
||||
:requestedToJoinAt :requested-to-join-at
|
||||
:isMember :is-member?
|
||||
:outroMessage :outro-message
|
||||
:adminSettings :admin-settings
|
||||
:tokenPermissions :token-permissions
|
||||
:communityTokensMetadata :tokens-metadata
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
[{:keys [db] :as cofx}]
|
||||
(rf/merge cofx
|
||||
{:db db}
|
||||
(navigation/pop-to-root :screen/profile.profiles)))
|
||||
(navigation/pop-to-root :profiles)))
|
||||
|
||||
(rf/defn login-pin-more-icon-pressed
|
||||
{:events [:keycard.login.pin.ui/more-icon-pressed]}
|
||||
|
||||
@@ -74,8 +74,7 @@
|
||||
(assoc :recovered-account? true))
|
||||
:keycard/check-nfc-enabled nil}
|
||||
(bottom-sheet/hide-bottom-sheet-old)
|
||||
(navigation/navigate-to-within-stack [:keycard-recovery-intro
|
||||
:screen/onboarding.new-to-status])))
|
||||
(navigation/navigate-to-within-stack [:keycard-recovery-intro :new-to-status])))
|
||||
|
||||
(rf/defn access-key-pressed
|
||||
{:events [:multiaccounts.recover.ui/recover-multiaccount-button-pressed]}
|
||||
@@ -128,7 +127,7 @@
|
||||
:multiaccount-whisper-public-key)}
|
||||
(navigation/navigate-to (if platform/android?
|
||||
:notifications-settings
|
||||
:screen/onboarding.welcome)
|
||||
:welcome)
|
||||
nil)))
|
||||
|
||||
(rf/defn intro-wizard
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(: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]
|
||||
@@ -144,6 +145,23 @@
|
||||
[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,7 +13,6 @@
|
||||
[{: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})
|
||||
@@ -21,5 +20,4 @@
|
||||
(def channel-action-row
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
:align-items :center
|
||||
:padding-right 2})
|
||||
:align-items :center})
|
||||
|
||||
@@ -8,10 +8,9 @@
|
||||
(defn date
|
||||
[value]
|
||||
[rn/view
|
||||
{:padding-top 8
|
||||
:padding-bottom 12
|
||||
:padding-right 20
|
||||
:padding-left 60}
|
||||
{:margin-vertical 12
|
||||
:padding-right 20
|
||||
:padding-left 60}
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:accessibility-label :divider-date-text
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
(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"))))
|
||||
@@ -1,16 +0,0 @@
|
||||
(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])
|
||||
@@ -1,55 +0,0 @@
|
||||
(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)))
|
||||
@@ -1,73 +0,0 @@
|
||||
(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,8 +81,7 @@
|
||||
(let [tag-type (or context-tag-type :account)]
|
||||
[rn/view
|
||||
{:accessibility-label :context-tag-wrapper
|
||||
:style {:flex-wrap :wrap
|
||||
:margin-top 4}}
|
||||
:style {:flex-wrap :wrap}}
|
||||
[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.
|
||||
(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)
|
||||
(when customization-color
|
||||
(let [color-top (colors/resolve-color customization-color 50 20)
|
||||
color-bottom (colors/resolve-color customization-color 50 0)]
|
||||
[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-40))))))
|
||||
colors/neutral-30))))))
|
||||
|
||||
(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-40))))))
|
||||
colors/neutral-80-opa-20))))))
|
||||
|
||||
(h/test "on blur with no text and blur? false"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
|
||||
@@ -58,64 +58,78 @@
|
||||
[{: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 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))
|
||||
(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 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?])]
|
||||
(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)
|
||||
(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
|
||||
@@ -123,7 +137,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
|
||||
|
||||
@@ -57,19 +57,14 @@
|
||||
"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 :ref])
|
||||
:container-style])
|
||||
|
||||
(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-clear]
|
||||
on-change-text on-char-limit-reach weight default-value]
|
||||
: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))
|
||||
@@ -98,15 +93,6 @@
|
||||
: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)
|
||||
@@ -122,8 +108,7 @@
|
||||
:small? small?
|
||||
:icon-name icon-name}])
|
||||
[rn/text-input
|
||||
(cond-> {:ref on-ref
|
||||
:style (style/input colors-by-status small? multiple-lines? weight)
|
||||
(cond-> {: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)
|
||||
@@ -162,10 +147,7 @@
|
||||
[{:keys [default-shown?]
|
||||
:or {default-shown? false}
|
||||
:as props}]
|
||||
(let [[password-shown?
|
||||
set-password-shown] (rn/use-state default-shown?)
|
||||
on-press (rn/use-callback #(set-password-shown (not password-shown?))
|
||||
[password-shown?])]
|
||||
(let [[password-shown? set-password-shown] (rn/use-state default-shown?)]
|
||||
[base-input
|
||||
(assoc props
|
||||
:accessibility-label :password-input
|
||||
@@ -174,7 +156,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 on-press})]))
|
||||
:on-press #(set-password-shown (not password-shown?))})]))
|
||||
|
||||
(defn input
|
||||
"This input supports the following properties:
|
||||
@@ -200,11 +182,15 @@
|
||||
- :on-change-text
|
||||
...
|
||||
"
|
||||
[{:keys [type icon-name]
|
||||
[{:keys [type clearable? on-clear icon-name]
|
||||
:or {type :text}
|
||||
:as props}]
|
||||
(let [base-props (cond-> props
|
||||
icon-name (assoc-in [:left-icon :icon-name] icon-name))]
|
||||
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))}))]
|
||||
(if (= type :password)
|
||||
[password-input base-props]
|
||||
[base-input base-props])))
|
||||
|
||||
@@ -26,20 +26,14 @@
|
||||
:padding-vertical 8
|
||||
:padding-horizontal 12}))
|
||||
|
||||
(def right-side-container
|
||||
{:flex 1
|
||||
:justify-content :center})
|
||||
(def right-side-container {:flex 1})
|
||||
|
||||
(defn title
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
|
||||
|
||||
(defn text
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 theme)})
|
||||
[override-theme]
|
||||
{:color (colors/theme-colors colors/white colors/neutral-100 override-theme)})
|
||||
|
||||
(defn avatar-container
|
||||
[{:keys [multiline?]}]
|
||||
{:margin-right 8
|
||||
:align-self (when-not multiline? :center)
|
||||
:margin-top (if multiline? 4 0)})
|
||||
(def avatar-container {:margin-right 8 :margin-top 4})
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
(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]))
|
||||
|
||||
@@ -17,33 +15,33 @@
|
||||
[into [rn/view {:accessibility-label :notification-body}] children])
|
||||
|
||||
(defn avatar-container
|
||||
[{:keys [multiline?]} & children]
|
||||
[& children]
|
||||
[into
|
||||
[rn/view
|
||||
{:style (style/avatar-container {:multiline? multiline?})
|
||||
{:style style/avatar-container
|
||||
:accessibility-label :notification-avatar}]
|
||||
children])
|
||||
|
||||
(defn title
|
||||
([{:keys [text weight theme multiline?]}]
|
||||
([text weight] (title text weight nil))
|
||||
([text weight override-theme]
|
||||
[text/text
|
||||
{:size :paragraph-1
|
||||
:weight (or weight (if multiline? :semi-bold :medium))
|
||||
:style (style/title theme)
|
||||
:weight (or weight :semi-bold)
|
||||
:style (style/title override-theme)
|
||||
:accessibility-label :notification-title}
|
||||
text]))
|
||||
|
||||
(defn message
|
||||
[text theme]
|
||||
[text override-theme]
|
||||
[text/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/text theme)
|
||||
:style (style/text override-theme)
|
||||
:accessibility-label :notification-content}
|
||||
text])
|
||||
|
||||
(defn- notification-container
|
||||
[{:keys [avatar header body container-style theme]}]
|
||||
[{:keys [avatar header body container-style override-theme]}]
|
||||
[rn/view
|
||||
{:style (merge style/box-container container-style)}
|
||||
[blur/view
|
||||
@@ -53,7 +51,7 @@
|
||||
:blur-type :transparent
|
||||
:overlay-color :transparent}]
|
||||
[rn/view
|
||||
{:style (style/content-container theme)}
|
||||
{:style (style/content-container override-theme)}
|
||||
avatar
|
||||
[rn/view
|
||||
{:style style/right-side-container}
|
||||
@@ -61,27 +59,17 @@
|
||||
body]]])
|
||||
|
||||
(defn notification
|
||||
[{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}]]))
|
||||
[{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}]))
|
||||
|
||||
@@ -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)) [on-press label])
|
||||
on-press (rn/use-callback #(when on-press (on-press label)) [label])
|
||||
on-long-press (rn/use-callback #(when (fn? on-long-press) (on-long-press label))
|
||||
[on-long-press label])
|
||||
[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,7 +4,8 @@
|
||||
|
||||
(def container
|
||||
(merge (shadows/get 2)
|
||||
{:align-items :center
|
||||
{:flex 1
|
||||
:align-items :center
|
||||
:justify-content :center
|
||||
:border-radius 16}))
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(ns quo.components.profile.expanded-collectible.view
|
||||
(:require
|
||||
[promesa.core :as promesa]
|
||||
[promesa.core :as p]
|
||||
[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 []
|
||||
(promesa/let [[image-width image-height] (rn/image-get-size image-src)]
|
||||
(p/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
|
||||
[rn/view {:style {:flex 1}}
|
||||
[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} [:maybe string?]]
|
||||
[:image-src {:optional true} string?]
|
||||
[:container-style {:optional true} [:maybe :map]]
|
||||
[:square? {:optional true} [:maybe boolean?]]
|
||||
[:counter {:optional true} [:maybe string?]]
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
(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"))))
|
||||
@@ -1,14 +0,0 @@
|
||||
(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})
|
||||
@@ -1,24 +0,0 @@
|
||||
(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,12 +7,11 @@
|
||||
[react-native.core :as rn]))
|
||||
|
||||
(defn- view-internal
|
||||
[{:keys [title networks status theme blur? container-style] :or {status :default}}]
|
||||
[{:keys [title networks status theme blur?] :or {status :default}}]
|
||||
[rn/view
|
||||
{:style (merge (style/container {:status status
|
||||
:theme theme
|
||||
:blur? blur?})
|
||||
container-style)}
|
||||
{:style (style/container {:status status
|
||||
:theme theme
|
||||
:blur? blur?})}
|
||||
[preview-list/view
|
||||
{:type :network
|
||||
:number (count networks)
|
||||
|
||||
@@ -100,7 +100,8 @@
|
||||
: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
|
||||
@@ -112,17 +113,19 @@
|
||||
: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,24 +12,32 @@
|
||||
(h/describe "Amount input component"
|
||||
(h/test "Renders with default value"
|
||||
(let [text-expected 0]
|
||||
(render [amount-input/view {:value text-expected}])
|
||||
(h/is-truthy (h/query-by-label-text :amount-input))))
|
||||
(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))))
|
||||
|
||||
(h/test "When the value = minimum dec button is disabled"
|
||||
(render [amount-input/view
|
||||
{:value 0
|
||||
:min-value 0}])
|
||||
{:init-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
|
||||
{:value 100
|
||||
:max-value 100}])
|
||||
{:init-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 :value 10}])
|
||||
(render [amount-input/view {:status :error}])
|
||||
(h/is-equal (colors/resolve-color :danger :light)
|
||||
(oops/oget (h/get-by-label-text :amount-input) "props" "style" "color"))))
|
||||
(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))))
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
(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
|
||||
@@ -7,10 +11,11 @@
|
||||
[:map {:closed true}
|
||||
[:status {:optional true} [:maybe [:enum :default :error]]]
|
||||
[:theme :schema.common/theme]
|
||||
[:on-inc-press {:optional true} [:maybe fn?]]
|
||||
[:on-dec-press {:optional true} [:maybe fn?]]
|
||||
[:on-change-text {: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]]
|
||||
[:value [:maybe :int]]]]]
|
||||
[:return-key-type {:optional true} [:maybe return-key-types]]
|
||||
[:init-value {:optional true} [:maybe :int]]]]]
|
||||
:any])
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
(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,6 +6,7 @@
|
||||
[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
|
||||
@@ -20,35 +21,60 @@
|
||||
: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 [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)}]])
|
||||
[{: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)}]]))))
|
||||
|
||||
(def view
|
||||
(quo.theme/with-theme
|
||||
|
||||
@@ -48,7 +48,6 @@
|
||||
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
|
||||
@@ -129,7 +128,6 @@
|
||||
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
|
||||
@@ -251,7 +249,6 @@
|
||||
|
||||
;;;; 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)
|
||||
@@ -380,7 +377,6 @@
|
||||
(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)
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
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
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
["react" :as react]
|
||||
["react-native" :as react-native]
|
||||
[oops.core :as oops]
|
||||
[promesa.core :as promesa]
|
||||
[promesa.core :as p]
|
||||
[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]
|
||||
(promesa/create (fn [res rej]
|
||||
(.getSize ^js (.-Image ^js react-native)
|
||||
uri
|
||||
(fn [width height] (res [width height]))
|
||||
rej))))
|
||||
(p/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)))
|
||||
|
||||
|
||||
@@ -62,26 +62,23 @@
|
||||
([server username password]
|
||||
(save-credentials server username password identity))
|
||||
([server username password callback]
|
||||
(when-not (empty? server)
|
||||
(-> (.setInternetCredentials ^js react-native-keychain
|
||||
(string/lower-case server)
|
||||
username
|
||||
password
|
||||
keychain-secure-hardware
|
||||
keychain-restricted-availability)
|
||||
(.then callback)))))
|
||||
(-> (.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]
|
||||
(when-not (empty? server)
|
||||
(-> (.getInternetCredentials ^js react-native-keychain (string/lower-case server))
|
||||
(.then callback)))))
|
||||
(-> (.getInternetCredentials ^js react-native-keychain (string/lower-case server))
|
||||
(.then callback))))
|
||||
|
||||
(defn reset-credentials
|
||||
[server]
|
||||
(when-not (empty? server)
|
||||
(-> (.resetInternetCredentials ^js react-native-keychain (string/lower-case server))
|
||||
(.then #(when-not % (log/error (str "Error while clearing saved password.")))))))
|
||||
(-> (.resetInternetCredentials ^js react-native-keychain (string/lower-case server))
|
||||
(.then #(when-not % (log/error (str "Error while clearing saved password."))))))
|
||||
|
||||
@@ -148,26 +148,28 @@
|
||||
(reset! search-text ""))
|
||||
|
||||
(defn f-view
|
||||
[{:keys [search-active? on-change-text clear-states active-category scroll-ref theme]
|
||||
[{:keys [search-text on-change-text clear-states active-category scroll-ref theme]
|
||||
:as sheet-opts}]
|
||||
[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}])]])
|
||||
(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}])]]))
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
@@ -200,7 +202,7 @@
|
||||
(fn [sheet-opts]
|
||||
[:f> f-view
|
||||
(assoc sheet-opts
|
||||
:search-active? (pos? (count @search-text))
|
||||
:search-text 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 scroll-view-ref]}]
|
||||
[{:keys [on-did-show]}]
|
||||
(let [keyboard-will-show? (reagent/atom false)
|
||||
keyboard-did-show? (reagent/atom false)
|
||||
add-listener (fn [listener callback]
|
||||
@@ -41,10 +41,7 @@
|
||||
(reset! keyboard-did-show? true)
|
||||
(when on-did-show (on-did-show e))))
|
||||
will-hide-listener (add-listener "keyboardWillHide"
|
||||
(fn []
|
||||
(reset! keyboard-will-show? false)
|
||||
(reagent/flush)
|
||||
(.scrollTo @scroll-view-ref #js {:x 0 :y 0 :animated true})))
|
||||
#(reset! keyboard-will-show? false))
|
||||
did-hide-listener (add-listener "keyboardDidHide"
|
||||
#(reset! keyboard-did-show? false))
|
||||
remove-listeners (fn []
|
||||
@@ -58,11 +55,9 @@
|
||||
(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 [scroll-view-ref (atom nil)
|
||||
set-scroll-ref #(reset! scroll-view-ref %)
|
||||
window-height (:height (rn/get-window))
|
||||
:or {footer-container-padding (safe-area/get-top)}} &
|
||||
children]
|
||||
(reagent/with-let [window-height (:height (rn/get-window))
|
||||
footer-container-height (reagent/atom 0)
|
||||
header-height (reagent/atom 0)
|
||||
content-container-height (reagent/atom 0)
|
||||
@@ -71,8 +66,7 @@
|
||||
{:keys [keyboard-will-show?
|
||||
keyboard-did-show?
|
||||
remove-listeners]} (init-keyboard-listeners
|
||||
{:scroll-view-ref scroll-view-ref
|
||||
:on-did-show
|
||||
{:on-did-show
|
||||
(fn [e]
|
||||
(reset! keyboard-height
|
||||
(oops/oget e "endCoordinates.height")))})
|
||||
@@ -91,22 +85,16 @@
|
||||
: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
|
||||
{: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}
|
||||
{:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1}}
|
||||
(into [rn/view {:on-layout set-content-container-height}]
|
||||
children)]
|
||||
[rn/keyboard-avoiding-view
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
(ns status-im.common.log
|
||||
(:require
|
||||
[clojure.pprint :as promesa]
|
||||
[clojure.pprint :as p]
|
||||
[clojure.string :as string]
|
||||
[native-module.core :as native-module]
|
||||
[re-frame.core :as re-frame]
|
||||
@@ -43,8 +43,7 @@
|
||||
:middleware [(fn [data]
|
||||
(update data
|
||||
:vargs
|
||||
(partial mapv
|
||||
#(if (string? %) % (with-out-str (promesa/pprint %))))))]})
|
||||
(partial mapv #(if (string? %) % (with-out-str (p/pprint %))))))]})
|
||||
(native-module/init-status-go-logging logging-params)))))
|
||||
|
||||
(re-frame/reg-fx
|
||||
|
||||
@@ -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) :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)]
|
||||
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)]
|
||||
(merge {:db (cond-> db
|
||||
connection-success?
|
||||
(assoc-in [:syncing :pairing-status] :connected)
|
||||
@@ -51,9 +51,8 @@
|
||||
(cond
|
||||
(and navigate-to-syncing-devices? (not user-in-syncing-devices-screen?))
|
||||
{:dispatch (if user-in-sign-in-intro-screen?
|
||||
[:navigate-to-within-stack
|
||||
[:screen/onboarding.syncing-progress-intro :screen/onboarding.sign-in-intro]]
|
||||
[:navigate-to :screen/onboarding.syncing-progress])}
|
||||
[:navigate-to-within-stack [:syncing-progress-intro :sign-in-intro]]
|
||||
[:navigate-to :syncing-progress])}
|
||||
|
||||
(and completed-pairing? sender?)
|
||||
{:dispatch [:syncing/clear-states]}
|
||||
|
||||
@@ -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 :settings nil))
|
||||
(navigation/navigate-to :my-profile nil))
|
||||
|
||||
public-key
|
||||
{:dispatch [:chat.ui/show-profile public-key ens-name]}))
|
||||
|
||||
@@ -169,4 +169,3 @@
|
||||
|
||||
(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,6 +3,7 @@
|
||||
[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]
|
||||
@@ -50,66 +51,57 @@
|
||||
|
||||
(defn- search-input
|
||||
[]
|
||||
(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]]]))
|
||||
(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]))))
|
||||
|
||||
(defn- invalid-text
|
||||
[message]
|
||||
|
||||
@@ -38,8 +38,7 @@
|
||||
(let [cache (get-in db [:chat/link-previews :cache])
|
||||
previews (urls->previews cache urls)
|
||||
new-urls (->> previews
|
||||
(filter (fn [{:keys [loading? status-link-preview?]}]
|
||||
(or loading? status-link-preview?)))
|
||||
(filter :loading?)
|
||||
(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
|
||||
@@ -140,18 +139,14 @@
|
||||
sent."
|
||||
{:events [:link-preview/reset-unfurled]}
|
||||
[{:keys [db]}]
|
||||
{:db (-> db
|
||||
(update :chat/link-previews dissoc :unfurled :request-id :cleared)
|
||||
(update :chat/status-link-previews dissoc :unfurled :request-id :cleared))})
|
||||
{:db (update db :chat/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 (-> db
|
||||
(dissoc :chat/link-previews)
|
||||
(dissoc :chat/status-link-previews))})
|
||||
{:db (dissoc db :chat/link-previews)})
|
||||
|
||||
(rf/defn clear-link-previews
|
||||
"Mark current unfurled URLs as `cleared`, meaning the user won't see previews
|
||||
@@ -161,5 +156,4 @@
|
||||
(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))}))
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
(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})
|
||||
@@ -1,10 +0,0 @@
|
||||
(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)]]))
|
||||
@@ -1,10 +0,0 @@
|
||||
(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,15 +5,17 @@
|
||||
(def ^:private message-padding-scaling-ratio 4.5)
|
||||
|
||||
(defn message-container
|
||||
[{:keys [in-pinned-view? pinned-by mentioned last-in-group? system-message?]}]
|
||||
(cond-> {:border-radius 16
|
||||
:margin-horizontal 8}
|
||||
([]
|
||||
(message-container false nil nil false))
|
||||
([in-pinned-view? pinned-by mentioned last-in-group?]
|
||||
(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?) (not system-message?) (or mentioned pinned-by last-in-group?))
|
||||
(assoc :margin-top 4)))
|
||||
(and (not in-pinned-view?) (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,12 +17,10 @@
|
||||
[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]
|
||||
@@ -152,37 +150,38 @@
|
||||
(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 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])
|
||||
(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])
|
||||
{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
|
||||
@@ -232,14 +231,10 @@
|
||||
[content.text/text-content message-data context]
|
||||
|
||||
constants/content-type-emoji
|
||||
[emoji-message/view
|
||||
{:content content
|
||||
:last-in-group? last-in-group?
|
||||
:pinned pinned
|
||||
:in-pinned-view? (:in-pinned-view? context)}]
|
||||
[not-implemented/not-implemented [old-message/emoji message-data]]
|
||||
|
||||
constants/content-type-sticker
|
||||
[sticker-message/view {:url (-> message-data :content :sticker :url)}]
|
||||
[not-implemented/not-implemented [old-message/sticker message-data]]
|
||||
|
||||
constants/content-type-audio
|
||||
[audio/audio-message message-data context]
|
||||
@@ -292,7 +287,7 @@
|
||||
:show-user-info? false
|
||||
:show-reactions? true}]]))}]))
|
||||
|
||||
(defn check-if-system-message?
|
||||
(defn system-message?
|
||||
[content-type]
|
||||
(#{constants/content-type-system-text
|
||||
constants/content-type-community
|
||||
@@ -305,35 +300,28 @@
|
||||
(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?]
|
||||
(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]
|
||||
[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]
|
||||
|
||||
(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]
|
||||
|
||||
(= 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}])]))
|
||||
:else
|
||||
[user-message-content
|
||||
{:message-data message-data
|
||||
:context context
|
||||
:keyboard-shown? keyboard-shown?
|
||||
:show-reactions? true}])])
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
{: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
|
||||
@@ -20,12 +23,12 @@
|
||||
:height (+ top-margin messages.constants/header-container-radius)}))
|
||||
|
||||
(defn header-bottom-part
|
||||
[bottom theme top-margin]
|
||||
[border-radius theme top-margin]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:bottom bottom}
|
||||
{:border-top-left-radius border-radius
|
||||
:border-top-right-radius border-radius}
|
||||
{:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
|
||||
:padding-horizontal 20
|
||||
:border-radius 20
|
||||
:margin-top top-margin}))
|
||||
|
||||
(defn header-image
|
||||
@@ -39,20 +42,5 @@
|
||||
:border-radius 50
|
||||
:border-color (colors/theme-colors colors/white colors/neutral-95 theme)}))
|
||||
|
||||
(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}))
|
||||
(def bio
|
||||
{:margin-top 8})
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
[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)
|
||||
@@ -64,7 +63,8 @@
|
||||
[{:keys [ens-verified added?]} theme]
|
||||
(when (or ens-verified added?)
|
||||
[rn/view
|
||||
{:style {:margin-left 4}}
|
||||
{:style {:margin-left 4
|
||||
:margin-top 8}}
|
||||
(if ens-verified
|
||||
[quo/icon :i/verified
|
||||
{:no-color true
|
||||
@@ -111,55 +111,27 @@
|
||||
(- 70 (:bottom insets)))]
|
||||
[rn/view {:style {:height height}}]))
|
||||
|
||||
(defn list-footer-avatar
|
||||
[{:keys [distance-from-list-top display-name online? profile-picture theme group-chat color]}]
|
||||
(defn f-list-footer-avatar
|
||||
[{:keys [distance-from-list-top display-name online? profile-picture theme]}]
|
||||
(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]
|
||||
[-44 -12]
|
||||
[-40 -8]
|
||||
messages.constants/default-extrapolation-option)
|
||||
left (reanimated/interpolate distance-from-list-top
|
||||
[0 messages.constants/header-container-top-margin]
|
||||
[16 -8]
|
||||
[20 -4]
|
||||
messages.constants/default-extrapolation-option)]
|
||||
[reanimated/view
|
||||
{:style (style/header-image scale top left theme)}
|
||||
(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]]]))
|
||||
[quo/user-avatar
|
||||
{:full-name display-name
|
||||
:online? online?
|
||||
:profile-picture profile-picture
|
||||
:size :big}]]))
|
||||
|
||||
(defn actions
|
||||
[chat-id cover-bg-color]
|
||||
@@ -170,102 +142,89 @@
|
||||
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
|
||||
{: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?)))}]}]))
|
||||
{: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 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
|
||||
(defn f-list-footer
|
||||
[{:keys [chat distance-from-list-top theme customization-color]}]
|
||||
(let [{:keys [chat-id chat-name emoji chat-type
|
||||
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)]
|
||||
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)]
|
||||
[:<>
|
||||
[reanimated/view
|
||||
{:style (style/background-container background-color background-opacity top-margin)}]
|
||||
[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}]]]))
|
||||
[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]]]))
|
||||
|
||||
(defn list-footer
|
||||
[props]
|
||||
@@ -275,7 +234,7 @@
|
||||
[:<>
|
||||
(if (or loading-messages? (not all-loaded?))
|
||||
[loading-view chat-id props]
|
||||
[footer-component props])]))
|
||||
[:f> f-list-footer props])]))
|
||||
|
||||
(defn list-group-chat-header
|
||||
[{:keys [chat-id invitation-admin]}]
|
||||
@@ -325,7 +284,7 @@
|
||||
(reset! layout-height-atom layout-height))
|
||||
(reset! distance-atom new-distance)))
|
||||
|
||||
(defn messages-list-content
|
||||
(defn f-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)
|
||||
@@ -389,7 +348,6 @@
|
||||
: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,42 +18,37 @@
|
||||
[utils.worklets.chat.messenger.messages :as messages.worklets]
|
||||
[utils.worklets.chat.messenger.navigation :as worklets]))
|
||||
|
||||
(defn header-content-container
|
||||
(defn f-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 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))]
|
||||
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))]
|
||||
[reanimated/view
|
||||
{:style (style/header-content-container header-opacity header-position)}
|
||||
(if group-chat
|
||||
[quo/group-avatar
|
||||
{:customization-color color
|
||||
:size :size-32
|
||||
:picture photo-path
|
||||
:override-theme :dark}]
|
||||
(when-not group-chat
|
||||
[quo/user-avatar
|
||||
{:full-name display-name
|
||||
:online? online?
|
||||
@@ -75,7 +70,7 @@
|
||||
(i18n/label
|
||||
(if online? :t/online :t/offline))])]]))
|
||||
|
||||
(defn animated-background-and-pinned-banner
|
||||
(defn f-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
|
||||
@@ -127,7 +122,7 @@
|
||||
[all-loaded-sub])
|
||||
[rn/view
|
||||
{:style (style/navigation-view navigation-view-height messages.constants/pinned-banner-height)}
|
||||
[animated-background-and-pinned-banner
|
||||
[:f> f-animated-background-and-pinned-banner
|
||||
{:chat-id chat-id
|
||||
:navigation-view-height navigation-view-height
|
||||
:distance-from-list-top distance-from-list-top
|
||||
@@ -142,7 +137,7 @@
|
||||
:accessibility-label :back-button
|
||||
:on-press #(rf/dispatch [:navigate-back])}
|
||||
(if (= chat-type constants/community-chat-type) :i/arrow-left :i/close)]]
|
||||
[header-content-container
|
||||
[:f> f-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- chat-screen
|
||||
(defn- f-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?}]
|
||||
[list.view/messages-list-content
|
||||
[:f> list.view/f-messages-list-content
|
||||
{:insets insets
|
||||
:layout-height layout-height
|
||||
:content-height content-height
|
||||
@@ -46,11 +46,15 @@
|
||||
(when-not screen-loaded?
|
||||
(reanimated/set-shared-value chat-screen-layout-calculations-complete? false))
|
||||
(when screen-loaded?
|
||||
[chat-screen chat-screen-layout-calculations-complete?])))
|
||||
[:f> f-chat-screen chat-screen-layout-calculations-complete?])))
|
||||
|
||||
(defn chat
|
||||
(defn- f-chat
|
||||
[]
|
||||
(let [chat-screen-layout-calculations-complete? (reanimated/use-shared-value false)]
|
||||
[:<>
|
||||
[lazy-chat-screen chat-screen-layout-calculations-complete?]
|
||||
[placeholder.view/view chat-screen-layout-calculations-complete?]]))
|
||||
[:f> placeholder.view/f-view chat-screen-layout-calculations-complete?]]))
|
||||
|
||||
(defn chat
|
||||
[]
|
||||
[:f> f-chat])
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
(ns status-im.contexts.chat.messenger.photo-selector.effects
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[promesa.core :as promesa]
|
||||
[promesa.core :as p]
|
||||
[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]
|
||||
(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))))))]
|
||||
(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))))))]
|
||||
{: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))
|
||||
(promesa/then #(rf/dispatch
|
||||
[:photo-selector/image-selected chat-id image %]))
|
||||
(promesa/catch #(log/error "could not resize image" %)))))
|
||||
(p/then #(rf/dispatch
|
||||
[:photo-selector/image-selected chat-id image %]))
|
||||
(p/catch #(log/error "could not resize image" %)))))
|
||||
|
||||
(defn- get-albums
|
||||
[callback]
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
:parent-height (:height (rn/get-window))
|
||||
:animated? false}])
|
||||
|
||||
(defn view
|
||||
(defn f-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 promesa]
|
||||
[promesa.core :as p]
|
||||
[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]
|
||||
(promesa/create
|
||||
(p/create
|
||||
(fn [p-resolve p-reject]
|
||||
(rpc/call
|
||||
{:method :wakuext_generateJoiningCommunityRequestsForSigning
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
(defn- sign-data
|
||||
[sign-params password]
|
||||
(promesa/create
|
||||
(p/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]
|
||||
(promesa/create
|
||||
(p/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]
|
||||
(promesa/create
|
||||
(p/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]}]
|
||||
(-> (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)]
|
||||
(-> (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)]
|
||||
(run-callback-or-event on-success result))
|
||||
(promesa/catch #(run-callback-or-event on-error %))))
|
||||
(p/catch #(run-callback-or-event on-error %))))
|
||||
|
||||
(schema/=> sign-and-call-endpoint
|
||||
[:=>
|
||||
|
||||
@@ -20,13 +20,6 @@
|
||||
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
|
||||
@@ -115,7 +108,7 @@
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data revealed-accounts}
|
||||
:description-props {:text addresses-shared-text}}
|
||||
:description-props {:text (i18n/label :t/all-addresses)}}
|
||||
{:title (i18n/label :t/for-airdrops)
|
||||
:on-press show-airdrop-addresses
|
||||
:description :text
|
||||
|
||||
@@ -78,14 +78,16 @@
|
||||
;; 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)}
|
||||
{: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]}]]]}))
|
||||
(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]}]]]}))))
|
||||
|
||||
;; This event should be used to check permissions temporarily because it won't
|
||||
;; mutate the state `:communities/permissions-check` (used by many other
|
||||
|
||||
+8
-1
@@ -103,4 +103,11 @@
|
||||
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]))))))
|
||||
(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]))))))
|
||||
|
||||
@@ -195,23 +195,41 @@
|
||||
:button-type :grey
|
||||
:on-button-press open-permission-sheet))])]))
|
||||
|
||||
(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])
|
||||
(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))))))
|
||||
|
||||
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 []
|
||||
@@ -219,6 +237,14 @@
|
||||
{: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?
|
||||
@@ -237,107 +263,7 @@
|
||||
(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]))))
|
||||
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))))))]
|
||||
(rf/dispatch [:communities/set-addresses-to-reveal id addresses-to-reveal]))))]
|
||||
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
@@ -348,6 +274,7 @@
|
||||
(fn []
|
||||
(rf/dispatch [:communities/check-permissions-to-join-during-selection id addresses-to-reveal]))
|
||||
[id addresses-to-reveal])
|
||||
|
||||
[:<>
|
||||
[page-top
|
||||
{:community-id id
|
||||
@@ -361,25 +288,79 @@
|
||||
id
|
||||
color
|
||||
flag-share-all-addresses]
|
||||
: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}}]
|
||||
: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}}]
|
||||
:content-container-style {:padding-horizontal 20}
|
||||
:key-fn :address
|
||||
:data wallet-accounts}]
|
||||
|
||||
[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?}]]))
|
||||
[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))))]]))
|
||||
|
||||
@@ -69,7 +69,6 @@
|
||||
: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 community-keys-renamed
|
||||
(def commmunity-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 community-keys-renamed)]
|
||||
existing-rename (k commmunity-keys-renamed)]
|
||||
(cond starts-with-digit? s
|
||||
existing-rename existing-rename
|
||||
:else (keyword s))))
|
||||
|
||||
@@ -178,16 +178,23 @@
|
||||
: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/request-to-join)]])))
|
||||
(i18n/label :t/join-open-community)]])))
|
||||
|
||||
(defn- join-community
|
||||
[{:keys [id joined permissions] :as community}]
|
||||
[{:keys [id joined permissions can-request-access?] :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-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)])]))
|
||||
|
||||
(defn- status-tag
|
||||
[community-id joined]
|
||||
|
||||
@@ -69,9 +69,9 @@
|
||||
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(reanimated/set-shared-value @paused? (not= view-id :screen/onboarding.intro))
|
||||
(reanimated/set-shared-value @paused? (not= view-id :intro))
|
||||
(fn []
|
||||
(when (= view-id :screen/onboarding.generating-keys)
|
||||
(when (= view-id :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 display-name
|
||||
:title-input-props {:default-value @full-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? (= :screen/onboarding.syncing-results @state/root-id)]
|
||||
syncing-results? (= :syncing-results @state/root-id)]
|
||||
[rn/view {:style (style/buttons insets)}
|
||||
[quo/button
|
||||
{:size 40
|
||||
@@ -43,8 +43,7 @@
|
||||
:type :grey
|
||||
:on-press #(rf/dispatch (if syncing-results?
|
||||
[:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications
|
||||
:screen/onboarding.enable-biometrics]]
|
||||
[:enable-notifications :enable-biometrics]]
|
||||
[:onboarding/create-account-and-login]))
|
||||
:container-style {:margin-top 12}}
|
||||
(i18n/label :t/maybe-later)]]))
|
||||
|
||||
@@ -36,8 +36,7 @@
|
||||
:on-denied #(log/error "user denied push notification permissions")}])
|
||||
(rf/dispatch [:push-notifications/switch true platform/ios?])
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.welcome
|
||||
:screen/onboarding.enable-notifications]]))
|
||||
[:welcome :enable-notifications]]))
|
||||
:type :primary
|
||||
:icon-left :i/notifications
|
||||
:accessibility-label :enable-notifications-button
|
||||
@@ -47,8 +46,7 @@
|
||||
{:on-press (fn []
|
||||
(shell.utils/change-selected-stack-id :communities-stack true nil)
|
||||
(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.welcome
|
||||
:screen/onboarding.enable-notifications]]))
|
||||
[:welcome :enable-notifications]]))
|
||||
:accessibility-label :enable-notifications-later-button
|
||||
:type :grey
|
||||
:background :blur
|
||||
|
||||
@@ -27,8 +27,7 @@
|
||||
{:events [:onboarding/profile-data-set]}
|
||||
[{:keys [db]} onboarding-data]
|
||||
{:db (update db :onboarding/profile merge onboarding-data)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.create-profile-password :screen/onboarding.new-to-status]]})
|
||||
:dispatch [:navigate-to-within-stack [:create-profile-password :new-to-status]]})
|
||||
|
||||
(rf/defn enable-biometrics
|
||||
{:events [:onboarding/enable-biometrics]}
|
||||
@@ -43,8 +42,7 @@
|
||||
[{:keys [db]}]
|
||||
(let [key-uid (get-in db [:profile/profile :key-uid])]
|
||||
{:db (dissoc db :onboarding/profile)
|
||||
:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications :screen/onboarding.enable-biometrics]]}))
|
||||
:dispatch [:navigate-to-within-stack [:enable-notifications :enable-biometrics]]}))
|
||||
|
||||
(rf/defn biometrics-done
|
||||
{:events [:onboarding/biometrics-done]}
|
||||
@@ -66,8 +64,7 @@
|
||||
(let [{:keys [display-name seed-phrase password image-path color] :as profile}
|
||||
(:onboarding/profile db)]
|
||||
(rf/merge cofx
|
||||
{:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.generating-keys :screen/onboarding.new-to-status]]
|
||||
{:dispatch [:navigate-to-within-stack [:generating-keys :new-to-status]]
|
||||
:dispatch-later [{:ms constants/onboarding-generating-keys-animation-duration-ms
|
||||
:dispatch [:onboarding/navigate-to-identifiers]}]
|
||||
:db (-> db
|
||||
@@ -85,7 +82,7 @@
|
||||
(merge
|
||||
{:db (assoc db :profile/profiles-overview multiaccounts)}
|
||||
(when-not (seq multiaccounts)
|
||||
{:set-root :screen/onboarding.intro}))))
|
||||
{:set-root :intro}))))
|
||||
|
||||
(rf/defn password-set
|
||||
{:events [:onboarding/password-set]}
|
||||
@@ -95,8 +92,7 @@
|
||||
(assoc-in [:onboarding/profile :password] password)
|
||||
(assoc-in [:onboarding/profile :auth-method] constants/auth-method-password))
|
||||
:dispatch (if supported-type
|
||||
[:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-biometrics :screen/onboarding.new-to-status]]
|
||||
[:navigate-to-within-stack [:enable-biometrics :new-to-status]]
|
||||
[:onboarding/create-account-and-login])}))
|
||||
|
||||
(rf/defn navigate-to-enable-biometrics
|
||||
@@ -104,8 +100,8 @@
|
||||
[{:keys [db]}]
|
||||
(let [supported-type (get-in db [:biometrics :supported-type])]
|
||||
{:dispatch (if supported-type
|
||||
[:open-modal :screen/onboarding.enable-biometrics]
|
||||
[:open-modal :screen/onboarding.enable-notifications])}))
|
||||
[:open-modal :enable-biometrics]
|
||||
[:open-modal :enable-notifications])}))
|
||||
|
||||
(rf/defn seed-phrase-entered
|
||||
{:events [:onboarding/seed-phrase-entered]}
|
||||
@@ -125,21 +121,19 @@
|
||||
:content (i18n/label :t/multiaccount-exists-content)
|
||||
:confirm-button-text (i18n/label :t/unlock)
|
||||
:on-accept (fn []
|
||||
(re-frame/dispatch [:pop-to-root :screen/profile.profiles])
|
||||
(re-frame/dispatch [:pop-to-root :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
|
||||
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]}))
|
||||
:dispatch [:navigate-to-within-stack [:create-profile :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
|
||||
[:screen/onboarding.create-profile :screen/onboarding.new-to-status]]})
|
||||
:dispatch [:navigate-to-within-stack [:create-profile :new-to-status]]})
|
||||
|
||||
(rf/reg-event-fx :onboarding/set-auth-method
|
||||
(fn [{:keys [db]} [auth-method]]
|
||||
@@ -173,7 +167,6 @@
|
||||
{:events [:onboarding/navigate-to-identifiers]}
|
||||
[{:keys [db]}]
|
||||
(if (:onboarding/generated-keys? db)
|
||||
{:dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.identifiers :screen/onboarding.new-to-status]]}
|
||||
{:dispatch [:navigate-to-within-stack [:identifiers :new-to-status]]}
|
||||
{:dispatch-later [{:ms constants/onboarding-generating-keys-navigation-retry-ms
|
||||
:dispatch [:onboarding/navigate-to-identifiers]}]}))
|
||||
|
||||
@@ -63,8 +63,7 @@
|
||||
:type :grey
|
||||
:background :blur
|
||||
:on-press #(rf/dispatch [:navigate-to-within-stack
|
||||
[:screen/onboarding.enable-notifications
|
||||
:screen/onboarding.new-to-status]])
|
||||
[:enable-notifications :new-to-status]])
|
||||
:container-style style/button}
|
||||
(i18n/label :t/continue)]]]]))
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user