Compare commits

...
Author SHA1 Message Date
Omar Basem 6221b42f2a fix: android bottom padding 2023-05-16 10:44:03 +04:00
Churikova Tetiana 7ef466078a e2e: image test 2023-05-15 19:08:03 +02:00
Jamie Caprani 4b2d62ee1f chore: update ui for syncing page for onboarding and in profile (#15623) 2023-05-15 10:07:13 -07:00
flexsurfer 05073e7453 fix onboarding transition background color (#15900) 2023-05-15 16:28:08 +02:00
frank fa11c232cc update status-go-version.json (#15894) 2023-05-15 20:41:26 +08:00
Brian Sztamfater 3038ceeb82 fix: audio issue when sending app to background on Android and other fixes
Signed-off-by: Brian Sztamfater <brian@status.im>
2023-05-15 09:19:06 -03:00
frank d2e38772b9 use debounce-and-dispatch to improve mention performance (#15887)
* use debounce-and-dispatch to improve mention performance

* increase time to 400ms

* decrease time to 300ms

* update status-go-version.json

* update status-go-version.json
2023-05-15 15:51:29 +08:00
Churikova Tetiana 409c0a9e60 e2e: small fixes 2023-05-12 14:25:32 +02:00
erikseppanen 4b98f0e8de Add 'How to scan' syncing screens (#15710) 2023-05-11 20:58:57 -04:00
Omar Basem 264b7ffab9 Fix mentions animation when disappearing (#15879)
* fix: suggestions list animation
2023-05-11 22:33:25 +04:00
Alexander c71224e73e Double-tap for communities & fix for 'Recent' tab not being shown as selected if message icon is double tapped (#15844)
* Updates

* Small namespace fix
2023-05-11 18:17:50 +02:00
Parvesh Monu 3c278ed06c fix window height sub leak (#15878) 2023-05-11 19:57:37 +05:30
Jamie Caprani d714dc1590 chore: restore label on im new to status page (#15876) 2023-05-11 07:09:03 -07:00
Ajay Sivan d2840885dd fix: app locked screen accent color (#15854) 2023-05-11 05:31:41 -07:00
Omar Basem 87247af86b Composer polishing (#15875)
* composer polishing
2023-05-11 15:35:42 +04:00
Mohamed Javid 159ad02e7a [Fix] Tapable area of user avatar in chat (#15840) 2023-05-11 14:33:35 +05:30
Alexander ce322c9537 Remove identicons, replace them with initials of a user (#15815)
* Remove identicon, replace it with initials of a user

* Lint fix
2023-05-11 10:05:20 +02:00
Omar Basem 13a1ee7479 Fix composer max height on some Android devices (#15871)
* fix: android keyboard height
2023-05-11 11:41:53 +04:00
yqrashawn c1f24fb1bb feat: doc info boxes while onboarding (#15697) 2023-05-11 10:00:36 +08:00
Parvesh Monu 4afe251086 Show correct error message while unlocking app (#15845) 2023-05-11 02:29:52 +05:30
jakub ac3eb3e660 nix: use SRI hashes for Gradle dependencies
This way we will use the same format as Nix logs and errors when a hash
changes, which avoids confusion.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-05-10 15:45:32 +02:00
Omar Basem 638ec98db5 fix: maximized composer incorrect bottom padding (#15865)
* fix: maximized composer incorrect bottom padding
2023-05-10 17:36:44 +04:00
jakub 78131c1028 ci: add Alchemy and Infura credentials in CI
Depends on: https://github.com/status-im/status-jenkins-lib/pull/64

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-05-10 12:57:04 +02:00
Volodymyr Kozieiev 5655efa448 Separate doc with debug tips (#15849)
Debugging basics
2023-05-10 10:38:59 +01:00
jakub c008c01bc1 ci: bump timeout for tests to 15 minutes
We've been seing longer runs on release CI for nightlies, possibly due
to more than 2 parallel builds running on one host.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2023-05-10 11:06:10 +02:00
Omar Basem 7e1af5b80d Composer polishing (#15857)
* refactor: composer
2023-05-10 12:17:24 +04:00
Ulises Manuel Cárdenas ee4bcf9116 Recovery phrase onboarding (#15831)
* Add missing tests for recovery phrase input
2023-05-09 21:55:09 -06:00
Ajay Sivan 1aff364595 fix: android blur view hash mismatch in some locations 2023-05-09 21:36:12 +02:00
Alexander 929ec6a453 'Unpin' option in 1-1 chat for deleted message (#15833) 2023-05-09 19:27:10 +02:00
Omar Basem 341497e98d feat: new composer complete 🎉 (#15818)
* feat: new composer
2023-05-09 21:03:19 +04:00
frank c275205bed Adapt to status-go backend changes for ConvertToKeycardAccount (#15846) 2023-05-09 20:51:08 +08:00
185 changed files with 4168 additions and 4817 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
pipeline {
agent { label params.AGENT_LABEL }
+2 -2
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
/* Options section can't access functions in objects. */
def isPRBuild = utils.isPRBuild()
@@ -9,7 +9,7 @@ pipeline {
options {
timestamps()
/* Prevent Jenkins jobs from running forever */
timeout(time: 10, unit: 'MINUTES')
timeout(time: 15, unit: 'MINUTES')
/* Limit builds retained */
buildDiscarder(logRotator(
numToKeepStr: '10',
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
pipeline {
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
pipeline {
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
pipeline {
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
pipeline {
agent { label 'linux' }
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-jenkins-lib@v1.7.2'
library 'status-jenkins-lib@v1.7.3'
pipeline {
agent {
+1
View File
@@ -18,6 +18,7 @@
[Working on PR together with QA team](pipeline_process.md)
[Debugging](debugging.md)
## Testing
-19
View File
@@ -91,30 +91,11 @@ These guidelines make db.cljs namespaces the place to go when making changes to
- If manual QA is not needed but all tests don't pass, you can ping @churik or @Serhy to confirm that failed E2E tests are not unrelated.
## Enabling debug logs
Calls to `log/debug` will not be printed to the console by default. It can be enabled under "Advanced settings" in the app:
![Enable Debug Logs](images/codebase-structure-and-guidelines/log-settings.png)
## Translations
The app relies on system locale to select a language from the [list of supported languages](https://github.com/status-im/status-mobile/blob/bda73867471cf2bb8a68b1cc27c9f94b92d9a58b/src/status_im/i18n_resources.cljs#L9). It falls back to English in cash the system locale is not supported.
We use Lokalise App to manage [translations](https://translate.status.im/). In case you need to add/remove a key to translations, you only need to change `en.json`. Missing keys fallback to `en.json`. The actual translations will be added by Lokalise.
## re-frisk
re-frisk is a state visualization tool written by our very own Andrey (@flexsurfer). To start re-frisk, execute the following command:
```bash
$ yarn shadow-cljs run re-frisk-remote.core/start
```
or you can also use make:
```bash
$ make run-re-frisk
```
A server will be started at http://localhost:4567. It might show "not connected" at first. Don't worry and just start using the app. The events and state will populate.
## Merging approved PRs
We don't Github's UI to merge. Instead `./scripts/merge-pr.sh` is used to sign and merge PR to `develop`. You first need to enable [GPG signing on you commits](https://github.com/status-im/status-mobile/blob/develop/STARTING_GUIDE.md#configure-gpg-keys-for-signing-commits).
+64
View File
@@ -0,0 +1,64 @@
# Debugging
## Inspecting re-frame with re-frisk
`re-frisk` is a state visualization tool written by our very own Andrey (@flexsurfer). With its help you can inspect the current state of app-db, watch event, etc.
![re-frisk](images/debugging/re-frisk.png)
To start `re-frisk`, execute the following command:
```bash
$ yarn shadow-cljs run re-frisk-remote.core/start
```
or you can also use make:
```bash
$ make run-re-frisk
```
A server will be started at http://localhost:4567. It might show "not connected" at first. Don't worry and just start using the app. The events and state will populate.
More details about re-frisk are on the [project page](https://github.com/flexsurfer/re-frisk).
## Enabling debug logs
Calls to `log/debug` will not be printed to the console by default. It can be enabled under "Advanced settings" in the app:
![Enable Debug Logs](images/debugging/log-settings.png)
## Checking status-go logs
While status mobile works it saves logs from `status-go` to `geth.log` file.
### Checking logs from physical device
To obtain `geth.log` from physical device you need to shake it and in an opened menu select "Share logs".
![Share logs](images/debugging/share-logs.jpeg)
### Checking logs from iOS Simulator
When developing with iOS simulator it is more convenient to see the `geth.log` updates in real-time.
To do this:
- open Activity Monitor
- find the "StatusIm" app and doubleclick it
- in the opened window select "Open files and ports" and find the full path to `geth.log` (note that it won't appear until you login to Status app)
![geth.log path](images/debugging/geth-path.png)
## Tips
### From @ilmotta:
Something I find extremely convenient for Android is to use `adb` to tail logs. I don't use macOS so I don't know if the iOS simulator offers a CLI interface with the same capabilities.
But here's what I use for example:
```
adb shell tail -n 10 -f /storage/emulated/0/Android/data/im.status.ethereum.debug/files/Download/geth.log | grep 'waku.relay'
```
Also to inspect logs in a more flexible manner, instead of the strict output from `make run-metro`, I prefer `adb logcat`. Combined with enabling status-mobile logs in debug by default plus filtering the logs to only what I care during development, I find this helps me inspect the app without running re-frisk because with the debug log level I can already see which events are dispatched (one of the features I like the most from re-frisk).
```
adb logcat | grep 'ReactNativeJS\|StatusModule\|GoLog'
```
Binary file not shown.

After

Width:  |  Height:  |  Size: 255 KiB

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

+2 -2
View File
@@ -234,7 +234,7 @@ PODS:
- React
- react-native-blob-util (0.13.18):
- React-Core
- react-native-blur (4.3.2):
- react-native-blur (4.3.3):
- React-Core
- react-native-camera-kit (8.0.4):
- React
@@ -706,7 +706,7 @@ SPEC CHECKSUMS:
React-logger: 85f4ef06b9723714b2dfa5b0e5502b673b271b58
react-native-background-timer: 1f7d560647b40e6a60b01c452ba29c54bf581fc4
react-native-blob-util: 600972b1782380a5a7d5db61a3817ea32349dae9
react-native-blur: 4db8c7556566df4e8714c1af5762a4ebc99175d5
react-native-blur: c6d0a1dc2b4b519f7afe3b14d8151998632b6d18
react-native-camera-kit: 498a6d111a904834e0824e9073cfadef7303235f
react-native-cameraroll: 88f4e62d9ecd0e1f253abe4f685474f2ea14bfa2
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
@@ -1354,11 +1354,12 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void convertToKeycardAccount(final String keyUID, final String accountData, final String options, final String password, final String newPassword, final Callback callback) throws JSONException {
public void convertToKeycardAccount(final String keyUID, final String accountData, final String options, final String keycardUID, final String password,
final String newPassword, final Callback callback) throws JSONException {
final String keyStoreDir = this.getKeyStorePath(keyUID);
executeRunnableStatusGoMethod(() -> {
Statusgo.initKeystore(keyStoreDir);
return Statusgo.convertToKeycardAccount(accountData, options, password, newPassword);
return Statusgo.convertToKeycardAccount(accountData, options, keycardUID, password, newPassword);
}, callback);
}
@@ -692,6 +692,7 @@ RCT_EXPORT_METHOD(reEncryptDbAndKeystore:(NSString *)keyUID
RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
accountData:(NSString *)accountData
settings:(NSString *)settings
keycardUID:(NSString *)keycardUID
currentPassword:(NSString *)currentPassword
newPassword:(NSString *)newPassword
callback:(RCTResponseSenderBlock)callback) {
@@ -700,7 +701,7 @@ RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
#endif
NSURL *multiaccountKeystoreDir = [self getKeyStoreDir:keyUID];
StatusgoInitKeystore(multiaccountKeystoreDir.path);
NSString *result = StatusgoConvertToKeycardAccount(accountData, settings, currentPassword, newPassword);
NSString *result = StatusgoConvertToKeycardAccount(accountData, settings, keycardUID, currentPassword, newPassword);
callback(@[result]);
}
+1651 -1651
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -367,7 +367,7 @@ com.facebook.soloader:annotation:0.10.1
com.facebook.soloader:nativeloader:0.10.1
com.facebook.soloader:soloader:0.10.1
com.facebook.yoga:proguard-annotations:1.19.0
com.github.Dimezis:BlurView:version-2.0.2
com.github.Dimezis:BlurView:version-2.0.3
com.github.bumptech.glide:annotations:4.12.0
com.github.bumptech.glide:compiler:4.12.0
com.github.bumptech.glide:disklrucache:4.12.0
+3 -3
View File
@@ -310,7 +310,7 @@ https://dl.google.com/dl/android/maven2/com/android/zipflinger/4.1.0/zipflinger-
https://dl.google.com/dl/android/maven2/com/google/android/material/material/1.0.0/material-1.0.0.pom
https://dl.google.com/dl/android/maven2/com/google/android/material/material/1.2.0-alpha03/material-1.2.0-alpha03.pom
https://dl.google.com/dl/android/maven2/com/google/test/platform/core-proto/0.0.2-dev/core-proto-0.0.2-dev.pom
https://jitpack.io/com/github/Dimezis/BlurView/version-2.0.2/BlurView-version-2.0.2.pom
https://jitpack.io/com/github/Dimezis/BlurView/version-2.0.3/BlurView-version-2.0.3.pom
https://jitpack.io/com/github/status-im/function/0.0.1/function-0.0.1.pom
https://jitpack.io/com/github/status-im/status-keycard-java/android/3.1.1/android-3.1.1.pom
https://jitpack.io/com/github/status-im/status-keycard-java/lib/3.1.1/lib-3.1.1.pom
@@ -475,12 +475,12 @@ https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotatio
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.2.0/error_prone_annotations-2.2.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.3.1/error_prone_annotations-2.3.1.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.3.2/error_prone_annotations-2.3.2.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.18.0/error_prone_annotations-2.18.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_annotations/2.19.0/error_prone_annotations-2.19.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.0.18/error_prone_parent-2.0.18.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.2.0/error_prone_parent-2.2.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.3.1/error_prone_parent-2.3.1.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.3.2/error_prone_parent-2.3.2.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.18.0/error_prone_parent-2.18.0.pom
https://repo.maven.apache.org/maven2/com/google/errorprone/error_prone_parent/2.19.0/error_prone_parent-2.19.0.pom
https://repo.maven.apache.org/maven2/com/google/flatbuffers/flatbuffers-java/1.12.0/flatbuffers-java-1.12.0.pom
https://repo.maven.apache.org/maven2/com/google/google/1/google-1.pom
https://repo.maven.apache.org/maven2/com/google/guava/failureaccess/1.0.1/failureaccess-1.0.1.pom
+6 -6
View File
@@ -14,12 +14,12 @@ declare -a REPOS=(
"https://jitpack.io"
)
function nix_fetch() {
nix-prefetch-url --print-path --type sha256 "${1}" 2>/dev/null
function nix_prefetch() {
nix store prefetch-file --json "${1}" 2>/dev/null
}
function get_nix_path() { echo "${1}" | tail -n1; }
function get_nix_sha() { echo "${1}" | head -n1; }
function get_nix_path() { echo "${1}" | jq -r .storePath; }
function get_nix_sha() { echo "${1}" | jq -r .hash; }
function get_sha1() { sha1sum "${1}" | cut -d' ' -f1; }
# Assumes REPOS from repos.sh is available
@@ -44,7 +44,7 @@ function fetch_and_template_file() {
local OBJ_URL OBJ_NIX_FETCH_OUT OBJ_NAME OBJ_PATH
OBJ_URL="${REPO_URL}/${PKG_PATH}/${FILENAME}"
if ! OBJ_NIX_FETCH_OUT=$(nix_fetch "${OBJ_URL}"); then
if ! OBJ_NIX_FETCH_OUT=$(nix_prefetch "${OBJ_URL}"); then
echo " ! Failed to fetch: ${OBJ_URL}" >&2
return 1
fi
@@ -85,7 +85,7 @@ PKG_PATH="${PKG_URL_NO_EXT#"${REPO_URL}/"}"
PKG_PATH="$(dirname "${PKG_PATH}")"
# Both JARs and AARs have a POM
POM_NIX_FETCH_OUT=$(nix_fetch "${PKG_URL_NO_EXT}.pom")
POM_NIX_FETCH_OUT=$(nix_prefetch "${PKG_URL_NO_EXT}.pom")
POM_PATH=$(get_nix_path "${POM_NIX_FETCH_OUT}")
POM_NAME=$(basename "${PKG_URL_NO_EXT}.pom")
if [[ -z "${POM_PATH}" ]]; then
+1 -1
View File
@@ -16,7 +16,7 @@
"@babel/preset-typescript": "^7.17.12",
"@react-native-async-storage/async-storage": "^1.17.9",
"@react-native-community/audio-toolkit": "git+https://github.com/tbenr/react-native-audio-toolkit.git#refs/tags/v2.0.3-status-v6",
"@react-native-community/blur": "git+https://github.com/status-im/react-native-blur#refs/tags/v4.3.2-status",
"@react-native-community/blur": "git+https://github.com/status-im/react-native-blur#refs/tags/v4.3.3-status",
"@react-native-community/cameraroll": "git+https://github.com/status-im/react-native-cameraroll.git#refs/tags/v4.0.4-status.0",
"@react-native-community/clipboard": "^1.2.2",
"@react-native-community/hooks": "^2.5.1",
Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 552 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 288 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 KiB

+15 -2
View File
@@ -39,9 +39,22 @@ chmod 644 ${SECRETS_FILE_PATH}
# If secrets file was created we want to remove it.
trap "rm -vf ${SECRETS_FILE_PATH}" EXIT ERR INT QUIT
# Names of variables containing secrets to save in env file.
SECRETS_ENV_VARS=(
'ALCHEMY_ARBITRUM_GOERLI_TOKEN'
'ALCHEMY_ARBITRUM_MAINNET_TOKEN'
'ALCHEMY_OPTIMISM_GOERLI_TOKEN'
'ALCHEMY_OPTIMISM_MAINNET_TOKEN'
'INFURA_TOKEN'
'INFURA_TOKEN_SECRET'
'OPENSEA_API_KEY'
'POKT_TOKEN'
)
# Secrets like this can't be passed via args or they end up in derivation.
if [[ -n "${POKT_TOKEN}" ]]; then append_env_export 'POKT_TOKEN'; fi
if [[ -n "${OPENSEA_API_KEY}" ]]; then append_env_export 'OPENSEA_API_KEY'; fi
for SECRET_VAR_NAME in "${SECRETS_ENV_VARS[@]}"; do
[[ -n "${!SECRET_VAR_NAME}" ]] && append_env_export "${SECRET_VAR_NAME}"
done
# If no secrets were passed there's no need to pass the 'secretsFile'.
if [[ -s "${SECRETS_FILE_PATH}" ]]; then
+1
View File
@@ -513,6 +513,7 @@
key-uid
(types/clj->json multiaccount-data)
(types/clj->json settings)
""
current-password#
new-password
callback))
-10
View File
@@ -1,10 +0,0 @@
(ns native-module.core-test
(:require [cljs.test :refer [deftest is testing]]
[native-module.core :as native-module]))
(deftest identicon-test
(testing "check if identicon test works"
(is
(=
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAjklEQVR4nOzXsQmAMBQGYRV3cUAdQwd0Gm2sJIWSBI6f+0oR8XjwSKYhhCE0htAYQmMITUzI/PXF49yv0vN12cYWP1L7/ZiJGEJjCE31xvm7bXptv5iJGEJjCE31WasVz1oPQ2gMoWlyuyvpfaN8i5mIITSG0BhCYwiNIeokZiKG0BhCYwiNITR3AAAA//+A3RtWaKqXgQAAAABJRU5ErkJggg=="
(native-module/identicon "a")))))
+1 -1
View File
@@ -11,7 +11,7 @@
(defn neutral-border-color
[in-blur-view? override-theme]
(if in-blur-view?
(colors/theme-colors colors/white-opa-10 colors/neutral-80-opa-5 override-theme)
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-10 override-theme)
(colors/theme-colors colors/neutral-20 colors/neutral-80 override-theme)))
(def active-background-color (colors/custom-color :blue 50 10))
@@ -1,8 +1,59 @@
(ns quo2.components.inputs.recovery-phrase.component-spec
(:require [quo2.components.inputs.recovery-phrase.view :as recovery-phrase]
(:require [clojure.string :as string]
[oops.core :as oops]
[quo2.components.inputs.recovery-phrase.view :as recovery-phrase]
[test-helpers.component :as h]))
(h/describe "Recovery phrase input"
(h/test "Default render"
(h/render [recovery-phrase/recovery-phrase-input {}])
(h/is-truthy (h/get-by-label-text :recovery-phrase-input))))
(h/is-truthy (h/get-by-label-text :recovery-phrase-input)))
(h/test "Renders specified text"
(let [text-expected "My custom text"]
(h/render [recovery-phrase/recovery-phrase-input {} text-expected])
(h/is-equal (oops/oget (h/get-by-label-text :recovery-phrase-input) "props" "children")
text-expected)))
(h/test "Text changes and dispatches on-change-text"
(let [new-text "New text"
on-change-mock (h/mock-fn)
get-new-text #(-> % (oops/oget "props" "onChangeText" "mock" "calls") (aget 0 0))]
(h/render [recovery-phrase/recovery-phrase-input {:on-change-text on-change-mock}
"Old text"])
(h/fire-event :change-text (h/get-by-label-text :recovery-phrase-input) new-text)
(h/is-equal (get-new-text (h/get-by-label-text :recovery-phrase-input)) new-text)
(h/was-called on-change-mock)))
(h/describe "Error text"
(h/test "Marked when words doesn't satisfy a predicate"
(h/render [recovery-phrase/recovery-phrase-input
{:mark-errors? true
:error-pred #(>= (count %) 5)}
"Text with some error words that don't satisfy the predicate"])
(let [children-text-nodes (-> (h/get-by-label-text :recovery-phrase-input)
(oops/oget "props" "children" "props" "children")
(js->clj :keywordize-keys true))
{:keys [ok-words error-words]} (group-by #(if (string? %) :ok-words :error-words)
children-text-nodes)]
(h/is-equal (apply str ok-words) "Text with some that the ")
(h/is-truthy (= (map #(-> % :props :argv second) error-words)
["error" "words" "don't" "satisfy" "predicate"]))))
(h/test "Marked when words exceed the limit given"
(h/render [recovery-phrase/recovery-phrase-input
{:mark-errors? true
:word-limit 4}
"these are ok words, these words exceed the limit"])
(let [children-text-nodes (-> (h/get-by-label-text :recovery-phrase-input)
(oops/oget "props" "children" "props" "children")
(js->clj :keywordize-keys true))
{:keys [ok-words error-words]} (group-by #(if (string? %) :ok-words :error-words)
children-text-nodes)]
(h/is-equal (string/trim (apply str ok-words))
"these are ok words,")
(h/is-equal (->> error-words
(map #(-> % :props :argv second))
(interpose " ")
(apply str))
"these words exceed the limit")))))
@@ -31,7 +31,8 @@
set-default #(reset! state :default)]
(fn [{:keys [customization-color override-theme blur? on-focus on-blur mark-errors?
error-pred word-limit]
:or {customization-color :blue}
:or {customization-color :blue
error-pred (constantly false)}
:as props}
text]
(let [extra-props (apply dissoc props custom-props)]
@@ -173,6 +173,7 @@
reached-max-duration? (atom false)
touch-timestamp (atom nil)
disabled? (atom false)
app-state-listener (atom nil)
rec-options
(merge
audio/default-recorder-options
@@ -512,7 +513,13 @@
(on-init reset-recorder))
(when audio-file
(let [filename (last (string/split audio-file "/"))]
(reload-player filename)))))
(reload-player filename)))
(reset! app-state-listener
(.addEventListener rn/app-state
"change"
#(when (= % "background")
(reset! playing-audio? false))))
#(.remove @app-state-listener)))
[rn/view
{:style style/bar-container
:pointer-events :box-none}
@@ -12,12 +12,6 @@
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-5 override-theme)
(colors/theme-colors colors/neutral-10 colors/neutral-90 override-theme))})
(def context-tag-image
{:width 20
:border-radius 10
:background-color :white
:height 20})
(defn context-tag-icon-color
[blur?]
(if blur?
@@ -1,5 +1,6 @@
(ns quo2.components.tags.context-tag.view
(:require [quo2.components.avatars.group-avatar :as group-avatar]
(:require [quo2.components.avatars.user-avatar.view :as user-avatar]
[quo2.components.avatars.group-avatar :as group-avatar]
[quo2.components.icon :as icons]
[quo2.components.markdown.text :as text]
[quo2.components.tags.context-tag.style :as style]
@@ -43,9 +44,11 @@
:size :paragraph-2
:style (assoc text-style :justify-content :center)}]
[base-tag (assoc-in params [:style :padding-left] 3)
[rn/image
{:style style/context-tag-image
:source photo}]
[user-avatar/user-avatar
{:full-name name
:profile-picture photo
:size :xxs
:status-indicator? false}]
[rn/view {:style style/context-tag-text-container}
[text/text text-params (str " " name)]
(when channel-name
@@ -58,7 +61,7 @@
(defn user-avatar-tag
[params username photo]
[context-tag params {:uri photo} username])
[context-tag params photo username])
(defn audio-tag
[duration params]
+5
View File
@@ -130,6 +130,11 @@
(when (and player (.-canPlay ^js player))
(.-currentTime ^js player)))
(defn set-player-wake-lock
[player wake-lock?]
(when player
(set! (.-wakeLock player) wake-lock?)))
(defn toggle-playpause-player
[player on-play on-pause on-error]
(when (and player (.-canPlay ^js player))
+5 -2
View File
@@ -130,6 +130,9 @@
(when (exists? (.-NativeModules ^js react-native))
(.-RNSelectableTextInputManager ^js (.-NativeModules ^js react-native))))
;; TODO: iOS native implementation https://github.com/status-im/status-mobile/issues/14137
(defonce selectable-text-input
(reagent/adapt-react-class
(.requireNativeComponent ^js react-native "RNSelectableTextInput")))
(if platform/android?
(reagent/adapt-react-class
(.requireNativeComponent ^js react-native "RNSelectableTextInput"))
view))
+15 -17
View File
@@ -6,7 +6,6 @@
[status-im.chat.models.mentions :as mentions]
[status-im.chat.models.message :as chat.message]
[status-im.chat.models.message-content :as message-content]
[status-im2.config :as config]
[status-im2.constants :as constants]
[utils.re-frame :as rf]
[utils.i18n :as i18n]
@@ -35,9 +34,12 @@
"Set input text for current-chat. Takes db and input text and cofx
as arguments and returns new fx. Always clear all validation messages."
{:events [:chat.ui/set-chat-input-text]}
[{db :db} new-input chat-id]
[{:keys [db] :as cofx} new-input chat-id]
(let [current-chat-id (or chat-id (:current-chat-id db))]
{:db (assoc-in db [:chat/inputs current-chat-id :input-text] (text->emoji new-input))}))
(rf/merge cofx
{:db (assoc-in db [:chat/inputs current-chat-id :input-text] (text->emoji new-input))}
(when (empty? new-input)
(mentions/clear-mentions)))))
(rf/defn set-input-content-height
{:events [:chat.ui/set-input-content-height]}
@@ -68,13 +70,12 @@
[{:keys [db] :as cofx} text-input-ref {:keys [primary-name searched-text match public-key] :as user}]
(let [chat-id (:current-chat-id db)
text (get-in db [:chat/inputs chat-id :input-text])
method "wakuext_chatMentionNewInputTextWithMention"
params [chat-id text primary-name]]
method "wakuext_chatMentionSelectMention"
params [chat-id text primary-name public-key]]
{:json-rpc/call [{:method method
:params params
:on-success #(rf/dispatch [:mention/on-new-input-text-with-mentions-success %
primary-name text-input-ref match searched-text
public-key])
:on-success #(rf/dispatch [:mention/on-select-mention-success %
primary-name match searched-text public-key])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
@@ -111,8 +112,7 @@
(update-in [:chat/inputs current-chat-id :metadata]
dissoc
:sending-image))
:dispatch (when-not config/new-composer-enabled?
[:mention/to-input-field text current-chat-id])}))
:dispatch [:mention/to-input-field text current-chat-id]}))
(rf/defn show-contact-request-input
"Sets reference to previous chat message and focuses on input"
@@ -184,8 +184,6 @@
[{:keys [db] :as cofx}]
(let [current-chat-id (:current-chat-id db)]
(rf/merge cofx
(when-not config/new-composer-enabled?
{:set-text-input-value [current-chat-id ""]})
(clean-input current-chat-id)
(mentions/clear-mentions))))
@@ -251,21 +249,21 @@
[{{:keys [current-chat-id] :as db} :db :as cofx}]
(let [{:keys [input-text metadata]} (get-in db [:chat/inputs current-chat-id])
editing-message (:editing-message metadata)
method "wakuext_chatMentionCheckMentions"
method "wakuext_chatMentionReplaceWithPublicKey"
params [current-chat-id input-text]]
{:json-rpc/call [{:method method
:params params
:on-error #(rf/dispatch [:mention/on-error {:method method :params params} %])
:on-success #(rf/dispatch [:mention/on-check-mentions-success
:on-success #(rf/dispatch [:mention/on-replace-with-public-key-success
current-chat-id
editing-message
input-text
%])}]}))
(rf/defn on-check-mentions-success
{:events [:mention/on-check-mentions-success]}
(rf/defn on-replace-with-public-key-success
{:events [:mention/on-replace-with-public-key-success]}
[{:keys [db] :as cofx} current-chat-id editing-message input-text new-text]
(log/debug "[mentions] on-check-mentions-success"
(log/debug "[mentions] on-replace-with-public-key-success"
{:chat-id current-chat-id
:editing-message editing-message
:input-text input-text
+14 -95
View File
@@ -1,12 +1,7 @@
(ns status-im.chat.models.mentions
(:require [clojure.set :as set]
[quo.react :as react]
[quo.react-native :as rn]
[re-frame.core :as re-frame]
[status-im2.config :as config]
[utils.re-frame :as rf]
[taoensso.timbre :as log]
[native-module.core :as native-module]))
[taoensso.timbre :as log]))
(defn- transfer-input-segments
[segments]
@@ -99,10 +94,9 @@
[{:keys [db]} result]
(log/debug "[mentions] on-to-input-field-success" {:result result})
(let [{:keys [input-segments state chat-id new-text]} (transfer-mention-result result)]
{:set-text-input-value [chat-id new-text]
:db (-> db
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
{:db (-> db
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(rf/defn on-change-text
{:events [:mention/on-change-text]}
@@ -128,61 +122,21 @@
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(rf/defn recheck-at-idxs
[{:keys [db]} public-key]
(let [chat-id (:current-chat-id db)
text (get-in db [:chat/inputs chat-id :input-text])
params [chat-id text public-key]
method "wakuext_chatMentionRecheckAtIdxs"]
{:json-rpc/call [{:method method
:params params
:on-success #(rf/dispatch [:mention/on-recheck-at-idxs-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]}))
(rf/defn on-recheck-at-idxs-success
{:events [:mention/on-recheck-at-idxs-success]}
[{:keys [db]} result]
(log/debug "[mentions] on-recheck-at-idxs-success" {:result result})
(let [{:keys [input-segments state chat-id]} (transfer-mention-result result)]
{:db (-> db
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(rf/defn reset-text-input-cursor
[_ ref cursor]
{::reset-text-input-cursor [ref cursor]})
(rf/defn on-new-input-text-with-mentions-success
{:events [:mention/on-new-input-text-with-mentions-success]}
[{:keys [db] :as cofx} result primary-name text-input-ref match searched-text public-key]
(log/debug "[mentions] on-new-input-text-with-mentions-success"
(rf/defn on-select-mention-success
{:events [:mention/on-select-mention-success]}
[{:keys [db] :as cofx} result primary-name match searched-text public-key]
(log/debug "[mentions] on-select-mention-success"
{:result result
:primary-name primary-name
:match match
:searched-text searched-text
:public-key public-key})
(let [{:keys [new-text state chat-id]} (transfer-mention-result result)
{:keys [at-sign-idx]} state
cursor (+ at-sign-idx (count primary-name) 2)]
(rf/merge
cofx
(let [common {:db (-> db
(assoc-in [:chats/mention-suggestions chat-id] nil))
:dispatch [:chat.ui/set-chat-input-text new-text chat-id]}
extra (if (not config/new-composer-enabled?)
;; NOTE(rasom): Some keyboards do not react on selection property passed to
;; text input (specifically Samsung keyboard with predictive text set on).
;; In this case, if the user continues typing after the programmatic change,
;; the new text is added to the last known cursor position before
;; programmatic change. By calling `reset-text-input-cursor` we force the
;; keyboard's cursor position to be changed before the next input.
{:set-text-input-value [chat-id new-text text-input-ref]
:reset-text-input-cursor (reset-text-input-cursor text-input-ref cursor)}
{})]
(merge common extra))
(recheck-at-idxs public-key))))
(let [{:keys [new-text chat-id state input-segments]} (transfer-mention-result result)]
{:db (-> db
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments)
(assoc-in [:chats/mention-suggestions chat-id] nil))
:dispatch [:chat.ui/set-chat-input-text new-text chat-id]}))
(rf/defn clear-suggestions
[{:keys [db]}]
@@ -205,38 +159,3 @@
:on-error #(log/error "Error while calling wakuext_chatMentionClearMentions"
{:error %})}]}
(clear-suggestions))))
(rf/defn check-selection
{:events [:mention/on-selection-change]}
[{:keys [db]}
{:keys [start end]}]
(let [chat-id (:current-chat-id db)
text (get-in db [:chat/inputs chat-id :input-text])
params [chat-id text start end]
method "wakuext_chatMentionHandleSelectionChange"]
(when text
(log/debug "[mentions] check-selection" {:params params})
{:json-rpc/call [{:method method
:params params
:on-success #(rf/dispatch [:mention/on-handle-selection-change-success %])
:on-error #(rf/dispatch [:mention/on-error
{:method method
:params params} %])}]})))
(rf/defn on-check-selection-success
{:events [:mention/on-handle-selection-change-success]}
[{:keys [db]} result]
(log/debug "[mentions] on-check-selection-success" {:result result})
(let [{:keys [state chat-id mentionable-users input-segments]} (transfer-mention-result result)]
{:db (-> db
(assoc-in [:chats/mention-suggestions chat-id] mentionable-users)
(assoc-in [:chats/mentions chat-id :mentions] state)
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
(re-frame/reg-fx
::reset-text-input-cursor
(fn [[ref cursor]]
(when ref
(native-module/reset-keyboard-input
(rn/find-node-handle (react/current-ref ref))
cursor))))
@@ -20,7 +20,6 @@
:clock clock-value
:alias "alias"
:name "name"
:identicon "identicon"
:from "from"}]
;; <- cursor
;; <- message
@@ -107,7 +106,6 @@
:clock (- clock-value 2)
:alias "alias"
:name "name"
:identicon "identicon"
:from "from"}
result (dissoc (message/receive-many
cofx
+2 -4
View File
@@ -3,8 +3,7 @@
[clojure.string :as string]
[status-im2.constants :as constants]
[status-im.ethereum.core :as ethereum]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.identicon :as identicon]))
[status-im.utils.gfycat.core :as gfycat]))
(defn public-key->new-contact
[public-key]
@@ -12,7 +11,6 @@
{:alias alias
:name alias
:primary-name alias
:identicon (identicon/identicon public-key)
:public-key public-key}))
(defn public-key-and-ens-name->new-contact
@@ -59,7 +57,7 @@
[members admins contacts {:keys [public-key preferred-name name] :as current-account}]
(let [current-contact (some->
current-account
(select-keys [:name :preferred-name :public-key :identicon :images])
(select-keys [:name :preferred-name :public-key :images])
(set/rename-keys {:name :alias :preferred-name :name})
(assoc :primary-name (or preferred-name name)))
all-contacts (cond-> contacts
+2 -9
View File
@@ -1,13 +1,11 @@
(ns status-im.contact.db-test
(:require [cljs.test :refer-macros [deftest is testing]]
[status-im.contact.db :as contact.db]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.identicon :as identicon]))
[status-im.utils.gfycat.core :as gfycat]))
(deftest contacts-subs
(testing "get-all-contacts-in-group-chat"
(with-redefs [gfycat/generate-gfy (constantly "generated")
identicon/identicon (constantly "generated")]
(with-redefs [gfycat/generate-gfy (constantly "generated")]
(let
[chat-contact-ids
#{"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"
@@ -21,7 +19,6 @@
{:last-updated 0
:name "User B"
:primary-name "User B"
:identicon "photo1"
:last-online 0
:public-key
"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"}}
@@ -31,7 +28,6 @@
:sharing-usage-data? false
:primary-name "User A"
:name "User A"
:identicon "photo2"
:public-key
"0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"}]
(is
@@ -42,20 +38,17 @@
current-multiaccount)
[{:name "generated"
:primary-name "generated"
:identicon "generated"
:alias "generated"
:admin? true
:public-key
"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"}
{:alias "User A"
:primary-name "User A"
:identicon "photo2"
:public-key
"0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"}
{:last-updated 0
:name "User B"
:primary-name "User B"
:identicon "photo1"
:last-online 0
:public-key
"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"}]))))))
-1
View File
@@ -79,7 +79,6 @@
:emoji (.-emoji chat)
:timestamp (.-timestamp chat)
:alias (.-alias chat)
:identicon (.-identicon chat)
:muted (.-muted chat)
:joined (.-joined chat)
:muted-till (.-mutetill chat)
+2 -6
View File
@@ -62,7 +62,8 @@
[status-im2.common.theme.core :as theme]
[react-native.core :as rn]
[react-native.platform :as platform]
status-im2.contexts.chat.home.events))
status-im2.contexts.chat.home.events
status-im2.contexts.communities.home.events))
(re-frame/reg-fx
:dismiss-keyboard
@@ -108,11 +109,6 @@
[_]
{:dismiss-keyboard nil})
(rf/defn identicon-generated
{:events [:identicon-generated]}
[{:keys [db]} path identicon]
{:db (assoc-in db path identicon)})
(rf/defn gfycat-generated
{:events [:gfycat-generated]}
[{:keys [db]} path gfycat]
+3 -5
View File
@@ -339,11 +339,10 @@
(let [{:keys [key-uid encryption-public-key whisper-private-key]
:as account-data}
(js->clj data :keywordize-keys true)
{:keys [identicon name]} (get-in db [:multiaccounts/multiaccounts key-uid])
{:keys [name]} (get-in db [:multiaccounts/multiaccounts key-uid])
key-uid (get-in db [:keycard :application-info :key-uid])
multiaccount-data (types/clj->json {:name name
:key-uid key-uid
:identicon identicon})
multiaccount-data (types/clj->json {:name name
:key-uid key-uid})
save-keys? (get-in db [:multiaccounts/login :save-password?])]
(rf/merge cofx
{:db
@@ -360,7 +359,6 @@
(update :multiaccounts/login assoc
:password encryption-public-key
:key-uid key-uid
:identicon identicon
:name name))
:keycard/login-with-keycard {:multiaccount-data multiaccount-data
+1 -1
View File
@@ -200,7 +200,7 @@
(.remove listener)))
(re-frame/reg-fx
:keycard/generate-name-and-photo
:keycard/generate-name
(fn [{:keys [public-key on-success]}]
(native-module/gfycat-identicon-async
public-key
+6 -8
View File
@@ -151,13 +151,12 @@
:multiaccounts-stack
[:multiaccounts
:keycard-login-pin])
(let [{:keys [identicon name]} (get-in db [:multiaccounts/multiaccounts key-uid])
multiaccount-data (types/clj->json {:name name
:key-uid key-uid
:identicon identicon})
account-data {:key-uid key-uid
:encryption-public-key encryption-public-key
:whisper-private-key whisper-private-key}]
(let [{:keys [name]} (get-in db [:multiaccounts/multiaccounts key-uid])
multiaccount-data (types/clj->json {:name name
:key-uid key-uid})
account-data {:key-uid key-uid
:encryption-public-key encryption-public-key
:whisper-private-key whisper-private-key}]
{:db
(-> db
(assoc-in [:keycard :pin :status] nil)
@@ -168,7 +167,6 @@
(update :multiaccounts/login assoc
:password encryption-public-key
:key-uid key-uid
:identicon identicon
:name name
:save-password? true))
:keycard/login-with-keycard
+9 -13
View File
@@ -160,7 +160,6 @@
(let [{{:keys [multiaccount secrets flow]} :keycard} db
{:keys [address
name
identicon
public-key
whisper-public-key
wallet-public-key
@@ -175,18 +174,17 @@
recovered]}
multiaccount
{:keys [pairing paired-on]} secrets
{:keys [name identicon]}
{:keys [name]}
(if (nil? name)
;; name might have been generated during recovery via passphrase
(get-in db [:intro-wizard :derived constants/path-whisper-keyword])
{:name name
:identicon identicon})]
{:name name})]
;; if a name is still `nil` we have to generate it before multiaccount's
;; creation otherwise spec validation will fail
(if (nil? name)
{:keycard/generate-name-and-photo
{:keycard/generate-name
{:public-key whisper-public-key
:on-success ::on-name-and-photo-generated}}
:on-success ::on-name-generated}}
(rf/merge cofx
{:db (-> db
(assoc-in [:keycard :setup-step] nil)
@@ -199,8 +197,7 @@
constants/path-whisper-keyword
{:public-key whisper-public-key
:address (eip55/address->checksum whisper-address)
:name name
:identicon identicon}
:name name}
constants/path-default-wallet-keyword
{:public-key wallet-public-key
:address (eip55/address->checksum wallet-address)}}
@@ -382,11 +379,11 @@
{:on-card-connected :keycard/load-recovering-key-screen
:handler (common/dispatch-event :keycard/import-multiaccount)}))
(rf/defn on-name-and-photo-generated
{:events [::on-name-and-photo-generated]
(rf/defn on-name-generated
{:events [::on-name-generated]
:interceptors [(re-frame/inject-cofx :random-guid-generator)
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
[{:keys [db] :as cofx} whisper-name identicon]
[{:keys [db] :as cofx} whisper-name]
(rf/merge
cofx
{:db (update-in db
@@ -394,6 +391,5 @@
(fn [multiacc]
(assoc multiacc
:recovered (get db :recovered-account?)
:name whisper-name
:identicon identicon)))}
:name whisper-name)))}
(create-keycard-multiaccount)))
+2 -5
View File
@@ -268,12 +268,9 @@
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
(native-module/gfycat-identicon-async
public-key
(fn [name photo-path]
(fn [name _]
(let [derived-data-extended
(update derived-data
constants/path-whisper-keyword
merge
{:name name :identicon photo-path})]
(update derived-data constants/path-whisper-keyword assoc :name name)]
(reset! derived-acc
{:root-key root-data
:derived derived-data-extended})))))))))))
+4 -17
View File
@@ -9,7 +9,6 @@
[quo2.foundations.colors :as colors]
[status-im2.constants :as constants]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.identicon :as identicon]
[status-im2.setup.hot-reload :as hot-reload]
[status-im2.common.theme.core :as theme]
[taoensso.timbre :as log]
@@ -48,23 +47,11 @@
(gfycat/generate-gfy identity))]
[(:primary-name contact) (:secondary-name contact)])))
(def photo-quality-thumbnail :thumbnail)
(def photo-quality-large :large)
(defn displayed-photo
"If a photo, a image or an images array is set use it, otherwise fallback on identicon or generate"
[{:keys [images identicon public-key]}]
(cond
(pos? (count images))
(:uri (or (photo-quality-thumbnail images)
(photo-quality-large images)
(first images)))
(not (string/blank? identicon))
identicon
:else
(identicon/identicon public-key)))
[{:keys [images]}]
(or (:thumbnail images)
(:large images)
(first images)))
(re-frame/reg-fx
::webview-debug-changed
+3 -8
View File
@@ -71,11 +71,11 @@
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
(native-module/gfycat-identicon-async
public-key
(fn [name identicon]
(fn [name _]
(let [derived-whisper (derived-data constants/path-whisper-keyword)
derived-data-extended (assoc-in derived-data
[constants/path-whisper-keyword]
(merge derived-whisper {:name name :identicon identicon}))]
(assoc derived-whisper :name name))]
(re-frame/dispatch [::store-multiaccount-success key-code derived-data-extended]))))))]}))
(re-frame/reg-fx
@@ -154,13 +154,12 @@
:wallet true
:path constants/path-default-wallet
:name (i18n/label :t/main-account)})
(let [{:keys [compressed-key public-key address name identicon]}
(let [{:keys [compressed-key public-key address name]}
(get-in multiaccount [:derived constants/path-whisper-keyword])]
{:public-key public-key
:compressed-key compressed-key
:address (eip55/address->checksum address)
:name name
:identicon identicon
:path constants/path-whisper
:chat true})])
@@ -174,13 +173,11 @@
(let [[wallet-account
{:keys [public-key
compressed-key
identicon
name]} :as accounts-data]
(prepare-accounts-data
multiaccount)
multiaccount-data {:name name
:address address
:identicon identicon
:key-uid key-uid
:keycard-pairing keycard-pairing}
keycard-multiaccount? (boolean keycard-pairing)
@@ -202,7 +199,6 @@
constants/path-wallet-root-keyword
:address])
:name name
:identicon identicon
;; public key of the chat account
:public-key public-key
;; compressed key of the chat account
@@ -231,7 +227,6 @@
db (assoc db
:multiaccounts/login {:key-uid key-uid
:name name
:identicon identicon
:password password
:creating? true
:processing true}
+11 -13
View File
@@ -168,25 +168,23 @@
(rf/defn login
{:events [:multiaccounts.login.ui/password-input-submitted]}
[{:keys [db]}]
(let [{:keys [key-uid password name identicon]} (:multiaccounts/login db)]
(let [{:keys [key-uid password name]} (:multiaccounts/login db)]
{:db (-> db
(assoc-in [:multiaccounts/login :processing] true)
(dissoc :intro-wizard :recovered-account?)
(update :keycard dissoc :flow))
::login [key-uid
(types/clj->json {:name name
:key-uid key-uid
:identicon identicon})
(types/clj->json {:name name
:key-uid key-uid})
(ethereum/sha3 (security/safe-unmask-data password))]}))
(rf/defn export-db-submitted
{:events [:multiaccounts.login.ui/export-db-submitted]}
[{:keys [db]}]
(let [{:keys [key-uid password name identicon]} (:multiaccounts/login db)]
(let [{:keys [key-uid password name]} (:multiaccounts/login db)]
{::export-db [key-uid
(types/clj->json {:name name
:key-uid key-uid
:identicon identicon})
(types/clj->json {:name name
:key-uid key-uid})
(ethereum/sha3 (security/safe-unmask-data password))
(fn [path]
(when platform/ios?
@@ -198,11 +196,10 @@
(rf/defn import-db-submitted
{:events [:multiaccounts.login.ui/import-db-submitted]}
[{:keys [db]}]
(let [{:keys [key-uid password name identicon]} (:multiaccounts/login db)]
(let [{:keys [key-uid password name]} (:multiaccounts/login db)]
{::import-db [key-uid
(types/clj->json {:name name
:key-uid key-uid
:identicon identicon})
(types/clj->json {:name name
:key-uid key-uid})
(ethereum/sha3 (security/safe-unmask-data password))]}))
(rf/defn finish-keycard-setup
@@ -742,7 +739,8 @@
(merge
{:db (update db :keycard dissoc :application-info)}
(when keycard-multiaccount? {:navigate-to :keycard-login-pin}))
(open-login (select-keys multiaccount [:key-uid :name :public-key :identicon :images])))))
(open-login (select-keys multiaccount
[:key-uid :name :public-key :images :customization-color])))))
(rf/defn hide-keycard-banner
{:events [:hide-keycard-banner]}
@@ -5,8 +5,6 @@
:tags #{}
:address "2f88d65f3cb52605a54a833ae118fb1363acccd2"
:name "Darkviolet Lightgreen Halcyon"
:identicon
"data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX///+M2KwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdPOdBAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5UBARL8TK8AAAAASUVORK5CYII="
:added? true
:last-online 0
:public-key
@@ -14,8 +12,6 @@
{:last-updated 1547271764000
:address "b267ff8336ac10b3a1986c04a70ff91fb03d0b78"
:name "rv"
:identicon
"data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX////VjNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwYzy6AAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEAAAAAAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQAAAAABAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6IYA4bRtf+EAAAAASUVORK5CYII="
:added? true
:last-online 0
:public-key
@@ -101,8 +97,6 @@
:xdai #{}}
:preview-privacy? true
:fleet :eth.prod
:identicon
"data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX////YsYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPGFwxAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEAAAAAAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQAAAAABAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAloYA4a9rBHIAAAAASUVORK5CYII="
:wallet-set-up-passed? false
:public-key
"0x04173f7cdea0076a7998abb674cc79fe61337c42db77043c01d5b0f3e3ac1e5a45bca0c93bb9f3c3d38b7cc9a7337cd64f9f9b2114fe4bbdfe1ae2633ba14d8c9c"
@@ -10,14 +10,13 @@
(deftest on-password-input-submitted
(testing
"handling :multiaccounts.login.ui/password-input-submitted event"
(let [cofx {:db {:multiaccounts/login {:key-uid "key-uid"
:password "password"
:name "user"
:identicon "photo"}}}
(let [cofx {:db {:multiaccounts/login {:key-uid "key-uid"
:password "password"
:name "user"}}}
efx (login.core/login cofx)]
(testing "Change multiaccount."
(is (= (::login.core/login efx)
["key-uid" "{\"name\":\"user\",\"key-uid\":\"key-uid\",\"identicon\":\"photo\"}"
["key-uid" "{\"name\":\"user\",\"key-uid\":\"key-uid\"}"
(ethereum/sha3 "password")])))
(testing "start activity indicator"
(is (= (get-in efx [:db :multiaccounts/login :processing]) true))))))
@@ -108,12 +108,9 @@
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
(native-module/gfycat-identicon-async
public-key
(fn [name identicon]
(fn [name _]
(let [derived-data-extended
(update derived-data
constants/path-whisper-keyword
merge
{:name name :identicon identicon})]
(update derived-data constants/path-whisper-keyword assoc :name name)]
(re-frame/dispatch [success-event root-data derived-data-extended]))))))))))))
(rf/defn show-existing-multiaccount-alert
+3 -3
View File
@@ -195,10 +195,10 @@
(rf/defn send-installation-messages
{:events [:pairing.ui/synchronize-installation-pressed]}
[{:keys [db]}]
(let [multiaccount (:multiaccount db)
{:keys [name preferred-name identicon]} multiaccount]
(let [multiaccount (:multiaccount db)
{:keys [name preferred-name]} multiaccount]
{:json-rpc/call [{:method "wakuext_syncDevices"
:params [(or preferred-name name) identicon]
:params [(or preferred-name name)]
:on-success #(log/debug "successfully synced devices")}]}))
(defn installation<-rpc
+1 -1
View File
@@ -33,7 +33,7 @@
;; in case of an unknown error we show the
;; error
(if (= error "file is not a database")
(i18n/label :t/wrong-password)
(i18n/label :t/oops-wrong-password)
error)))}
(= (:view-id db) :progress)
(assoc :dispatch [:navigate-to :login]))
@@ -2,6 +2,7 @@
(:require [clojure.string :as string]
[quo.design-system.colors :as colors]
[quo.react-native :as rn]
[quo2.core :as quo]
[re-frame.core :as re-frame.core]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.ui.components.chat-icon.styles :as styles]
@@ -47,19 +48,13 @@
(defn profile-photo-plus-dot-view
[{:keys [public-key photo-container photo-path community?]}]
(let [photo-path (if (nil? photo-path)
@(re-frame.core/subscribe [:chats/photo-path public-key])
photo-path)
photo-container (if (nil? photo-container)
(let [photo-container (if (nil? photo-container)
styles/container-chat-list
photo-container)
size (:width photo-container)
identicon? (and photo-path
(string/starts-with? photo-path "data:image/png;base64,"))
dot-styles (visibility-status-utils/icon-visibility-status-dot
public-key
size
identicon?)
size)
dot-accessibility-label (:accessibility-label dot-styles)]
[rn/view
{:style photo-container
@@ -147,9 +142,13 @@
[photos/photo (multiaccounts/displayed-photo contact) styles]])
(defn contact-icon-contacts-tab
[photo-path]
[{:keys [primary-name] :as contact}]
[rn/view styles/container-chat-list
[photos/photo photo-path {:size 40}]])
[quo/user-avatar
{:full-name primary-name
:profile-picture (multiaccounts/displayed-photo contact)
:size :small
:status-indicator? false}]])
(defn dapp-icon-permission
[contact size]
@@ -195,9 +194,10 @@
:public-key public-key
:photo-container (:container styles)
:community? community?}]
(if (string/blank? emoji)
[default-chat-icon name styles]
[emoji-chat-icon emoji styles]))
[rn/view {:accessibility-label :chat-icon}
(if (string/blank? emoji)
[default-chat-icon name styles]
[emoji-chat-icon emoji styles])])
(when edit?
[rn/view {:style (styles/chat-icon-profile-edit)}
[icons/tiny-icon :tiny-icons/tiny-edit {:color colors/white-persist}]])]))
+3 -23
View File
@@ -1,7 +1,5 @@
(ns status-im.ui.screens.chat.photos
(:require [quo.design-system.colors :as colors]
[re-frame.core :as re-frame]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.ui.components.fast-image :as fast-image]
[status-im.ui.components.react :as react]
[status-im.ui.screens.chat.styles.photos :as style]))
@@ -11,32 +9,14 @@
(fn [photo-path size accessibility-label _]
[react/view {:style (style/photo-container size)}
[fast-image/fast-image
{:source {:uri photo-path}
{:source photo-path
:style (style/photo size)
:accessibility-label (or accessibility-label :chat-icon)}]
[react/view {:style (style/photo-border size)}]])))
;; "(colors/dark?)" is passed to memoized function to avoid previous themes cache
;; TODO: it's only used for old code, `quo/user-avatar` should be used instead for all the new one
(defn photo
^:deprecated
[photo-path {:keys [size accessibility-label]}]
[memo-photo-rend photo-path size accessibility-label (colors/dark?)])
;; We optionally pass identicon for perfomance reason, so it does not have to be calculated for each
;; message
(defn member-photo
([pub-key]
(member-photo pub-key nil))
([pub-key identicon]
(member-photo pub-key identicon style/default-size))
([pub-key identicon size]
(let [path @(re-frame/subscribe [:chats/photo-path pub-key identicon])]
[photo path
{:size size
:accessibility-label :member-photo}])))
(defn account-photo
[account]
(let [path (multiaccounts/displayed-photo account)]
[photo path
{:size style/default-size
:accessibility-label :own-account-photo}]))
+3 -4
View File
@@ -14,13 +14,12 @@
(defn one-to-one-chat-accents
[chat-id]
(let [photo @(re-frame/subscribe [:chats/photo-path chat-id])
contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity chat-id])]
(let [{:keys [primary-name] :as contact} @(re-frame/subscribe [:contacts/contact-by-identity chat-id])]
[react/view
[quo/list-item
{:theme :accent
:icon [chat-icon/contact-icon-contacts-tab photo]
:title contact-name
:icon [chat-icon/contact-icon-contacts-tab contact]
:title primary-name
:subtitle (i18n/label :t/view-profile)
:accessibility-label :view-chat-details-button
:chevron true
@@ -6,7 +6,6 @@
[status-im.communities.core :as communities]
[status-im2.constants :as constants]
[utils.i18n :as i18n]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.ui.components.chat-icon.screen :as chat-icon.screen]
[status-im.ui.components.toolbar :as toolbar]
[status-im.ui.components.topbar :as topbar]
@@ -34,8 +33,7 @@
[quo/list-item
{:title primary-name
:subtitle secondary-name
:icon [chat-icon.screen/contact-icon-contacts-tab
(multiaccounts/displayed-photo contact)]
:icon [chat-icon.screen/contact-icon-contacts-tab contact]
:accessory :checkbox
:active active
:on-press (fn []
@@ -22,8 +22,7 @@
[:<>
[quo/list-item
{:theme :accent
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo member)]
:icon [chat-icon/contact-icon-contacts-tab member]
:title primary-name
:subtitle (i18n/label :t/view-profile)
:accessibility-label :view-chat-details-button
@@ -46,8 +46,7 @@
{:flex-basis 120})
:accessory (when can-manage-users?
[request-actions community-id id])
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo member)]
:icon [chat-icon/contact-icon-contacts-tab member]
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]))
(defn requests-to-join
+2 -5
View File
@@ -5,7 +5,6 @@
[reagent.core :as reagent]
[status-im2.constants :as constants]
[utils.i18n :as i18n]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.invite.views :as invite]
[status-im.ui.components.keyboard-avoid-presentation :as kb-presentation]
@@ -24,8 +23,7 @@
[quo/list-item
{:title primary-name
:subtitle secondary-name
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo row)]}]))
:icon [chat-icon/contact-icon-contacts-tab row]}]))
(defn- on-toggle
[allow-new-users? checked? public-key]
@@ -59,8 +57,7 @@
[quo/list-item
{:title primary-name
:subtitle secondary-name
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo contact)]
:icon [chat-icon/contact-icon-contacts-tab contact]
:on-press #(on-toggle allow-new-users? contact-selected? public-key)
:active contact-selected?
:accessory :checkbox}])))
+2 -4
View File
@@ -205,10 +205,8 @@
[_ _]
(reagent/create-class
{:should-component-update
(fn [_ [_ old-account] [_ new-account]]
(and (not (nil? new-account))
(and (not (:identicon old-account))
(nil? (:identicon new-account)))))
(fn [_ [_ _] [_ new-account]]
(not (nil? new-account)))
:reagent-render
(fn [account small-screen?]
@@ -5,7 +5,6 @@
[re-frame.core :as re-frame]
[re-frame.db]
[utils.i18n :as i18n]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.multiaccounts.key-storage.core :as multiaccounts.key-storage]
[status-im.react-native.resources :as resources]
[status-im.ui.components.accordion :as accordion]
@@ -68,8 +67,7 @@
[local-topbar (i18n/label :t/choose-actions)]
[accordion/section
{:title name
:icon [chat-icon.screen/contact-icon-contacts-tab
(multiaccounts/displayed-photo multiaccount)]
:icon [chat-icon.screen/contact-icon-contacts-tab multiaccount]
:content [accordion-content]}]
[react/view
{:flex 1
@@ -17,8 +17,7 @@
(letsubs [{:keys [pubkey
processing?
compressed-key
name
identicon]}
name]}
[:intro-wizard/recovery-success]
existing-account? [:intro-wizard/recover-existing-account?]]
[react/view
@@ -44,14 +43,7 @@
[react/view
{:justify-content :center
:align-items :center
:margin-bottom 11}
[react/image
{:source {:uri identicon}
:style {:width 61
:height 61
:border-radius 30
:border-width 1
:border-color colors/black-transparent}}]]
:margin-bottom 11}]
[react/text
{:style {:text-align :center
:color colors/black
@@ -46,8 +46,7 @@
(i18n/label :t/delete-profile)]]
[quo/list-item
{:title (multiaccounts/displayed-name multiaccount)
:icon [chat-icon.screen/contact-icon-contacts-tab
(multiaccounts/displayed-photo multiaccount)]}]
:icon [chat-icon.screen/contact-icon-contacts-tab multiaccount]}]
(when keycard?
[react/view
[quo/list-header (i18n/label :t/actions)]
@@ -23,8 +23,7 @@
[react/view
[quo/list-item
{:theme :accent
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo member)]
:icon [chat-icon/contact-icon-contacts-tab member]
:title (:primary-name member)
:subtitle (i18n/label :t/view-profile)
:accessibility-label :view-chat-details-button
@@ -59,8 +58,7 @@
{:title primary-name
:subtitle secondary-name
:accessibility-label :member-item
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo member)]
:icon [chat-icon/contact-icon-contacts-tab member]
:on-press (when (not= public-key current-user-identity)
#(re-frame/dispatch [:chat.ui/show-profile public-key]))}
(when (:admin? member)
@@ -140,8 +138,7 @@
(let [contact (or @(re-frame/subscribe [:contacts/contact-by-identity from]) {:public-key from})]
[quo/list-item
{:title (multiaccounts/displayed-name contact)
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo contact)]
:icon [chat-icon/contact-icon-contacts-tab contact]
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
{:content (fn []
[invitation-sheet invitation contact])}])}]))
@@ -94,20 +94,16 @@
:online-profile-photo-dot
:offline-profile-photo-dot))
(defn icon-dot-margin
[_ _]
-2)
(defn icon-dot-size
[container-size]
(/ container-size 2.4))
(defn icon-visibility-status-dot
[public-key container-size identicon?]
[public-key container-size]
(let [my-icon? (my-icon? public-key)
visibility-status-update (visibility-status-update public-key my-icon?)
size (icon-dot-size container-size)
margin (icon-dot-margin size identicon?)
margin -2
dot-color (icon-dot-color visibility-status-update)
new-ui? true]
(merge (styles/visibility-status-dot {:color dot-color
@@ -7,7 +7,6 @@
[status-im.ethereum.core :as ethereum]
[status-im.ethereum.stateofus :as stateofus]
[utils.i18n :as i18n]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.ui.components.chat-icon.screen :as chat-icon]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.keyboard-avoid-presentation :as kb-presentation]
@@ -98,8 +97,7 @@
(some-> ^js @scroll-view-ref
(.scrollTo #js {:x 0 :animated true}))
(re-frame/dispatch [:wallet.recipient/address-changed name]))
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo contact)]}])
:icon [chat-icon/contact-icon-contacts-tab contact]}])
(defn empty-items
[icon title]
@@ -83,8 +83,7 @@
{:monospace true
:color :secondary}
(utils/get-shortened-checksum-address (:address contact))]
:icon [chat-icon/contact-icon-contacts-tab
(multiaccounts/displayed-photo contact)]}]
:icon [chat-icon/contact-icon-contacts-tab contact]}]
[quo/list-item
(merge {:title (if-not contact
(i18n/label :t/wallet-choose-recipient)
@@ -1,25 +0,0 @@
(ns status-im.ui2.screens.chat.components.edit.style)
(def container
{:flex-direction :row
:height 24})
(def content-container
{:padding-horizontal 10
:flex 1
:flex-direction :row})
(def icon-container
{:position :absolute
:left 10
:bottom -4
:width 16
:height 16})
(def text-container
{:position :absolute
:left 36
:right 54
:top 3
:flex-direction :row
:align-items :center})
@@ -1,33 +0,0 @@
(ns status-im.ui2.screens.chat.components.edit.view
(:require [utils.i18n :as i18n]
[quo2.core :as quo]
[quo2.foundations.colors :as colors]
[re-frame.core :as rf]
[react-native.core :as rn]
[status-im.ui2.screens.chat.components.edit.style :as style]))
(defn edit-message
[on-cancel]
[rn/view
{:style style/container
:accessibility-label :edit-message}
[rn/view {:style style/content-container}
[quo/icon :i/connector
{:size 16
:color (colors/theme-colors colors/neutral-40 colors/neutral-60)
:container-style style/icon-container}]
[rn/view {:style style/text-container}
[quo/text
{:weight :medium
:size :paragraph-2}
(i18n/label :t/editing-message)]]]
[quo/button
{:width 24
:size 24
:accessibility-label :reply-cancel-button
:on-press #(do (on-cancel)
(rf/dispatch [:chat.ui/cancel-message-edit]))
:type :outline}
[quo/icon :i/close
{:size 16
:color (colors/theme-colors colors/neutral-100 colors/neutral-40)}]]])
@@ -1,37 +0,0 @@
(ns status-im.ui2.screens.chat.components.reply.style)
(defn reply-content
[pin?]
{:padding-horizontal (when-not pin? 10)
:flex 1
:flex-direction :row})
(defn quoted-message
[pin? in-chat-input?]
(merge {:flex-direction :row
:flex 1
:align-items :center
:width (if in-chat-input? "100%" "45%")}
(when-not pin?
{:left 22
:margin-right 22})))
(def reply-from
{:flex-direction :row
:align-items :center})
(def message-author-text
{:margin-left 4})
(def message-text
{:text-transform :none
:margin-left 4
:margin-top 2
:flex 1})
(def gradient
{:position :absolute
:right 0
:top 0
:bottom 0
:width "50%"})
@@ -1,142 +0,0 @@
(ns status-im.ui2.screens.chat.components.reply.view
(:require [clojure.string :as string]
[utils.i18n :as i18n]
[quo.react-native :as rn]
[quo2.components.buttons.button :as quo2.button]
[quo2.components.icon :as quo2.icon]
[quo2.components.markdown.text :as quo2.text]
[quo2.foundations.colors :as colors]
[status-im2.constants :as constants]
[status-im.ethereum.stateofus :as stateofus]
[status-im.ui.components.icons.icons :as icons]
[status-im2.contexts.chat.messages.avatar.view :as avatar]
[utils.re-frame :as rf]
[status-im.ui2.screens.chat.components.reply.style :as style]
[react-native.linear-gradient :as linear-gradient]))
(defn get-quoted-text-with-mentions
[parsed-text]
(string/join
(mapv (fn [{:keys [type literal children]}]
(cond
(= type "paragraph")
(get-quoted-text-with-mentions children)
(= type "mention")
(rf/sub [:messages/resolve-mention literal])
(seq children)
(get-quoted-text-with-mentions children)
:else
literal))
parsed-text)))
(defn format-author
[contact-name]
(let [author (if (or (= (aget contact-name 0) "@")
;; in case of replies
(= (aget contact-name 1) "@"))
(or (stateofus/username contact-name)
(subs contact-name 0 81))
contact-name)]
author))
(defn format-reply-author
[from username current-public-key]
(or (and (= from current-public-key)
(i18n/label :t/You))
(when username (format-author username))))
(defn reply-deleted-message
[]
[rn/view
{:style {:flex-direction :row
:align-items :center}}
[quo2.icon/icon :sad-face {:size 16}]
[quo2.text/text
{:number-of-lines 1
:size :label
:weight :regular
:accessibility-label :quoted-message
:style {:text-transform :none
:margin-left 4
:margin-top 2}}
(i18n/label :t/message-deleted)]])
(defn reply-from
[{:keys [from contact-name current-public-key]}]
[rn/view {:style style/reply-from}
[avatar/avatar from :xxxs]
[quo2.text/text
{:weight :semi-bold
:size :paragraph-2
:number-of-lines 1
:style style/message-author-text}
(format-reply-author from contact-name current-public-key)]])
(defn reply-message
[{:keys [from identicon content-type contentType parsed-text content deleted? deleted-for-me?
album-images-count]}
in-chat-input? pin? recording-audio?]
(let [contact-name (rf/sub [:contacts/contact-name-by-identity from])
current-public-key (rf/sub [:multiaccount/public-key])
content-type (or content-type contentType)]
[rn/view
{:style {:flex-direction :row
:height (when-not pin? 24)
:accessibility-label :reply-message}}
[rn/view {:style (style/reply-content pin?)}
(when-not pin?
;;TODO quo2 icon should be used
[icons/icon :main-icons/connector
{:color (colors/theme-colors colors/neutral-40 colors/neutral-60)
:container-style {:position :absolute :left 10 :bottom -4 :width 16 :height 16}}])
(if (or deleted? deleted-for-me?)
[rn/view {:style (style/quoted-message pin? in-chat-input?)}
[reply-deleted-message]]
[rn/view {:style (style/quoted-message pin? in-chat-input?)}
[reply-from
{:from from
:identicon identicon
:contact-name contact-name
:current-public-key current-public-key}]
[quo2.text/text
{:number-of-lines 1
:size :label
:weight :regular
:accessibility-label :quoted-message
:ellipsize-mode :tail
:style (merge
style/message-text
(when (or (= constants/content-type-image content-type)
(= constants/content-type-sticker content-type)
(= constants/content-type-audio content-type))
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40)}))}
(case (or content-type contentType)
constants/content-type-image (if album-images-count
(i18n/label :t/images-albums-count
{:album-images-count album-images-count})
(i18n/label :t/image))
constants/content-type-sticker (i18n/label :t/sticker)
constants/content-type-audio (i18n/label :t/audio)
(get-quoted-text-with-mentions (or parsed-text (:parsed-text content))))]])]
(when (and in-chat-input? (not recording-audio?))
[quo2.button/button
{:width 24
:size 24
:type :outline
:accessibility-label :reply-cancel-button
:on-press #(rf/dispatch [:chat.ui/cancel-message-reply])}
;;TODO quo2 icon should be used
[icons/icon :main-icons/close
{:width 16
:height 16
:color (colors/theme-colors colors/neutral-100 colors/neutral-40)}]])
(when (and in-chat-input? recording-audio?)
[linear-gradient/linear-gradient
{:colors [(colors/theme-colors colors/white-opa-0 colors/neutral-90-opa-0)
(colors/theme-colors colors/white colors/neutral-90)]
:start {:x 0 :y 0}
:end {:x 0.7 :y 0}
:style style/gradient}])]))
@@ -1,5 +0,0 @@
(ns status-im.ui2.screens.chat.composer.edit.style)
(def container
{:padding-horizontal 15
:padding-vertical 8})
@@ -1,23 +0,0 @@
(ns status-im.ui2.screens.chat.composer.edit.view
(:require [react-native.core :as rn]
[status-im.ui2.screens.chat.components.edit.view :as edit]
[status-im.ui2.screens.chat.composer.edit.style :as style]
[status-im.ui2.screens.chat.composer.input :as input]))
(defn- focus-input-on-edit
[edit had-edit text-input-ref]
;;when we show edit we focus input
(when-not (= edit @had-edit)
(reset! had-edit edit)
(when edit
;; A setTimeout of 0 is necessary to ensure the statement is enqueued and will get executed ASAP.
(js/setTimeout #(input/input-focus text-input-ref) 0))))
(defn edit-message-auto-focus-wrapper
[text-input-ref _]
(let [had-edit (atom nil)]
(fn [_ edit on-cancel]
(focus-input-on-edit edit had-edit text-input-ref)
(when edit
[rn/view {:style style/container}
[edit/edit-message on-cancel]]))))
@@ -1,11 +0,0 @@
(ns status-im.ui2.screens.chat.composer.images.style)
(def remove-photo-container
{:position :absolute
:top 5
:right 5})
(def small-image
{:width 56
:height 56
:border-radius 8})
@@ -1,35 +0,0 @@
(ns status-im.ui2.screens.chat.composer.images.view
(:require [quo2.core :as quo]
[quo2.foundations.colors :as colors]
[re-frame.core :as rf]
[react-native.core :as rn]
[status-im.ui2.screens.chat.composer.images.style :as style]))
(defn image
[item]
;; there is a bug on Android https://github.com/facebook/react-native/issues/12534
;; so we need some magic here with paddings so close button isn't cut
[rn/view {:padding-top 12 :padding-bottom 8 :padding-right 12}
[rn/image
{:source {:uri (:resized-uri (val item))}
:style style/small-image}]
[rn/touchable-opacity
{:on-press (fn [] (rf/dispatch [:chat.ui/image-unselected (val item)]))
:style style/remove-photo-container
:hit-slop {:right 5
:left 5
:top 10
:bottom 10}}
[quo/icon :i/clear
{:size 20
:color (colors/theme-colors colors/neutral-50 colors/neutral-60)}]]])
(defn images-list
[images]
(when (seq images)
[rn/flat-list
{:key-fn first
:render-fn image
:data images
:horizontal true
:keyboard-should-persist-taps :handled}]))
@@ -1,383 +0,0 @@
(ns status-im.ui2.screens.chat.composer.input
(:require [clojure.string :as string]
[oops.core :as oops]
[quo2.foundations.colors :as colors]
[re-frame.core :as re-frame]
[reagent.core :as reagent]
[status-im2.constants :as chat.constants]
[utils.i18n :as i18n]
[utils.re-frame :as rf]
[utils.transforms :as transforms]
[quo2.foundations.typography :as typography]
[react-native.background-timer :as background-timer]
[react-native.platform :as platform]
[react-native.core :as rn]
[react-native.clipboard :as clipboard]
[quo.react :as quo.react]))
(defonce input-texts (atom {}))
(defonce input-text-content-heights (atom {}))
(defonce mentions-enabled? (reagent/atom {}))
(defonce chat-input-key (reagent/atom 1))
(defonce text-input-ref (reagent/atom nil))
(defonce recording-audio? (reagent/atom false))
(defonce reviewing-audio? (reagent/atom false))
(defonce reviewing-audio-filepath (atom {}))
(defonce record-audio-permission-granted (reagent/atom false))
(defonce record-audio-reset-fn (atom nil))
(declare selectable-text-input)
(re-frame/reg-fx
:chat.ui/clear-inputs
(fn []
(reset! input-texts {})
(reset! input-text-content-heights {})
(reset! mentions-enabled? {})
(reset! chat-input-key 1)))
(defn input-focus
[text-input-ref]
(some-> ^js (quo.react/current-ref text-input-ref)
.focus))
(defn show-send
[{:keys [actions-ref send-ref sticker-ref record-ref]} chat-id]
(when (and (or @recording-audio?
(get @reviewing-audio-filepath chat-id))
@record-audio-reset-fn)
(@record-audio-reset-fn)
(swap! reviewing-audio-filepath dissoc chat-id))
(when actions-ref
(quo.react/set-native-props actions-ref #js {:width 0 :left -88}))
(quo.react/set-native-props send-ref #js {:width nil :right nil})
(quo.react/set-native-props record-ref #js {:right nil :left -1000})
(when sticker-ref
(quo.react/set-native-props sticker-ref #js {:width 0 :right -100})))
(defn hide-send
[{:keys [actions-ref send-ref sticker-ref record-ref]}]
(when actions-ref
(quo.react/set-native-props actions-ref #js {:width nil :left nil}))
(quo.react/set-native-props send-ref #js {:width 0 :right -100})
(quo.react/set-native-props record-ref #js {:left 0 :right 0})
(when sticker-ref
(quo.react/set-native-props sticker-ref #js {:width nil :right nil})))
(defn reset-input
[refs chat-id]
(some-> ^js (quo.react/current-ref (:text-input-ref refs))
.clear)
(swap! mentions-enabled? update :render not)
(swap! input-texts dissoc chat-id)
(swap! input-text-content-heights dissoc chat-id))
(defn clear-input
[chat-id refs]
(hide-send refs)
(if (get @mentions-enabled? chat-id)
(do
(swap! mentions-enabled? dissoc chat-id)
;;we need this timeout, because if we clear text input and first index was a mention object with
;;blue color,
;;after clearing text will be typed with this blue color, so we render white text first and then
;;clear it
(js/setTimeout #(reset-input refs chat-id) 50))
(reset-input refs chat-id)))
(defn on-text-change
[val chat-id]
(swap! input-texts assoc chat-id val)
;;we still store it in app-db for mentions, we don't have reactions in views
(rf/dispatch [:chat.ui/set-chat-input-text val]))
(defn on-selection-change
[timeout-id last-text-change args]
(let [selection (.-selection ^js (.-nativeEvent ^js args))
start (.-start selection)
end (.-end selection)]
;; NOTE(rasom): on iOS we do not dispatch this event immediately
;; because it is needed only in case if selection is changed without
;; typing. Timeout might be canceled on `on-change`.
(when platform/ios?
(reset!
timeout-id
(background-timer/set-timeout
#(rf/dispatch [:mention/on-selection-change
{:start start
:end end}])
50)))
;; NOTE(rasom): on Android we dispatch event only in case if there
;; was no text changes during last 50ms. `on-selection-change` is
;; dispatched after `on-change`, that's why there is no another way
;; to know whether selection was changed without typing.
(when (and platform/android?
(or (not @last-text-change)
(< 50 (- (js/Date.now) @last-text-change))))
(rf/dispatch [:mention/on-selection-change
{:start start
:end end}]))))
(defn on-change
[last-text-change timeout-id refs chat-id sending-image args]
(let [text (.-text ^js (.-nativeEvent ^js args))
prev-text (get @input-texts chat-id)]
(when (and (seq prev-text) (empty? text) (not sending-image))
(hide-send refs))
(when (and (empty? prev-text) (or (seq text) sending-image))
(show-send refs chat-id)
(reset! recording-audio? false)
(swap! reviewing-audio-filepath dissoc chat-id))
(when (and (not (get @mentions-enabled? chat-id)) (string/index-of text "@"))
(swap! mentions-enabled? assoc chat-id true))
;; NOTE(rasom): on iOS `on-selection-change` is canceled in case if it
;; happens during typing because it is not needed for mention
;; suggestions calculation
(when (and platform/ios? @timeout-id)
(background-timer/clear-timeout @timeout-id))
(when platform/android?
(reset! last-text-change (js/Date.now)))
(on-text-change text chat-id)
(rf/dispatch [:mention/on-change-text text])))
(defn on-text-input
[chat-id args]
(let [native-event (.-nativeEvent ^js args)
text (.-text ^js native-event)]
(when (and (not (get @mentions-enabled? chat-id)) (string/index-of text "@"))
(swap! mentions-enabled? assoc chat-id true))))
(defn text-input-style
[chat-id]
(merge typography/font-regular
typography/paragraph-1
{:flex 1
:min-height 34
:margin 0
:flex-shrink 1
:color (colors/theme-colors colors/neutral-100 colors/white)
:margin-horizontal 20}
(if platform/android?
{:padding-vertical 8
:text-align-vertical :top}
{:margin-top 8
:margin-bottom 8})
(when (or @recording-audio? (get @reviewing-audio-filepath chat-id))
{:display :none})))
(defn text-input
[{:keys [refs chat-id sending-image on-content-size-change]}]
(let [cooldown-enabled? (rf/sub [:chats/current-chat-cooldown-enabled?])
timeout-id (reagent/atom nil)
last-text-change (reagent/atom nil)
mentions-enabled? (get @mentions-enabled? chat-id)
props
{:style (text-input-style chat-id)
:ref (:text-input-ref refs)
:max-font-size-multiplier 1
:accessibility-label :chat-message-input
:text-align-vertical :center
:multiline true
:editable (not cooldown-enabled?)
:blur-on-submit false
:auto-focus false
:max-length chat.constants/max-text-size
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/white-opa-30)
:placeholder (if cooldown-enabled?
(i18n/label :cooldown/text-input-disabled)
(i18n/label :t/type-a-message))
:default-value (get @input-texts chat-id)
:underline-color-android :transparent
:auto-capitalize :sentences
:auto-correct false
:spell-check false
:on-content-size-change on-content-size-change
:on-selection-change (partial on-selection-change
timeout-id
last-text-change)
:on-change
(partial on-change last-text-change timeout-id refs chat-id sending-image)
:on-text-input (partial on-text-input chat-id)}
input-with-mentions (rf/sub [:chat/input-with-mentions])
children (fn []
(if mentions-enabled?
(map-indexed
(fn [index [mention-type text]]
^{:key (str index "_" mention-type "_" text)}
[rn/text (when (= mention-type :mention) {:style {:color colors/primary-50}})
text])
input-with-mentions)
(get @input-texts chat-id)))]
(reset! text-input-ref (:text-input-ref refs))
;when ios implementation for selectable-text-input is ready, we need remove this condition and use
;selectable-text-input directly.
(if platform/android?
[selectable-text-input chat-id props children]
[rn/text-input props
children])))
(declare first-level-menu-items second-level-menu-items)
(defn update-input-text
[{:keys [text-input chat-id]} text]
(on-text-change text chat-id)
(.setNativeProps ^js text-input (clj->js {:text text})))
(re-frame/reg-fx
:set-text-input-value
(fn [[chat-id text local-text-input-ref]]
(when local-text-input-ref
(reset! text-input-ref local-text-input-ref))
(on-text-change text chat-id)
(if platform/ios?
(.setNativeProps ^js (quo.react/current-ref @text-input-ref) (clj->js {:text text}))
(if (string/blank? text)
(.clear ^js (quo.react/current-ref @text-input-ref))
(.setNativeProps ^js (quo.react/current-ref @text-input-ref) (clj->js {:text text}))))))
(defn calculate-input-text
[{:keys [full-text selection-start selection-end]} content]
(let [head (subs full-text 0 selection-start)
tail (subs full-text selection-end)]
(str head content tail)))
(defn update-selection
[text-input-handle selection-start selection-end]
;to avoid something disgusting like this
;https://lightrun.com/answers/facebook-react-native-textinput-controlled-selection-broken-on-both-ios-and-android
;use native invoke instead! do not use setNativeProps! e.g. (.setNativeProps ^js text-input (clj->js
;{:selection {:start selection-start :end selection-end}}))
(let [manager (rn/selectable-text-input-manager)]
(oops/ocall manager :setSelection text-input-handle selection-start selection-end)))
(def first-level-menus
{:cut (fn [{:keys [content] :as params}]
(let [new-text (calculate-input-text params "")]
(clipboard/set-string content)
(update-input-text params new-text)))
:copy-to-clipboard (fn [{:keys [content]}]
(clipboard/set-string content))
:paste (fn [params]
(let [callback (fn [paste-content]
(let [content (string/trim paste-content)
new-text (calculate-input-text params content)]
(update-input-text params new-text)))]
(clipboard/get-string callback)))
:biu (fn [{:keys [first-level text-input-handle menu-items selection-start
selection-end]}]
(reset! first-level false)
(reset! menu-items second-level-menu-items)
(update-selection text-input-handle selection-start selection-end))})
(def first-level-menu-items (map i18n/label (keys first-level-menus)))
(defn reset-to-first-level-menu
[first-level menu-items]
(reset! first-level true)
(reset! menu-items first-level-menu-items))
(defn append-markdown-char
[{:keys [first-level menu-items content selection-start selection-end text-input-handle
selection-event]
:as params} wrap-chars]
(let [content (str wrap-chars content wrap-chars)
new-text (calculate-input-text params content)
len-wrap-chars (count wrap-chars)
selection-start (+ selection-start len-wrap-chars)
selection-end (+ selection-end len-wrap-chars)]
;don't update selection directly here, process it within on-selection-change instead
;so that we can avoid java.lang.IndexOutOfBoundsException: setSpan..
(reset! selection-event {:start selection-start
:end selection-end
:text-input-handle text-input-handle})
(update-input-text params new-text)
(reset-to-first-level-menu first-level menu-items)))
(def second-level-menus
{:bold #(append-markdown-char % "**")
:italic #(append-markdown-char % "*")
:strikethrough #(append-markdown-char % "~~")})
(def second-level-menu-items (map i18n/label (keys second-level-menus)))
(defn on-menu-item-touched
[{:keys [first-level event-type] :as params}]
(let [menus (if @first-level first-level-menus second-level-menus)
menu-item-key (nth (keys menus) event-type)
action (get menus menu-item-key)]
(action params)))
(defn selectable-text-input
[_ _ _]
(let [text-input-ref (reagent/atom nil)
menu-items (reagent/atom first-level-menu-items)
first-level (reagent/atom true)
selection-event (atom nil)
manager (rn/selectable-text-input-manager)]
(reagent/create-class
{:component-did-mount
(fn [this]
(when @text-input-ref
(let [selectable-text-input-handle (rn/find-node-handle this)
text-input-handle (rn/find-node-handle @text-input-ref)]
(oops/ocall manager :setupMenuItems selectable-text-input-handle text-input-handle))))
:component-did-update (fn [_ _ _ _]
(when (not @first-level)
(let [text-input-handle (rn/find-node-handle @text-input-ref)]
(oops/ocall manager :startActionMode text-input-handle))))
:reagent-render
(fn [chat-id {:keys [style ref on-selection-change] :as props} children]
(let [ref #(do (reset! text-input-ref %)
(when ref
(quo.react/set-ref-val! ref %)))
on-selection-change (fn [args]
(let [selection (.-selection ^js (.-nativeEvent ^js args))
start (.-start selection)
end (.-end selection)
no-selection (<= (- end start) 0)]
(when (and no-selection (not @first-level))
(oops/ocall manager :hideLastActionMode)
(reset-to-first-level-menu first-level menu-items)))
(when on-selection-change
(on-selection-change args))
(when @selection-event
(let [{:keys [start end text-input-handle]} @selection-event]
(update-selection text-input-handle start end)
(reset! selection-event nil))))
on-selection
(fn [^js event]
(let [native-event (.-nativeEvent event)
native-event (transforms/js->clj native-event)
{:keys [eventType content selectionStart
selectionEnd]} native-event
full-text (:input-text (rf/sub [:chats/current-chat-input]))]
(on-menu-item-touched {:first-level first-level
:event-type eventType
:content content
:selection-start selectionStart
:selection-end selectionEnd
:text-input @text-input-ref
:text-input-handle (rn/find-node-handle @text-input-ref)
:full-text full-text
:menu-items menu-items
:chat-id chat-id
:selection-event selection-event})))
props (merge props
{:ref ref
:style (dissoc style :margin-horizontal)
:on-selection-change on-selection-change
:on-selection on-selection})]
[rn/selectable-text-input {:menuItems @menu-items :style style}
[rn/text-input props
children]]))})))
@@ -1,2 +0,0 @@
(ns status-im.ui2.screens.chat.composer.mentions)
@@ -1,37 +0,0 @@
(ns status-im.ui2.screens.chat.composer.reply
(:require [quo.react-native :as rn]
[status-im.ui2.screens.chat.components.reply.view :as reply]
[status-im.ui2.screens.chat.composer.input :as input]))
(defn focus-input-on-reply
[reply had-reply text-input-ref]
;;when we show reply we focus input
(when-not (= reply @had-reply)
(reset! had-reply reply)
(when reply
;; A setTimeout of 0 is necessary to ensure the statement is enqueued and will get executed ASAP.
(js/setTimeout #(input/input-focus text-input-ref) 0))))
(defn reply-message-auto-focus-wrapper
[text-input-ref _]
(let [had-reply (atom nil)]
(fn [_ reply]
(focus-input-on-reply reply had-reply text-input-ref)
(when reply
[rn/view
{:style (merge
{:padding-horizontal 15
:padding-vertical 8}
(when @input/recording-audio?
{:position :absolute
:top 12
:left 0
:right 0
;;When recording an audio and replying at the same time,
;;text input is overlapped by the reply component but
;;text input still have priority over touches, so we need
;;to force the reply component to receive the touches in this
;;scenario, thus we increase its z-index
:z-index 1}))}
[reply/reply-message reply true false
(and @input/recording-audio? (not @input/reviewing-audio?))]]))))
@@ -18,7 +18,6 @@
[status-im.ui.screens.chat.styles.message.message :as style]
[status-im.ui.screens.chat.utils :as chat.utils]
[status-im.ui.screens.communities.icon :as communities.icon]
[status-im.ui2.screens.chat.components.reply.view :as components.reply]
[status-im.utils.utils :as utils]
[status-im2.constants :as constants]
[status-im2.contexts.chat.home.chat-list-item.view :as home.chat-list-item]
@@ -144,9 +143,8 @@
(:parsed-text content))))
(defn quoted-message
[quoted-message pin?]
[rn/view {:style (when-not pin? (style/quoted-message-container))}
[components.reply/reply-message quoted-message false pin?]])
[_ pin?]
[rn/view {:style (when-not pin? (style/quoted-message-container))}])
(defn message-not-sent-text
[chat-id message-id]
@@ -3,12 +3,10 @@
[re-frame.core :as re-frame]
[status-im.router.core :as router]
[status-im.utils.gfycat.core :as gfycat]
[status-im.utils.identicon :as identicon]
[status-im.utils.universal-links.core :as links]))
(deftest handle-url-test
(with-redefs [gfycat/generate-gfy (constantly "generated")
identicon/identicon (constantly "generated")]
(with-redefs [gfycat/generate-gfy (constantly "generated")]
(testing "the user is not logged in"
(testing "it stores the url for later processing"
(is (= {:db {:universal-links/url "some-url"}}
@@ -30,19 +30,19 @@
close-button-text]}]
(let [extra-action-selected? (reagent/atom false)]
(fn []
(let [{:keys [group-chat chat-id public-key color profile-picture
name]} context
id (or chat-id public-key)
display-name (or
name
(when-not group-chat
(rf/sub [:contacts/contact-name-by-identity id])))
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address
id]))
photo-path (or profile-picture
(when-not (empty? (:images contact))
(rf/sub [:chats/photo-path id])))]
(let [{:keys [group-chat chat-id public-key color
profile-picture name]} context
id (or chat-id public-key)
display-name (or
name
(when-not group-chat
(rf/sub [:contacts/contact-name-by-identity id])))
contact (when-not group-chat
(rf/sub [:contacts/contact-by-address
id]))
photo-path (or profile-picture
(when-not (empty? (:images contact))
(rf/sub [:chats/photo-path id])))]
[rn/view
{:style {:margin-horizontal 20}
:accessibility-label accessibility-label}
+14 -9
View File
@@ -1,15 +1,20 @@
(ns status-im2.common.resources)
(def ui
{:add-new-contact (js/require "../resources/images/ui2/add-contact.png")
:lifestyle (js/require "../resources/images/ui2/lifestyle.png")
:music (js/require "../resources/images/ui2/music.png")
:podcasts (js/require "../resources/images/ui2/podcasts.png")
:generate-keys (js/require "../resources/images/ui2/generate-keys.png")
:ethereum-address (js/require "../resources/images/ui2/ethereum-address.png")
:use-keycard (js/require "../resources/images/ui2/keycard.png")
:onboarding-illustration (js/require "../resources/images/ui2/onboarding_illustration.png")
:qr-code (js/require "../resources/images/ui2/qr-code.png")
{:add-new-contact (js/require "../resources/images/ui2/add-contact.png")
:desktop-how-to-pair-sign-in (js/require "../resources/images/ui2/desktop-how-to-pair-sign-in.png")
:desktop-how-to-pair-logged-in (js/require
"../resources/images/ui2/desktop-how-to-pair-logged-in.png")
:mobile-how-to-pair-sign-in (js/require "../resources/images/ui2/mobile-how-to-pair-sign-in.png")
:mobile-how-to-pair-logged-in (js/require "../resources/images/ui2/mobile-how-to-pair-logged-in.png")
:lifestyle (js/require "../resources/images/ui2/lifestyle.png")
:music (js/require "../resources/images/ui2/music.png")
:podcasts (js/require "../resources/images/ui2/podcasts.png")
:generate-keys (js/require "../resources/images/ui2/generate-keys.png")
:ethereum-address (js/require "../resources/images/ui2/ethereum-address.png")
:use-keycard (js/require "../resources/images/ui2/keycard.png")
:onboarding-illustration (js/require "../resources/images/ui2/onboarding_illustration.png")
:qr-code (js/require "../resources/images/ui2/qr-code.png")
})
(def mock-images
-2
View File
@@ -158,5 +158,3 @@
["enrtree://AOGECG2SPND25EEFMAJ5WF3KSGJNSGV356DSTL2YVLLZWIV6SAYBM@test.waku.nodes.status.im"]})
(def default-kdf-iterations 3200)
(def ^:const new-composer-enabled? false)
-1
View File
@@ -263,7 +263,6 @@
2 5000
3 10000})
(def ^:const max-text-size 4096)
;; any message that comes after this amount of ms will be grouped separately
(def ^:const group-ms 300000)
@@ -17,14 +17,14 @@
(defn user-avatar-tag
[user-id]
(let [contact (rf/sub [:contacts/contact-by-identity user-id])]
(let [{:keys [primary-name] :as contact} (rf/sub [:contacts/contact-by-identity user-id])]
[quo/user-avatar-tag
{:color :purple
:override-theme :dark
:size :small
:style style/user-avatar-tag
:text-style style/user-avatar-tag-text}
(:primary-name contact)
primary-name
(multiaccounts/displayed-photo contact)]))
(defn- render-swipe-action
@@ -5,6 +5,7 @@
[react-native.core :as rn]
[react-native.clipboard :as clipboard]
[reagent.core :as reagent]
[status-im.multiaccounts.core :as multiaccounts]
[status-im.qr-scanner.core :as qr-scanner]
[status-im.utils.utils :as utils]
[status-im2.contexts.add-new-contact.style :as style]
@@ -14,12 +15,8 @@
(defn found-contact
[public-key]
(let [{:keys [primary-name
compressed-key
identicon
images]} (rf/sub [:contacts/contact-by-identity public-key])
profile-picture (-> (or (:thumbnail images) (:large images) (first images))
(get :uri identicon))]
(let [{:keys [primary-name compressed-key]
:as contact} (rf/sub [:contacts/contact-by-identity public-key])]
(when primary-name
[rn/view style/found-user
[quo/text (style/text-description)
@@ -27,7 +24,7 @@
[rn/view (style/found-user-container)
[quo/user-avatar
{:full-name primary-name
:profile-picture profile-picture
:profile-picture (multiaccounts/displayed-photo contact)
:size :small
:status-indicator? false}]
[rn/view style/found-user-text
@@ -1,122 +0,0 @@
(ns status-im2.contexts.chat.bottom-sheet-composer.effects
(:require
[status-im.async-storage.core :as async-storage]
[react-native.core :as rn]
[react-native.reanimated :as reanimated]
[status-im2.contexts.chat.bottom-sheet-composer.constants :as constants]
[status-im2.contexts.chat.bottom-sheet-composer.keyboard :as kb]
[utils.number :as utils.number]))
(defn reenter-screen-effect
[{:keys [text-value saved-cursor-position maximized?]}
{:keys [content-height]}
{:keys [input-content-height input-text input-maximized?]}]
(when (and (empty? @text-value) (not= input-text nil))
(reset! text-value input-text)
(reset! content-height input-content-height)
(reset! saved-cursor-position (count input-text)))
(when input-maximized?
(reset! maximized? true)))
(defn maximized-effect
[{:keys [maximized?]}
{:keys [height saved-height last-height]}
{:keys [max-height]}
{:keys [input-content-height]}]
(when (or @maximized? (>= input-content-height max-height))
(reanimated/animate height max-height)
(reanimated/set-shared-value saved-height max-height)
(reanimated/set-shared-value last-height max-height)))
(defn layout-effect
[{:keys [lock-layout?]}]
(when-not @lock-layout?
(js/setTimeout #(reset! lock-layout? true) 500)))
(defn kb-default-height-effect
[{:keys [kb-default-height]}]
(when-not @kb-default-height
(async-storage/get-item :kb-default-height
#(reset! kb-default-height (utils.number/parse-int % nil)))))
(defn background-effect
[{:keys [maximized?]}
{:keys [opacity background-y]}
{:keys [max-height]}
{:keys [input-content-height]}]
(when (or @maximized? (>= input-content-height (* max-height constants/background-threshold)))
(reanimated/set-shared-value background-y 0)
(reanimated/animate opacity 1)))
(defn images-or-reply-effect
[{:keys [container-opacity]}
{:keys [replying? sending-images? input-ref]}
images? reply?]
(when (or images? reply?)
(reanimated/animate container-opacity 1))
(when (and (not @sending-images?) images? @input-ref)
(.focus ^js @input-ref)
(reset! sending-images? true))
(when (and (not @replying?) reply? @input-ref)
(.focus ^js @input-ref)
(reset! replying? true))
(when-not images?
(reset! sending-images? false))
(when-not reply?
(reset! replying? false)))
(defn edit-effect
[{:keys [text-value saved-cursor-position]}
{:keys [editing? input-ref]}
edit]
(let [edit-text (get-in edit [:content :text])]
(when (and (not @editing?) edit @input-ref)
(.focus ^js @input-ref)
(reset! editing? true)
(reset! text-value edit-text)
(reset! saved-cursor-position (count edit-text)))
(when-not edit-text
(reset! editing? false))))
(defn audio-effect
[{:keys [recording? gesture-enabled?]}
{:keys [container-opacity]}
audio]
(when (and audio (not @recording?))
(reset! recording? true)
(reset! gesture-enabled? false)
(reanimated/animate container-opacity 1)))
(defn empty-effect
[{:keys [text-value maximized? focused?]}
{:keys [container-opacity]}
images?
reply?
audio]
(when
(and (empty? @text-value) (not images?) (not reply?) (not @maximized?) (not @focused?) (not audio))
(reanimated/animate-delay container-opacity constants/empty-opacity 200)))
(defn component-will-unmount
[{:keys [keyboard-show-listener keyboard-hide-listener keyboard-frame-listener]}]
(.remove ^js @keyboard-show-listener)
(.remove ^js @keyboard-hide-listener)
(.remove ^js @keyboard-frame-listener))
(defn initialize
[props state animations {:keys [max-height] :as dimensions} chat-input keyboard-height images? reply?
edit audio]
(rn/use-effect
(fn []
(maximized-effect state animations dimensions chat-input)
(reenter-screen-effect state dimensions chat-input)
(layout-effect state)
(kb-default-height-effect state)
(background-effect state animations dimensions chat-input)
(images-or-reply-effect animations props images? reply?)
(edit-effect state props edit)
(audio-effect state animations audio)
(empty-effect state animations images? reply? audio)
(kb/add-kb-listeners props state animations dimensions keyboard-height)
#(component-will-unmount props))
[max-height]))

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