Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b00f0971bc | ||
|
|
a6fdc9b118 | ||
|
|
4d1ff17ba1 | ||
|
|
8a02803d9f | ||
|
|
f9ee7e0559 | ||
|
|
978540d5b7 | ||
|
|
3c02518d4a | ||
|
|
7bafb3d82b | ||
|
|
59d1383177 | ||
|
|
5fb48949ae | ||
|
|
78e9102264 | ||
|
|
2b2170dfff | ||
|
|
ab94f9b017 | ||
|
|
1f5047eea7 | ||
|
|
e6e77e4a58 | ||
|
|
22d9c14ae6 | ||
|
|
84bbfe8f9d |
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
/* 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: 15, unit: 'MINUTES')
|
||||
timeout(time: 10, unit: 'MINUTES')
|
||||
/* Limit builds retained */
|
||||
buildDiscarder(logRotator(
|
||||
numToKeepStr: '10',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
library 'status-jenkins-lib@v1.7.3'
|
||||
library 'status-jenkins-lib@v1.7.2'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
[Working on PR together with QA team](pipeline_process.md)
|
||||
|
||||
[Debugging](debugging.md)
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
@@ -91,11 +91,30 @@ 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:
|
||||
|
||||

|
||||
|
||||
## 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).
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
# 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.
|
||||
|
||||

|
||||
|
||||
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:
|
||||
|
||||

|
||||
|
||||
|
||||
## 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".
|
||||
|
||||

|
||||
|
||||
|
||||
### 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)
|
||||
|
||||

|
||||
|
||||
|
||||
## 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'
|
||||
```
|
||||
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 255 KiB |
|
Before Width: | Height: | Size: 308 KiB |
|
Before Width: | Height: | Size: 16 KiB |
@@ -234,7 +234,7 @@ PODS:
|
||||
- React
|
||||
- react-native-blob-util (0.13.18):
|
||||
- React-Core
|
||||
- react-native-blur (4.3.3):
|
||||
- react-native-blur (4.3.2):
|
||||
- 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: c6d0a1dc2b4b519f7afe3b14d8151998632b6d18
|
||||
react-native-blur: 4db8c7556566df4e8714c1af5762a4ebc99175d5
|
||||
react-native-camera-kit: 498a6d111a904834e0824e9073cfadef7303235f
|
||||
react-native-cameraroll: 88f4e62d9ecd0e1f253abe4f685474f2ea14bfa2
|
||||
react-native-config: 5330c8258265c1e5fdb8c009d2cabd6badd96727
|
||||
|
||||
@@ -1354,12 +1354,11 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
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 {
|
||||
public void convertToKeycardAccount(final String keyUID, final String accountData, final String options, 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, keycardUID, password, newPassword);
|
||||
return Statusgo.convertToKeycardAccount(accountData, options, password, newPassword);
|
||||
}, callback);
|
||||
}
|
||||
|
||||
|
||||
@@ -692,7 +692,6 @@ 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) {
|
||||
@@ -701,7 +700,7 @@ RCT_EXPORT_METHOD(convertToKeycardAccount:(NSString *)keyUID
|
||||
#endif
|
||||
NSURL *multiaccountKeystoreDir = [self getKeyStoreDir:keyUID];
|
||||
StatusgoInitKeystore(multiaccountKeystoreDir.path);
|
||||
NSString *result = StatusgoConvertToKeycardAccount(accountData, settings, keycardUID, currentPassword, newPassword);
|
||||
NSString *result = StatusgoConvertToKeycardAccount(accountData, settings, currentPassword, newPassword);
|
||||
callback(@[result]);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.3
|
||||
com.github.Dimezis:BlurView:version-2.0.2
|
||||
com.github.bumptech.glide:annotations:4.12.0
|
||||
com.github.bumptech.glide:compiler:4.12.0
|
||||
com.github.bumptech.glide:disklrucache:4.12.0
|
||||
|
||||
@@ -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.3/BlurView-version-2.0.3.pom
|
||||
https://jitpack.io/com/github/Dimezis/BlurView/version-2.0.2/BlurView-version-2.0.2.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.19.0/error_prone_annotations-2.19.0.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_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.19.0/error_prone_parent-2.19.0.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/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
|
||||
|
||||
@@ -14,12 +14,12 @@ declare -a REPOS=(
|
||||
"https://jitpack.io"
|
||||
)
|
||||
|
||||
function nix_prefetch() {
|
||||
nix store prefetch-file --json "${1}" 2>/dev/null
|
||||
function nix_fetch() {
|
||||
nix-prefetch-url --print-path --type sha256 "${1}" 2>/dev/null
|
||||
}
|
||||
|
||||
function get_nix_path() { echo "${1}" | jq -r .storePath; }
|
||||
function get_nix_sha() { echo "${1}" | jq -r .hash; }
|
||||
function get_nix_path() { echo "${1}" | tail -n1; }
|
||||
function get_nix_sha() { echo "${1}" | head -n1; }
|
||||
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_prefetch "${OBJ_URL}"); then
|
||||
if ! OBJ_NIX_FETCH_OUT=$(nix_fetch "${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_prefetch "${PKG_URL_NO_EXT}.pom")
|
||||
POM_NIX_FETCH_OUT=$(nix_fetch "${PKG_URL_NO_EXT}.pom")
|
||||
POM_PATH=$(get_nix_path "${POM_NIX_FETCH_OUT}")
|
||||
POM_NAME=$(basename "${PKG_URL_NO_EXT}.pom")
|
||||
if [[ -z "${POM_PATH}" ]]; then
|
||||
|
||||
@@ -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.3-status",
|
||||
"@react-native-community/blur": "git+https://github.com/status-im/react-native-blur#refs/tags/v4.3.2-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",
|
||||
|
||||
|
Before Width: | Height: | Size: 64 KiB |
|
Before Width: | Height: | Size: 112 KiB |
|
Before Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 103 KiB |
|
Before Width: | Height: | Size: 274 KiB |
|
Before Width: | Height: | Size: 552 KiB |
|
Before Width: | Height: | Size: 288 KiB |
|
Before Width: | Height: | Size: 587 KiB |
@@ -39,22 +39,9 @@ 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.
|
||||
for SECRET_VAR_NAME in "${SECRETS_ENV_VARS[@]}"; do
|
||||
[[ -n "${!SECRET_VAR_NAME}" ]] && append_env_export "${SECRET_VAR_NAME}"
|
||||
done
|
||||
if [[ -n "${POKT_TOKEN}" ]]; then append_env_export 'POKT_TOKEN'; fi
|
||||
if [[ -n "${OPENSEA_API_KEY}" ]]; then append_env_export 'OPENSEA_API_KEY'; fi
|
||||
|
||||
# If no secrets were passed there's no need to pass the 'secretsFile'.
|
||||
if [[ -s "${SECRETS_FILE_PATH}" ]]; then
|
||||
|
||||
@@ -513,7 +513,6 @@
|
||||
key-uid
|
||||
(types/clj->json multiaccount-data)
|
||||
(types/clj->json settings)
|
||||
""
|
||||
current-password#
|
||||
new-password
|
||||
callback))
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
(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")))))
|
||||
@@ -11,7 +11,7 @@
|
||||
(defn neutral-border-color
|
||||
[in-blur-view? override-theme]
|
||||
(if in-blur-view?
|
||||
(colors/theme-colors colors/neutral-80-opa-5 colors/white-opa-10 override-theme)
|
||||
(colors/theme-colors colors/white-opa-10 colors/neutral-80-opa-5 override-theme)
|
||||
(colors/theme-colors colors/neutral-20 colors/neutral-80 override-theme)))
|
||||
|
||||
(def active-background-color (colors/custom-color :blue 50 10))
|
||||
|
||||
@@ -1,59 +1,8 @@
|
||||
(ns quo2.components.inputs.recovery-phrase.component-spec
|
||||
(:require [clojure.string :as string]
|
||||
[oops.core :as oops]
|
||||
[quo2.components.inputs.recovery-phrase.view :as recovery-phrase]
|
||||
(:require [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/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")))))
|
||||
(h/is-truthy (h/get-by-label-text :recovery-phrase-input))))
|
||||
|
||||
@@ -31,8 +31,7 @@
|
||||
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
|
||||
error-pred (constantly false)}
|
||||
:or {customization-color :blue}
|
||||
:as props}
|
||||
text]
|
||||
(let [extra-props (apply dissoc props custom-props)]
|
||||
|
||||
@@ -173,7 +173,6 @@
|
||||
reached-max-duration? (atom false)
|
||||
touch-timestamp (atom nil)
|
||||
disabled? (atom false)
|
||||
app-state-listener (atom nil)
|
||||
rec-options
|
||||
(merge
|
||||
audio/default-recorder-options
|
||||
@@ -513,13 +512,7 @@
|
||||
(on-init reset-recorder))
|
||||
(when audio-file
|
||||
(let [filename (last (string/split audio-file "/"))]
|
||||
(reload-player filename)))
|
||||
(reset! app-state-listener
|
||||
(.addEventListener rn/app-state
|
||||
"change"
|
||||
#(when (= % "background")
|
||||
(reset! playing-audio? false))))
|
||||
#(.remove @app-state-listener)))
|
||||
(reload-player filename)))))
|
||||
[rn/view
|
||||
{:style style/bar-container
|
||||
:pointer-events :box-none}
|
||||
|
||||
@@ -12,6 +12,12 @@
|
||||
(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,6 +1,5 @@
|
||||
(ns quo2.components.tags.context-tag.view
|
||||
(:require [quo2.components.avatars.user-avatar.view :as user-avatar]
|
||||
[quo2.components.avatars.group-avatar :as group-avatar]
|
||||
(:require [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]
|
||||
@@ -44,11 +43,9 @@
|
||||
:size :paragraph-2
|
||||
:style (assoc text-style :justify-content :center)}]
|
||||
[base-tag (assoc-in params [:style :padding-left] 3)
|
||||
[user-avatar/user-avatar
|
||||
{:full-name name
|
||||
:profile-picture photo
|
||||
:size :xxs
|
||||
:status-indicator? false}]
|
||||
[rn/image
|
||||
{:style style/context-tag-image
|
||||
:source photo}]
|
||||
[rn/view {:style style/context-tag-text-container}
|
||||
[text/text text-params (str " " name)]
|
||||
(when channel-name
|
||||
@@ -61,7 +58,7 @@
|
||||
|
||||
(defn user-avatar-tag
|
||||
[params username photo]
|
||||
[context-tag params photo username])
|
||||
[context-tag params {:uri photo} username])
|
||||
|
||||
(defn audio-tag
|
||||
[duration params]
|
||||
|
||||
@@ -130,11 +130,6 @@
|
||||
(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))
|
||||
|
||||
@@ -70,12 +70,13 @@
|
||||
[{: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_chatMentionSelectMention"
|
||||
params [chat-id text primary-name public-key]]
|
||||
method "wakuext_chatMentionNewInputTextWithMention"
|
||||
params [chat-id text primary-name]]
|
||||
{:json-rpc/call [{:method method
|
||||
:params params
|
||||
:on-success #(rf/dispatch [:mention/on-select-mention-success %
|
||||
primary-name match searched-text public-key])
|
||||
:on-success #(rf/dispatch [:mention/on-new-input-text-with-mentions-success %
|
||||
primary-name text-input-ref match searched-text
|
||||
public-key])
|
||||
:on-error #(rf/dispatch [:mention/on-error
|
||||
{:method method
|
||||
:params params} %])}]}))
|
||||
@@ -249,21 +250,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_chatMentionReplaceWithPublicKey"
|
||||
method "wakuext_chatMentionCheckMentions"
|
||||
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-replace-with-public-key-success
|
||||
:on-success #(rf/dispatch [:mention/on-check-mentions-success
|
||||
current-chat-id
|
||||
editing-message
|
||||
input-text
|
||||
%])}]}))
|
||||
|
||||
(rf/defn on-replace-with-public-key-success
|
||||
{:events [:mention/on-replace-with-public-key-success]}
|
||||
(rf/defn on-check-mentions-success
|
||||
{:events [:mention/on-check-mentions-success]}
|
||||
[{:keys [db] :as cofx} current-chat-id editing-message input-text new-text]
|
||||
(log/debug "[mentions] on-replace-with-public-key-success"
|
||||
(log/debug "[mentions] on-check-mentions-success"
|
||||
{:chat-id current-chat-id
|
||||
:editing-message editing-message
|
||||
:input-text input-text
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
(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]
|
||||
[utils.re-frame :as rf]
|
||||
[taoensso.timbre :as log]))
|
||||
[taoensso.timbre :as log]
|
||||
[native-module.core :as native-module]))
|
||||
|
||||
(defn- transfer-input-segments
|
||||
[segments]
|
||||
@@ -122,21 +126,47 @@
|
||||
(assoc-in [:chats/mentions chat-id :mentions] state)
|
||||
(assoc-in [:chat/inputs-with-mentions chat-id] input-segments))}))
|
||||
|
||||
(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"
|
||||
(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"
|
||||
{:result result
|
||||
:primary-name primary-name
|
||||
:match match
|
||||
:searched-text searched-text
|
||||
:public-key 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]}))
|
||||
(let [{:keys [new-text chat-id]} (transfer-mention-result result)]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (assoc-in db [:chats/mention-suggestions chat-id] nil)
|
||||
:dispatch [:chat.ui/set-chat-input-text new-text chat-id]}
|
||||
(recheck-at-idxs public-key))))
|
||||
|
||||
(rf/defn clear-suggestions
|
||||
[{:keys [db]}]
|
||||
@@ -159,3 +189,38 @@
|
||||
: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,6 +20,7 @@
|
||||
:clock clock-value
|
||||
:alias "alias"
|
||||
:name "name"
|
||||
:identicon "identicon"
|
||||
:from "from"}]
|
||||
;; <- cursor
|
||||
;; <- message
|
||||
@@ -106,6 +107,7 @@
|
||||
:clock (- clock-value 2)
|
||||
:alias "alias"
|
||||
:name "name"
|
||||
:identicon "identicon"
|
||||
:from "from"}
|
||||
result (dissoc (message/receive-many
|
||||
cofx
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
[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.gfycat.core :as gfycat]
|
||||
[status-im.utils.identicon :as identicon]))
|
||||
|
||||
(defn public-key->new-contact
|
||||
[public-key]
|
||||
@@ -11,6 +12,7 @@
|
||||
{:alias alias
|
||||
:name alias
|
||||
:primary-name alias
|
||||
:identicon (identicon/identicon public-key)
|
||||
:public-key public-key}))
|
||||
|
||||
(defn public-key-and-ens-name->new-contact
|
||||
@@ -57,7 +59,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 :images])
|
||||
(select-keys [:name :preferred-name :public-key :identicon :images])
|
||||
(set/rename-keys {:name :alias :preferred-name :name})
|
||||
(assoc :primary-name (or preferred-name name)))
|
||||
all-contacts (cond-> contacts
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
(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.gfycat.core :as gfycat]
|
||||
[status-im.utils.identicon :as identicon]))
|
||||
|
||||
(deftest contacts-subs
|
||||
(testing "get-all-contacts-in-group-chat"
|
||||
(with-redefs [gfycat/generate-gfy (constantly "generated")]
|
||||
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
||||
identicon/identicon (constantly "generated")]
|
||||
(let
|
||||
[chat-contact-ids
|
||||
#{"0x04fcf40c526b09ff9fb22f4a5dbd08490ef9b64af700870f8a0ba2133f4251d5607ed83cd9047b8c2796576bc83fa0de23a13a4dced07654b8ff137fe744047917"
|
||||
@@ -19,6 +21,7 @@
|
||||
{:last-updated 0
|
||||
:name "User B"
|
||||
:primary-name "User B"
|
||||
:identicon "photo1"
|
||||
:last-online 0
|
||||
:public-key
|
||||
"0x04985040682b77a32bb4bb58268a0719bd24ca4d07c255153fe1eb2ccd5883669627bd1a092d7cc76e8e4b9104327667b19dcda3ac469f572efabe588c38c1985f"}}
|
||||
@@ -28,6 +31,7 @@
|
||||
:sharing-usage-data? false
|
||||
:primary-name "User A"
|
||||
:name "User A"
|
||||
:identicon "photo2"
|
||||
:public-key
|
||||
"0x048a2f8b80c60f89a91b4c1316e56f75b087f446e7b8701ceca06a40142d8efe1f5aa36bd0fee9e248060a8d5207b43ae98bef4617c18c71e66f920f324869c09f"}]
|
||||
(is
|
||||
@@ -38,17 +42,20 @@
|
||||
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"}]))))))
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
:emoji (.-emoji chat)
|
||||
:timestamp (.-timestamp chat)
|
||||
:alias (.-alias chat)
|
||||
:identicon (.-identicon chat)
|
||||
:muted (.-muted chat)
|
||||
:joined (.-joined chat)
|
||||
:muted-till (.-mutetill chat)
|
||||
|
||||
@@ -62,8 +62,7 @@
|
||||
[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.communities.home.events))
|
||||
status-im2.contexts.chat.home.events))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:dismiss-keyboard
|
||||
@@ -109,6 +108,11 @@
|
||||
[_]
|
||||
{: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]
|
||||
|
||||
@@ -339,10 +339,11 @@
|
||||
(let [{:keys [key-uid encryption-public-key whisper-private-key]
|
||||
:as account-data}
|
||||
(js->clj data :keywordize-keys true)
|
||||
{:keys [name]} (get-in db [:multiaccounts/multiaccounts key-uid])
|
||||
{:keys [identicon 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})
|
||||
multiaccount-data (types/clj->json {:name name
|
||||
:key-uid key-uid
|
||||
:identicon identicon})
|
||||
save-keys? (get-in db [:multiaccounts/login :save-password?])]
|
||||
(rf/merge cofx
|
||||
{:db
|
||||
@@ -359,6 +360,7 @@
|
||||
(update :multiaccounts/login assoc
|
||||
:password encryption-public-key
|
||||
:key-uid key-uid
|
||||
:identicon identicon
|
||||
:name name))
|
||||
|
||||
:keycard/login-with-keycard {:multiaccount-data multiaccount-data
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
(.remove listener)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:keycard/generate-name
|
||||
:keycard/generate-name-and-photo
|
||||
(fn [{:keys [public-key on-success]}]
|
||||
(native-module/gfycat-identicon-async
|
||||
public-key
|
||||
|
||||
@@ -151,12 +151,13 @@
|
||||
:multiaccounts-stack
|
||||
[:multiaccounts
|
||||
:keycard-login-pin])
|
||||
(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}]
|
||||
(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}]
|
||||
{:db
|
||||
(-> db
|
||||
(assoc-in [:keycard :pin :status] nil)
|
||||
@@ -167,6 +168,7 @@
|
||||
(update :multiaccounts/login assoc
|
||||
:password encryption-public-key
|
||||
:key-uid key-uid
|
||||
:identicon identicon
|
||||
:name name
|
||||
:save-password? true))
|
||||
:keycard/login-with-keycard
|
||||
|
||||
@@ -160,6 +160,7 @@
|
||||
(let [{{:keys [multiaccount secrets flow]} :keycard} db
|
||||
{:keys [address
|
||||
name
|
||||
identicon
|
||||
public-key
|
||||
whisper-public-key
|
||||
wallet-public-key
|
||||
@@ -174,17 +175,18 @@
|
||||
recovered]}
|
||||
multiaccount
|
||||
{:keys [pairing paired-on]} secrets
|
||||
{:keys [name]}
|
||||
{:keys [name identicon]}
|
||||
(if (nil? name)
|
||||
;; name might have been generated during recovery via passphrase
|
||||
(get-in db [:intro-wizard :derived constants/path-whisper-keyword])
|
||||
{:name name})]
|
||||
{:name name
|
||||
:identicon identicon})]
|
||||
;; 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
|
||||
{:keycard/generate-name-and-photo
|
||||
{:public-key whisper-public-key
|
||||
:on-success ::on-name-generated}}
|
||||
:on-success ::on-name-and-photo-generated}}
|
||||
(rf/merge cofx
|
||||
{:db (-> db
|
||||
(assoc-in [:keycard :setup-step] nil)
|
||||
@@ -197,7 +199,8 @@
|
||||
constants/path-whisper-keyword
|
||||
{:public-key whisper-public-key
|
||||
:address (eip55/address->checksum whisper-address)
|
||||
:name name}
|
||||
:name name
|
||||
:identicon identicon}
|
||||
constants/path-default-wallet-keyword
|
||||
{:public-key wallet-public-key
|
||||
:address (eip55/address->checksum wallet-address)}}
|
||||
@@ -379,11 +382,11 @@
|
||||
{:on-card-connected :keycard/load-recovering-key-screen
|
||||
:handler (common/dispatch-event :keycard/import-multiaccount)}))
|
||||
|
||||
(rf/defn on-name-generated
|
||||
{:events [::on-name-generated]
|
||||
(rf/defn on-name-and-photo-generated
|
||||
{:events [::on-name-and-photo-generated]
|
||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)
|
||||
(re-frame/inject-cofx ::multiaccounts.create/get-signing-phrase)]}
|
||||
[{:keys [db] :as cofx} whisper-name]
|
||||
[{:keys [db] :as cofx} whisper-name identicon]
|
||||
(rf/merge
|
||||
cofx
|
||||
{:db (update-in db
|
||||
@@ -391,5 +394,6 @@
|
||||
(fn [multiacc]
|
||||
(assoc multiacc
|
||||
:recovered (get db :recovered-account?)
|
||||
:name whisper-name)))}
|
||||
:name whisper-name
|
||||
:identicon identicon)))}
|
||||
(create-keycard-multiaccount)))
|
||||
|
||||
@@ -268,9 +268,12 @@
|
||||
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
|
||||
(native-module/gfycat-identicon-async
|
||||
public-key
|
||||
(fn [name _]
|
||||
(fn [name photo-path]
|
||||
(let [derived-data-extended
|
||||
(update derived-data constants/path-whisper-keyword assoc :name name)]
|
||||
(update derived-data
|
||||
constants/path-whisper-keyword
|
||||
merge
|
||||
{:name name :identicon photo-path})]
|
||||
(reset! derived-acc
|
||||
{:root-key root-data
|
||||
:derived derived-data-extended})))))))))))
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
[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]
|
||||
@@ -47,11 +48,23 @@
|
||||
(gfycat/generate-gfy identity))]
|
||||
[(:primary-name contact) (:secondary-name contact)])))
|
||||
|
||||
(def photo-quality-thumbnail :thumbnail)
|
||||
(def photo-quality-large :large)
|
||||
|
||||
(defn displayed-photo
|
||||
[{:keys [images]}]
|
||||
(or (:thumbnail images)
|
||||
(:large images)
|
||||
(first images)))
|
||||
"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)))
|
||||
|
||||
(re-frame/reg-fx
|
||||
::webview-debug-changed
|
||||
|
||||
@@ -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 _]
|
||||
(fn [name identicon]
|
||||
(let [derived-whisper (derived-data constants/path-whisper-keyword)
|
||||
derived-data-extended (assoc-in derived-data
|
||||
[constants/path-whisper-keyword]
|
||||
(assoc derived-whisper :name name))]
|
||||
(merge derived-whisper {:name name :identicon identicon}))]
|
||||
(re-frame/dispatch [::store-multiaccount-success key-code derived-data-extended]))))))]}))
|
||||
|
||||
(re-frame/reg-fx
|
||||
@@ -154,12 +154,13 @@
|
||||
:wallet true
|
||||
:path constants/path-default-wallet
|
||||
:name (i18n/label :t/main-account)})
|
||||
(let [{:keys [compressed-key public-key address name]}
|
||||
(let [{:keys [compressed-key public-key address name identicon]}
|
||||
(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})])
|
||||
|
||||
@@ -173,11 +174,13 @@
|
||||
(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)
|
||||
@@ -199,6 +202,7 @@
|
||||
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
|
||||
@@ -227,6 +231,7 @@
|
||||
db (assoc db
|
||||
:multiaccounts/login {:key-uid key-uid
|
||||
:name name
|
||||
:identicon identicon
|
||||
:password password
|
||||
:creating? true
|
||||
:processing true}
|
||||
|
||||
@@ -168,23 +168,25 @@
|
||||
(rf/defn login
|
||||
{:events [:multiaccounts.login.ui/password-input-submitted]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password name]} (:multiaccounts/login db)]
|
||||
(let [{:keys [key-uid password name identicon]} (: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})
|
||||
(types/clj->json {:name name
|
||||
:key-uid key-uid
|
||||
:identicon identicon})
|
||||
(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]} (:multiaccounts/login db)]
|
||||
(let [{:keys [key-uid password name identicon]} (:multiaccounts/login db)]
|
||||
{::export-db [key-uid
|
||||
(types/clj->json {:name name
|
||||
:key-uid key-uid})
|
||||
(types/clj->json {:name name
|
||||
:key-uid key-uid
|
||||
:identicon identicon})
|
||||
(ethereum/sha3 (security/safe-unmask-data password))
|
||||
(fn [path]
|
||||
(when platform/ios?
|
||||
@@ -196,10 +198,11 @@
|
||||
(rf/defn import-db-submitted
|
||||
{:events [:multiaccounts.login.ui/import-db-submitted]}
|
||||
[{:keys [db]}]
|
||||
(let [{:keys [key-uid password name]} (:multiaccounts/login db)]
|
||||
(let [{:keys [key-uid password name identicon]} (:multiaccounts/login db)]
|
||||
{::import-db [key-uid
|
||||
(types/clj->json {:name name
|
||||
:key-uid key-uid})
|
||||
(types/clj->json {:name name
|
||||
:key-uid key-uid
|
||||
:identicon identicon})
|
||||
(ethereum/sha3 (security/safe-unmask-data password))]}))
|
||||
|
||||
(rf/defn finish-keycard-setup
|
||||
@@ -739,8 +742,7 @@
|
||||
(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 :images :customization-color])))))
|
||||
(open-login (select-keys multiaccount [:key-uid :name :public-key :identicon :images])))))
|
||||
|
||||
(rf/defn hide-keycard-banner
|
||||
{:events [:hide-keycard-banner]}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
:tags #{}
|
||||
:address "2f88d65f3cb52605a54a833ae118fb1363acccd2"
|
||||
:name "Darkviolet Lightgreen Halcyon"
|
||||
:identicon
|
||||
"data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX///+M2KwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADdPOdBAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAY5UBARL8TK8AAAAASUVORK5CYII="
|
||||
:added? true
|
||||
:last-online 0
|
||||
:public-key
|
||||
@@ -12,6 +14,8 @@
|
||||
{:last-updated 1547271764000
|
||||
:address "b267ff8336ac10b3a1986c04a70ff91fb03d0b78"
|
||||
:name "rv"
|
||||
:identicon
|
||||
"data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX////VjNgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwYzy6AAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEBAQEBAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQEBAQEBAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAQEBAQEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEAAAAAAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQAAAAABAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA6IYA4bRtf+EAAAAASUVORK5CYII="
|
||||
:added? true
|
||||
:last-online 0
|
||||
:public-key
|
||||
@@ -97,6 +101,8 @@
|
||||
:xdai #{}}
|
||||
:preview-privacy? true
|
||||
:fleet :eth.prod
|
||||
:identicon
|
||||
"data:image/png;base64iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAMAAAC7IEhfAAADAFBMVEX////YsYwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPGFwxAAABAHRSTlP//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAKmfXxgAABnNJREFUeNoBaAaX+QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEAAAAAAQEBAQAAAAABAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQAAAAABAQEBAAAAAAEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAAAAAAEBAQEAAAAAAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQEBAQEBAQEAAAAAAQEBAQEBAQEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAQEBAQEBAQAAAAABAQEBAQEBAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAEBAQEBAQEBAAAAAAEBAQEBAQEBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAloYA4a9rBHIAAAAASUVORK5CYII="
|
||||
:wallet-set-up-passed? false
|
||||
:public-key
|
||||
"0x04173f7cdea0076a7998abb674cc79fe61337c42db77043c01d5b0f3e3ac1e5a45bca0c93bb9f3c3d38b7cc9a7337cd64f9f9b2114fe4bbdfe1ae2633ba14d8c9c"
|
||||
|
||||
@@ -10,13 +10,14 @@
|
||||
(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"}}}
|
||||
(let [cofx {:db {:multiaccounts/login {:key-uid "key-uid"
|
||||
:password "password"
|
||||
:name "user"
|
||||
:identicon "photo"}}}
|
||||
efx (login.core/login cofx)]
|
||||
(testing "Change multiaccount."
|
||||
(is (= (::login.core/login efx)
|
||||
["key-uid" "{\"name\":\"user\",\"key-uid\":\"key-uid\"}"
|
||||
["key-uid" "{\"name\":\"user\",\"key-uid\":\"key-uid\",\"identicon\":\"photo\"}"
|
||||
(ethereum/sha3 "password")])))
|
||||
(testing "start activity indicator"
|
||||
(is (= (get-in efx [:db :multiaccounts/login :processing]) true))))))
|
||||
|
||||
@@ -108,9 +108,12 @@
|
||||
public-key (get-in derived-data [constants/path-whisper-keyword :public-key])]
|
||||
(native-module/gfycat-identicon-async
|
||||
public-key
|
||||
(fn [name _]
|
||||
(fn [name identicon]
|
||||
(let [derived-data-extended
|
||||
(update derived-data constants/path-whisper-keyword assoc :name name)]
|
||||
(update derived-data
|
||||
constants/path-whisper-keyword
|
||||
merge
|
||||
{:name name :identicon identicon})]
|
||||
(re-frame/dispatch [success-event root-data derived-data-extended]))))))))))))
|
||||
|
||||
(rf/defn show-existing-multiaccount-alert
|
||||
|
||||
@@ -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]} multiaccount]
|
||||
(let [multiaccount (:multiaccount db)
|
||||
{:keys [name preferred-name identicon]} multiaccount]
|
||||
{:json-rpc/call [{:method "wakuext_syncDevices"
|
||||
:params [(or preferred-name name)]
|
||||
:params [(or preferred-name name) identicon]
|
||||
:on-success #(log/debug "successfully synced devices")}]}))
|
||||
|
||||
(defn installation<-rpc
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
;; in case of an unknown error we show the
|
||||
;; error
|
||||
(if (= error "file is not a database")
|
||||
(i18n/label :t/oops-wrong-password)
|
||||
(i18n/label :t/wrong-password)
|
||||
error)))}
|
||||
(= (:view-id db) :progress)
|
||||
(assoc :dispatch [:navigate-to :login]))
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(: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]
|
||||
@@ -48,13 +47,19 @@
|
||||
|
||||
(defn profile-photo-plus-dot-view
|
||||
[{:keys [public-key photo-container photo-path community?]}]
|
||||
(let [photo-container (if (nil? photo-container)
|
||||
(let [photo-path (if (nil? photo-path)
|
||||
@(re-frame.core/subscribe [:chats/photo-path public-key])
|
||||
photo-path)
|
||||
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)
|
||||
size
|
||||
identicon?)
|
||||
dot-accessibility-label (:accessibility-label dot-styles)]
|
||||
[rn/view
|
||||
{:style photo-container
|
||||
@@ -142,13 +147,9 @@
|
||||
[photos/photo (multiaccounts/displayed-photo contact) styles]])
|
||||
|
||||
(defn contact-icon-contacts-tab
|
||||
[{:keys [primary-name] :as contact}]
|
||||
[photo-path]
|
||||
[rn/view styles/container-chat-list
|
||||
[quo/user-avatar
|
||||
{:full-name primary-name
|
||||
:profile-picture (multiaccounts/displayed-photo contact)
|
||||
:size :small
|
||||
:status-indicator? false}]])
|
||||
[photos/photo photo-path {:size 40}]])
|
||||
|
||||
(defn dapp-icon-permission
|
||||
[contact size]
|
||||
@@ -194,10 +195,9 @@
|
||||
:public-key public-key
|
||||
:photo-container (:container styles)
|
||||
:community? community?}]
|
||||
[rn/view {:accessibility-label :chat-icon}
|
||||
(if (string/blank? emoji)
|
||||
[default-chat-icon name styles]
|
||||
[emoji-chat-icon emoji styles])])
|
||||
(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}]])]))
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
(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]))
|
||||
@@ -9,14 +11,32 @@
|
||||
(fn [photo-path size accessibility-label _]
|
||||
[react/view {:style (style/photo-container size)}
|
||||
[fast-image/fast-image
|
||||
{:source photo-path
|
||||
{:source {:uri 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}]))
|
||||
|
||||
@@ -14,12 +14,13 @@
|
||||
|
||||
(defn one-to-one-chat-accents
|
||||
[chat-id]
|
||||
(let [{:keys [primary-name] :as contact} @(re-frame/subscribe [:contacts/contact-by-identity chat-id])]
|
||||
(let [photo @(re-frame/subscribe [:chats/photo-path chat-id])
|
||||
contact-name @(re-frame/subscribe [:contacts/contact-name-by-identity chat-id])]
|
||||
[react/view
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab contact]
|
||||
:title primary-name
|
||||
:icon [chat-icon/contact-icon-contacts-tab photo]
|
||||
:title contact-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
:chevron true
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
[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]
|
||||
@@ -33,7 +34,8 @@
|
||||
[quo/list-item
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab contact]
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
:accessory :checkbox
|
||||
:active active
|
||||
:on-press (fn []
|
||||
|
||||
@@ -22,7 +22,8 @@
|
||||
[:<>
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab member]
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:title primary-name
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
{:flex-basis 120})
|
||||
:accessory (when can-manage-users?
|
||||
[request-actions community-id id])
|
||||
:icon [chat-icon/contact-icon-contacts-tab member]
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:on-press #(re-frame/dispatch [:chat.ui/show-profile public-key])}]))
|
||||
|
||||
(defn requests-to-join
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[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]
|
||||
@@ -23,7 +24,8 @@
|
||||
[quo/list-item
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:icon [chat-icon/contact-icon-contacts-tab row]}]))
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo row)]}]))
|
||||
|
||||
(defn- on-toggle
|
||||
[allow-new-users? checked? public-key]
|
||||
@@ -57,7 +59,8 @@
|
||||
[quo/list-item
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:icon [chat-icon/contact-icon-contacts-tab contact]
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
:on-press #(on-toggle allow-new-users? contact-selected? public-key)
|
||||
:active contact-selected?
|
||||
:accessory :checkbox}])))
|
||||
|
||||
@@ -205,8 +205,10 @@
|
||||
[_ _]
|
||||
(reagent/create-class
|
||||
{:should-component-update
|
||||
(fn [_ [_ _] [_ new-account]]
|
||||
(not (nil? new-account)))
|
||||
(fn [_ [_ old-account] [_ new-account]]
|
||||
(and (not (nil? new-account))
|
||||
(and (not (:identicon old-account))
|
||||
(nil? (:identicon new-account)))))
|
||||
|
||||
:reagent-render
|
||||
(fn [account small-screen?]
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[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]
|
||||
@@ -67,7 +68,8 @@
|
||||
[local-topbar (i18n/label :t/choose-actions)]
|
||||
[accordion/section
|
||||
{:title name
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab multiaccount]
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo multiaccount)]
|
||||
:content [accordion-content]}]
|
||||
[react/view
|
||||
{:flex 1
|
||||
|
||||
@@ -17,7 +17,8 @@
|
||||
(letsubs [{:keys [pubkey
|
||||
processing?
|
||||
compressed-key
|
||||
name]}
|
||||
name
|
||||
identicon]}
|
||||
[:intro-wizard/recovery-success]
|
||||
existing-account? [:intro-wizard/recover-existing-account?]]
|
||||
[react/view
|
||||
@@ -43,7 +44,14 @@
|
||||
[react/view
|
||||
{:justify-content :center
|
||||
:align-items :center
|
||||
:margin-bottom 11}]
|
||||
:margin-bottom 11}
|
||||
[react/image
|
||||
{:source {:uri identicon}
|
||||
:style {:width 61
|
||||
:height 61
|
||||
:border-radius 30
|
||||
:border-width 1
|
||||
:border-color colors/black-transparent}}]]
|
||||
[react/text
|
||||
{:style {:text-align :center
|
||||
:color colors/black
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
(i18n/label :t/delete-profile)]]
|
||||
[quo/list-item
|
||||
{:title (multiaccounts/displayed-name multiaccount)
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab multiaccount]}]
|
||||
:icon [chat-icon.screen/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo multiaccount)]}]
|
||||
(when keycard?
|
||||
[react/view
|
||||
[quo/list-header (i18n/label :t/actions)]
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
[react/view
|
||||
[quo/list-item
|
||||
{:theme :accent
|
||||
:icon [chat-icon/contact-icon-contacts-tab member]
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:title (:primary-name member)
|
||||
:subtitle (i18n/label :t/view-profile)
|
||||
:accessibility-label :view-chat-details-button
|
||||
@@ -58,7 +59,8 @@
|
||||
{:title primary-name
|
||||
:subtitle secondary-name
|
||||
:accessibility-label :member-item
|
||||
:icon [chat-icon/contact-icon-contacts-tab member]
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo member)]
|
||||
:on-press (when (not= public-key current-user-identity)
|
||||
#(re-frame/dispatch [:chat.ui/show-profile public-key]))}
|
||||
(when (:admin? member)
|
||||
@@ -138,7 +140,8 @@
|
||||
(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 contact]
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]
|
||||
:on-press #(re-frame/dispatch [:bottom-sheet/show-sheet-old
|
||||
{:content (fn []
|
||||
[invitation-sheet invitation contact])}])}]))
|
||||
|
||||
@@ -94,16 +94,20 @@
|
||||
: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]
|
||||
[public-key container-size identicon?]
|
||||
(let [my-icon? (my-icon? public-key)
|
||||
visibility-status-update (visibility-status-update public-key my-icon?)
|
||||
size (icon-dot-size container-size)
|
||||
margin -2
|
||||
margin (icon-dot-margin size identicon?)
|
||||
dot-color (icon-dot-color visibility-status-update)
|
||||
new-ui? true]
|
||||
(merge (styles/visibility-status-dot {:color dot-color
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
[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]
|
||||
@@ -97,7 +98,8 @@
|
||||
(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 contact]}])
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]}])
|
||||
|
||||
(defn empty-items
|
||||
[icon title]
|
||||
|
||||
@@ -83,7 +83,8 @@
|
||||
{:monospace true
|
||||
:color :secondary}
|
||||
(utils/get-shortened-checksum-address (:address contact))]
|
||||
:icon [chat-icon/contact-icon-contacts-tab contact]}]
|
||||
:icon [chat-icon/contact-icon-contacts-tab
|
||||
(multiaccounts/displayed-photo contact)]}]
|
||||
[quo/list-item
|
||||
(merge {:title (if-not contact
|
||||
(i18n/label :t/wallet-choose-recipient)
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
[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")]
|
||||
(with-redefs [gfycat/generate-gfy (constantly "generated")
|
||||
identicon/identicon (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}
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
(ns status-im2.common.resources)
|
||||
|
||||
(def ui
|
||||
{: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")
|
||||
{: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")
|
||||
})
|
||||
|
||||
(def mock-images
|
||||
|
||||
@@ -17,14 +17,14 @@
|
||||
|
||||
(defn user-avatar-tag
|
||||
[user-id]
|
||||
(let [{:keys [primary-name] :as contact} (rf/sub [:contacts/contact-by-identity user-id])]
|
||||
(let [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
|
||||
(:primary-name contact)
|
||||
(multiaccounts/displayed-photo contact)]))
|
||||
|
||||
(defn- render-swipe-action
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
[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]
|
||||
@@ -15,8 +14,12 @@
|
||||
|
||||
(defn found-contact
|
||||
[public-key]
|
||||
(let [{:keys [primary-name compressed-key]
|
||||
:as contact} (rf/sub [:contacts/contact-by-identity 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))]
|
||||
(when primary-name
|
||||
[rn/view style/found-user
|
||||
[quo/text (style/text-description)
|
||||
@@ -24,7 +27,7 @@
|
||||
[rn/view (style/found-user-container)
|
||||
[quo/user-avatar
|
||||
{:full-name primary-name
|
||||
:profile-picture (multiaccounts/displayed-photo contact)
|
||||
:profile-picture profile-picture
|
||||
:size :small
|
||||
:status-indicator? false}]
|
||||
[rn/view style/found-user-text
|
||||
|
||||
@@ -31,4 +31,4 @@
|
||||
:left -20
|
||||
:right -20
|
||||
:bottom 0
|
||||
:height (- constants/composer-default-height constants/bottom-padding)})
|
||||
:height constants/composer-default-height})
|
||||
|
||||
@@ -58,9 +58,9 @@
|
||||
:i/arrow-up]])
|
||||
|
||||
(defn send-button
|
||||
[{:keys [text-value] :as state} animations window-height images?]
|
||||
[state animations window-height images?]
|
||||
(let [btn-opacity (reanimated/use-shared-value 0)
|
||||
z-index (reagent/atom (if (and (empty? @text-value) (not images?)) 0 1))]
|
||||
z-index (reagent/atom 0)]
|
||||
[:f> f-send-button state animations window-height images? btn-opacity z-index]))
|
||||
|
||||
(defn audio-button
|
||||
@@ -149,12 +149,11 @@
|
||||
(defn image-button
|
||||
[props animations insets]
|
||||
[quo/button
|
||||
{:on-press #(open-photo-selector props animations insets)
|
||||
:accessibility-label :open-images-button
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
{:on-press #(open-photo-selector props animations insets)
|
||||
:icon true
|
||||
:type :outline
|
||||
:size 32
|
||||
:style {:margin-right 12}}
|
||||
:i/image])
|
||||
|
||||
(defn reaction-button
|
||||
@@ -177,7 +176,7 @@
|
||||
:i/format])
|
||||
|
||||
(defn view
|
||||
[props state animations window-height insets {:keys [edit images]}]
|
||||
[props state animations window-height insets edit? images?]
|
||||
[rn/view {:style style/actions-container}
|
||||
[rn/view
|
||||
{:style {:flex-direction :row
|
||||
@@ -186,6 +185,6 @@
|
||||
[image-button props animations insets]
|
||||
[reaction-button]
|
||||
[format-button]]
|
||||
[:f> send-button state animations window-height images]
|
||||
(when (and (not edit) (not images))
|
||||
[:f> send-button state animations window-height images?]
|
||||
(when (and (not edit?) (not images?))
|
||||
[audio-button props state animations])])
|
||||
|
||||
@@ -5,17 +5,13 @@
|
||||
|
||||
(def ^:const bar-container-height 20)
|
||||
|
||||
(def ^:const input-height 32)
|
||||
(def ^:const input-height (if platform/ios? 32 42))
|
||||
|
||||
(def ^:const actions-container-height 56)
|
||||
|
||||
(def ^:const bottom-padding (if platform/android? 15 0))
|
||||
(def ^:const composer-default-height (+ bar-container-height input-height actions-container-height))
|
||||
|
||||
(def ^:const composer-default-height (+ bar-container-height input-height actions-container-height bottom-padding))
|
||||
|
||||
(def ^:const line-height (:line-height typography/paragraph-1))
|
||||
|
||||
(def ^:const multiline-minimized-height (+ input-height (if platform/ios? 18 line-height)))
|
||||
(def ^:const multiline-minimized-height (+ input-height 18))
|
||||
|
||||
(def ^:const empty-opacity 0.7)
|
||||
|
||||
@@ -27,7 +23,7 @@
|
||||
|
||||
(def ^:const mentions-max-height 240)
|
||||
|
||||
(def ^:const extra-content-offset (if platform/ios? 6 -8))
|
||||
(def ^:const extra-content-offset (if platform/ios? 6 0))
|
||||
|
||||
(def ^:const content-change-threshold 10)
|
||||
|
||||
@@ -37,4 +33,6 @@
|
||||
|
||||
(def ^:const background-threshold 0.75)
|
||||
|
||||
(def ^:const line-height (:line-height typography/paragraph-1))
|
||||
|
||||
(def ^:const max-text-size 4096)
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
[status-im2.contexts.chat.composer.keyboard :as kb]
|
||||
[utils.number :as utils.number]
|
||||
[oops.core :as oops]
|
||||
[utils.debounce :as debounce]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn reenter-screen-effect
|
||||
[{:keys [text-value saved-cursor-position maximized?]}
|
||||
@@ -37,12 +37,10 @@
|
||||
(js/setTimeout #(reset! lock-layout? true) 500)))
|
||||
|
||||
(defn kb-default-height-effect
|
||||
[{:keys [kb-default-height kb-height]}]
|
||||
(when (zero? @kb-default-height)
|
||||
[{:keys [kb-default-height]}]
|
||||
(when-not @kb-default-height
|
||||
(async-storage/get-item :kb-default-height
|
||||
(fn [height]
|
||||
(reset! kb-default-height (utils.number/parse-int height 0))
|
||||
(reset! kb-height (utils.number/parse-int height 0))))))
|
||||
#(reset! kb-default-height (utils.number/parse-int % nil)))))
|
||||
|
||||
(defn background-effect
|
||||
[{:keys [maximized?]}
|
||||
@@ -65,6 +63,32 @@
|
||||
(when-not images?
|
||||
(reset! sending-images? false)))
|
||||
|
||||
(defn edit-effect
|
||||
[{:keys [input-ref]}
|
||||
{:keys [text-value saved-cursor-position]}
|
||||
edit]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(let [edit-text (get-in edit [:content :text])]
|
||||
(when (and edit @input-ref)
|
||||
(.focus ^js @input-ref)
|
||||
(.setNativeProps ^js @input-ref (clj->js {:text edit-text}))
|
||||
(reset! text-value edit-text)
|
||||
(reset! saved-cursor-position (count edit-text)))))
|
||||
[(:message-id edit)]))
|
||||
|
||||
(defn reply-effect
|
||||
[{:keys [input-ref]}
|
||||
{:keys [container-opacity]}
|
||||
reply]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when reply
|
||||
(reanimated/animate container-opacity 1))
|
||||
(when (and reply @input-ref)
|
||||
(.focus ^js @input-ref)))
|
||||
[(:message-id reply)]))
|
||||
|
||||
(defn audio-effect
|
||||
[{:keys [recording? gesture-enabled?]}
|
||||
{:keys [container-opacity]}
|
||||
@@ -91,7 +115,8 @@
|
||||
(.remove ^js @keyboard-frame-listener))
|
||||
|
||||
(defn initialize
|
||||
[props state animations {:keys [max-height] :as dimensions} {:keys [chat-input images reply audio]}]
|
||||
[props state animations {:keys [max-height] :as dimensions} chat-input keyboard-height images? reply?
|
||||
audio]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(maximized-effect state animations dimensions chat-input)
|
||||
@@ -99,41 +124,15 @@
|
||||
(layout-effect state)
|
||||
(kb-default-height-effect state)
|
||||
(background-effect state animations dimensions chat-input)
|
||||
(images-effect props animations images)
|
||||
(images-effect props animations images?)
|
||||
(audio-effect state animations audio)
|
||||
(empty-effect state animations images reply audio)
|
||||
(kb/add-kb-listeners props state animations dimensions)
|
||||
(empty-effect state animations images? reply? audio)
|
||||
(kb/add-kb-listeners props state animations dimensions keyboard-height)
|
||||
#(component-will-unmount props))
|
||||
[max-height]))
|
||||
|
||||
(defn edit
|
||||
[{:keys [input-ref]}
|
||||
{:keys [text-value saved-cursor-position]}
|
||||
{:keys [edit]}]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(let [edit-text (get-in edit [:content :text])]
|
||||
(when (and edit @input-ref)
|
||||
(.focus ^js @input-ref)
|
||||
(.setNativeProps ^js @input-ref (clj->js {:text edit-text}))
|
||||
(reset! text-value edit-text)
|
||||
(reset! saved-cursor-position (count edit-text)))))
|
||||
[(:message-id edit)]))
|
||||
|
||||
(defn reply
|
||||
[{:keys [input-ref]}
|
||||
{:keys [container-opacity]}
|
||||
{:keys [reply]}]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when reply
|
||||
(reanimated/animate container-opacity 1))
|
||||
(when (and reply @input-ref)
|
||||
(.focus ^js @input-ref)))
|
||||
[(:message-id reply)]))
|
||||
|
||||
(defn edit-mentions
|
||||
[{:keys [input-ref]} {:keys [text-value cursor-position]} {:keys [input-with-mentions]}]
|
||||
[{:keys [input-ref]} {:keys [text-value cursor-position]} input-with-mentions]
|
||||
(rn/use-effect (fn []
|
||||
(let [input-text (reduce (fn [acc item]
|
||||
(str acc (second item)))
|
||||
@@ -152,14 +151,14 @@
|
||||
(defn update-input-mention
|
||||
[{:keys [input-ref]}
|
||||
{:keys [text-value]}
|
||||
{:keys [input-text]}]
|
||||
input-text]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
(when (and input-text (not= @text-value input-text))
|
||||
(when @input-ref
|
||||
(.setNativeProps ^js @input-ref (clj->js {:text input-text})))
|
||||
(reset! text-value input-text)
|
||||
(debounce/debounce-and-dispatch [:mention/on-change-text input-text] 300)))
|
||||
(rf/dispatch [:mention/on-change-text input-text])))
|
||||
[input-text]))
|
||||
|
||||
(defn did-mount
|
||||
|
||||
@@ -56,7 +56,7 @@
|
||||
|
||||
(defn drag-gesture
|
||||
[{:keys [input-ref] :as props}
|
||||
{:keys [gesture-enabled?] :as state}
|
||||
{:keys [gesture-enabled? text-value] :as state}
|
||||
{:keys [height saved-height last-height opacity background-y container-opacity] :as animations}
|
||||
{:keys [max-height lines] :as dimensions}
|
||||
keyboard-shown]
|
||||
@@ -67,10 +67,10 @@
|
||||
(gesture/on-start (fn [event]
|
||||
(if-not keyboard-shown
|
||||
(do ; focus and end
|
||||
(reset! text-value (str (oops/oget event "velocityY")))
|
||||
(when (< (oops/oget event "velocityY") constants/velocity-threshold)
|
||||
(reanimated/set-shared-value container-opacity 1)
|
||||
(reanimated/set-shared-value last-height max-height)
|
||||
(maximize state animations dimensions))
|
||||
(reanimated/set-shared-value last-height max-height))
|
||||
(when @input-ref
|
||||
(.focus ^js @input-ref))
|
||||
(reset! gesture-enabled? false))
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
(:require
|
||||
[quo2.foundations.colors :as colors]
|
||||
[quo2.foundations.typography :as typography]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]))
|
||||
|
||||
(defn top-gradient-style
|
||||
@@ -24,7 +25,7 @@
|
||||
:style (top-gradient-style opacity z-index)})
|
||||
|
||||
(def bottom-gradient-style
|
||||
{:height (:line-height typography/paragraph-1)
|
||||
{:height (if platform/ios? (:line-height typography/paragraph-1) 32)
|
||||
:position :absolute
|
||||
:bottom 0
|
||||
:left 0
|
||||
@@ -38,3 +39,4 @@
|
||||
:start {:x 0 :y 1}
|
||||
:end {:x 0 :y 0}
|
||||
:style bottom-gradient-style})
|
||||
|
||||
|
||||
@@ -8,8 +8,7 @@
|
||||
[status-im2.contexts.chat.composer.keyboard :as kb]
|
||||
[status-im2.contexts.chat.composer.utils :as utils]
|
||||
[status-im2.contexts.chat.composer.selection :as selection]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.debounce :as debounce]))
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn focus
|
||||
[{:keys [input-ref] :as props}
|
||||
@@ -38,10 +37,10 @@
|
||||
[{:keys [text-value focused? lock-selection? cursor-position saved-cursor-position gradient-z-index
|
||||
maximized?]}
|
||||
{:keys [height saved-height last-height gradient-opacity container-opacity opacity background-y]}
|
||||
{:keys [content-height max-height window-height]}
|
||||
{:keys [images reply]}]
|
||||
(let [lines (utils/calc-lines (- @content-height constants/extra-content-offset))
|
||||
min-height (utils/get-min-height lines)
|
||||
{:keys [lines content-height max-height window-height]}
|
||||
images
|
||||
reply]
|
||||
(let [min-height (utils/get-min-height lines)
|
||||
reopen-height (utils/calc-reopen-height text-value min-height content-height saved-height)]
|
||||
(reset! focused? false)
|
||||
(rf/dispatch [:chat.ui/set-input-focused false])
|
||||
@@ -62,17 +61,13 @@
|
||||
|
||||
(defn content-size-change
|
||||
[event
|
||||
{:keys [maximized? lock-layout?]}
|
||||
{:keys [maximized?]}
|
||||
{:keys [height saved-height opacity background-y]}
|
||||
{:keys [content-height window-height max-height]}
|
||||
keyboard-shown]
|
||||
(when keyboard-shown
|
||||
(let [event-size (oops/oget event "nativeEvent.contentSize.height")
|
||||
content-size (+ event-size constants/extra-content-offset)
|
||||
lines (utils/calc-lines event-size)
|
||||
content-size (if (= lines 1)
|
||||
constants/input-height
|
||||
(if (= lines 2) constants/multiline-minimized-height content-size))
|
||||
(let [content-size (+ (oops/oget event "nativeEvent.contentSize.height")
|
||||
constants/extra-content-offset)
|
||||
new-height (utils/bounded-val content-size constants/input-height max-height)]
|
||||
(reset! content-height content-size)
|
||||
(when (utils/update-height? content-size height max-height maximized?)
|
||||
@@ -81,15 +76,14 @@
|
||||
(when (= new-height max-height)
|
||||
(reset! maximized? true)
|
||||
(rf/dispatch [:chat.ui/set-input-maximized true]))
|
||||
(if (utils/show-background? max-height new-height maximized?)
|
||||
(if (utils/show-background? saved-height max-height new-height)
|
||||
(do
|
||||
(reanimated/set-shared-value background-y 0)
|
||||
(reanimated/animate opacity 1))
|
||||
(when (= (reanimated/get-shared-value opacity) 1)
|
||||
(reanimated/animate opacity 0)
|
||||
(js/setTimeout #(reanimated/set-shared-value background-y (- window-height)) 300)))
|
||||
(rf/dispatch [:chat.ui/set-input-content-height new-height])
|
||||
(reset! lock-layout? (> lines 2)))))
|
||||
(rf/dispatch [:chat.ui/set-input-content-height new-height]))))
|
||||
|
||||
(defn scroll
|
||||
[event
|
||||
@@ -119,7 +113,7 @@
|
||||
(@record-reset-fn)
|
||||
(reset! recording? false))
|
||||
(rf/dispatch [:chat.ui/set-chat-input-text text])
|
||||
(debounce/debounce-and-dispatch [:mention/on-change-text text] 300))
|
||||
(rf/dispatch [:mention/on-change-text text]))
|
||||
|
||||
(defn selection-change
|
||||
[event
|
||||
@@ -142,6 +136,8 @@
|
||||
(reset! selection-event nil)))))
|
||||
|
||||
(defn layout
|
||||
[event state blur-height]
|
||||
(when (utils/update-blur-height? event state blur-height)
|
||||
[event
|
||||
{:keys [lock-layout?]}
|
||||
blur-height]
|
||||
(when (utils/update-blur-height? event lock-layout? blur-height)
|
||||
(reanimated/set-shared-value blur-height (oops/oget event "nativeEvent.layout.height"))))
|
||||
|
||||
@@ -12,11 +12,9 @@
|
||||
curr-height))
|
||||
|
||||
(defn store-kb-height
|
||||
[event {:keys [kb-default-height kb-height]} {:keys [window-height]}]
|
||||
(let [height (- window-height (oops/oget event "endCoordinates.screenY"))]
|
||||
(reset! kb-height height)
|
||||
(when (zero? @kb-default-height)
|
||||
(async-storage/set-item! :kb-default-height (str height)))))
|
||||
[{:keys [kb-default-height]} keyboard-height]
|
||||
(when (and (not @kb-default-height) (pos? keyboard-height))
|
||||
(async-storage/set-item! :kb-default-height (str keyboard-height))))
|
||||
|
||||
(defn handle-emoji-kb-ios
|
||||
[event
|
||||
@@ -46,10 +44,10 @@
|
||||
|
||||
(defn add-kb-listeners
|
||||
[{:keys [keyboard-show-listener keyboard-frame-listener keyboard-hide-listener input-ref] :as props}
|
||||
state animations dimensions]
|
||||
state animations dimensions keyboard-height]
|
||||
(reset! keyboard-show-listener (.addListener rn/keyboard
|
||||
"keyboardDidShow"
|
||||
#(store-kb-height % state dimensions)))
|
||||
#(store-kb-height state keyboard-height)))
|
||||
(reset! keyboard-frame-listener (.addListener
|
||||
rn/keyboard
|
||||
"keyboardWillChangeFrame"
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im2.contexts.chat.composer.mentions.view
|
||||
(:require
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
@@ -30,17 +31,17 @@
|
||||
user])
|
||||
|
||||
(defn- f-view
|
||||
[suggestions-atom props state animations max-height cursor-pos images reply edit]
|
||||
(let [suggestions (rf/sub [:chat/mention-suggestions])
|
||||
opacity (reanimated/use-shared-value (if (seq suggestions) 1 0))
|
||||
size (count suggestions)
|
||||
data {:keyboard-height @(:kb-height state)
|
||||
:insets (safe-area/get-insets)
|
||||
:curr-height (reanimated/get-shared-value (:height animations))
|
||||
:window-height (:height (rn/get-window))
|
||||
:images images
|
||||
:reply reply
|
||||
:edit edit}
|
||||
[suggestions-atom props state animations max-height cursor-pos]
|
||||
(let [{:keys [keyboard-height]} (hooks/use-keyboard)
|
||||
suggestions (rf/sub [:chat/mention-suggestions])
|
||||
opacity (reanimated/use-shared-value (if (seq suggestions) 1 0))
|
||||
size (count suggestions)
|
||||
data {:keyboard-height keyboard-height
|
||||
:insets (safe-area/get-insets)
|
||||
:curr-height (reanimated/get-shared-value (:height animations))
|
||||
:window-height (rf/sub [:dimensions/window-height])
|
||||
:reply (rf/sub [:chats/reply-message])
|
||||
:edit (rf/sub [:chats/edit-message])}
|
||||
mentions-pos (utils/calc-suggestions-position cursor-pos max-height size state data)]
|
||||
(rn/use-effect
|
||||
(fn []
|
||||
@@ -61,6 +62,6 @@
|
||||
:accessibility-label :mentions-list}]]))
|
||||
|
||||
(defn view
|
||||
[props state animations max-height cursor-pos images reply edit]
|
||||
[props state animations max-height cursor-pos]
|
||||
(let [suggestions-atom (reagent/atom {})]
|
||||
[:f> f-view suggestions-atom props state animations max-height cursor-pos images reply edit]))
|
||||
[:f> f-view suggestions-atom props state animations max-height cursor-pos]))
|
||||
|
||||
@@ -79,7 +79,7 @@
|
||||
(format-reply-author from contact-name current-public-key)]]))
|
||||
|
||||
(defn quoted-message
|
||||
[{:keys [from content-type contentType parsed-text content deleted? deleted-for-me?
|
||||
[{: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])
|
||||
@@ -100,6 +100,7 @@
|
||||
[rn/view {:style (style/quoted-message pin?)}
|
||||
[reply-from
|
||||
{:from from
|
||||
:identicon identicon
|
||||
:contact-name contact-name
|
||||
:current-public-key current-public-key}]
|
||||
[quo/text
|
||||
|
||||
@@ -55,23 +55,22 @@
|
||||
:overflow :hidden}))
|
||||
|
||||
(defn input-view
|
||||
[{:keys [recording?]}]
|
||||
[{:keys [saved-emoji-kb-extra-height]}
|
||||
{:keys [focused? recording?]}]
|
||||
{:z-index 1
|
||||
:position (if @saved-emoji-kb-extra-height :relative :absolute)
|
||||
:top 0
|
||||
:left 0
|
||||
:right (when (or focused? platform/ios?) 0)
|
||||
:flex 1
|
||||
:display (if @recording? :none :flex)
|
||||
:min-height constants/input-height})
|
||||
|
||||
(defn input-text
|
||||
[{:keys [saved-emoji-kb-extra-height]}
|
||||
{:keys [focused? maximized?]}]
|
||||
[]
|
||||
(merge typography/paragraph-1
|
||||
{:color (colors/theme-colors :black :white)
|
||||
:text-align-vertical :top
|
||||
:position (if @saved-emoji-kb-extra-height :relative :absolute)
|
||||
:top 0
|
||||
:left 0
|
||||
:right (when (or focused? platform/ios?) 0)
|
||||
:padding-bottom (when @maximized? 0)}))
|
||||
:text-align-vertical :top}))
|
||||
(defn background
|
||||
[opacity background-y window-height]
|
||||
(reanimated/apply-animations-to-style
|
||||
|
||||
@@ -1,15 +1,9 @@
|
||||
(ns status-im2.contexts.chat.composer.sub-view
|
||||
(:require
|
||||
[quo2.core :as quo]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[status-im2.contexts.chat.composer.style :as style]
|
||||
[status-im2.contexts.chat.composer.utils :as utils]
|
||||
[status-im2.contexts.chat.messages.list.view :as messages.list]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
[status-im2.contexts.chat.composer.style :as style]))
|
||||
|
||||
(defn bar
|
||||
[]
|
||||
@@ -20,40 +14,6 @@
|
||||
[layout-height focused?]
|
||||
[reanimated/view {:style (style/blur-container layout-height focused?)}
|
||||
[blur/view (style/blur-view)]])
|
||||
|
||||
(defn blur-view
|
||||
[layout-height focused?]
|
||||
[:f> f-blur-view layout-height focused?])
|
||||
|
||||
(defn- f-shell-button
|
||||
[{:keys [maximized?]} {:keys [height]} {:keys [images reply edit]}]
|
||||
(let [insets (safe-area/get-insets)
|
||||
extra-height (utils/calc-extra-content-height images reply edit)
|
||||
translate-y (reanimated/use-shared-value
|
||||
(utils/calc-shell-neg-y insets maximized? extra-height))]
|
||||
(rn/use-effect (fn []
|
||||
(let [extra-height (utils/calc-extra-content-height images reply edit)]
|
||||
(reanimated/animate translate-y
|
||||
(utils/calc-shell-neg-y insets maximized? extra-height))))
|
||||
[@maximized? images reply edit])
|
||||
[reanimated/view
|
||||
{:style (reanimated/apply-animations-to-style
|
||||
{:bottom height ; we use height of the input directly as bottom position
|
||||
:transform [{:translate-y translate-y}]} ; translate down when maximized
|
||||
{:position :absolute
|
||||
:left 0
|
||||
:right 0})}
|
||||
[quo/floating-shell-button
|
||||
(merge {:jump-to
|
||||
{:on-press (fn []
|
||||
(rf/dispatch [:chat/close true])
|
||||
(rf/dispatch [:shell/navigate-to-jump-to]))
|
||||
:label (i18n/label :t/jump-to)
|
||||
:style {:align-self :center}}}
|
||||
(when @messages.list/show-floating-scroll-down-button
|
||||
{:scroll-to-bottom {:on-press messages.list/scroll-to-bottom}}))
|
||||
{}]]))
|
||||
|
||||
(defn shell-button
|
||||
[state animations subs]
|
||||
[:f> f-shell-button state animations subs])
|
||||
|
||||
@@ -50,14 +50,13 @@
|
||||
(and (not-empty @text-value) (not @focused?) (> lines 2)))
|
||||
|
||||
(defn show-background?
|
||||
[max-height new-height maximized?]
|
||||
(or @maximized?
|
||||
[saved-height max-height new-height]
|
||||
(or (= (reanimated/get-shared-value saved-height) max-height)
|
||||
(> new-height (* constants/background-threshold max-height))))
|
||||
|
||||
(defn update-blur-height?
|
||||
[event {:keys [lock-layout? focused?]} layout-height]
|
||||
[event lock-layout? layout-height]
|
||||
(or (not @lock-layout?)
|
||||
(not @focused?)
|
||||
(> (reanimated/get-shared-value layout-height) (oops/oget event "nativeEvent.layout.height"))))
|
||||
|
||||
(defn calc-lines
|
||||
@@ -65,22 +64,17 @@
|
||||
(let [lines (Math/round (/ height constants/line-height))]
|
||||
(if platform/ios? lines (dec lines))))
|
||||
|
||||
(defn calc-extra-content-height
|
||||
[images? reply? edit?]
|
||||
(let [height (if images? constants/images-container-height 0)
|
||||
height (if reply? (+ height constants/reply-container-height) height)
|
||||
height (if edit? (+ height constants/edit-container-height) height)]
|
||||
height))
|
||||
|
||||
(defn calc-max-height
|
||||
[{:keys [images reply edit]} window-height kb-height insets]
|
||||
[window-height kb-height insets images? reply? edit?]
|
||||
(let [margin-top (if platform/ios? (:top insets) (+ 10 (:top insets)))
|
||||
max-height (- window-height
|
||||
margin-top
|
||||
kb-height
|
||||
constants/bar-container-height
|
||||
constants/actions-container-height)
|
||||
max-height (- max-height (calc-extra-content-height images reply edit))]
|
||||
max-height (if images? (- max-height constants/images-container-height) max-height)
|
||||
max-height (if reply? (- max-height constants/reply-container-height) max-height)
|
||||
max-height (if edit? (- max-height constants/edit-container-height) max-height)]
|
||||
max-height))
|
||||
|
||||
(defn empty-input?
|
||||
@@ -112,25 +106,18 @@
|
||||
sub-text-lines-in-view (- sub-text-lines scrolled-lines)]
|
||||
(* sub-text-lines-in-view constants/line-height)))
|
||||
|
||||
(defn calc-shell-neg-y
|
||||
[insets maximized? extra-height]
|
||||
(let [padding 6
|
||||
neg-y (if @maximized? -50 0)]
|
||||
(- (+ constants/bar-container-height
|
||||
constants/actions-container-height
|
||||
constants/bottom-padding
|
||||
(:bottom insets)
|
||||
padding
|
||||
extra-height
|
||||
neg-y))))
|
||||
|
||||
(defn calc-suggestions-position
|
||||
[cursor-pos max-height size
|
||||
{:keys [maximized?]}
|
||||
{:keys [insets curr-height window-height keyboard-height images reply edit]}]
|
||||
{:keys [insets curr-height window-height keyboard-height edit reply]}]
|
||||
(let [base (+ constants/composer-default-height (:bottom insets) 8)
|
||||
base (+ base (- curr-height constants/input-height))
|
||||
base (+ base (calc-extra-content-height images reply edit))
|
||||
base (if edit
|
||||
(+ base constants/edit-container-height)
|
||||
base)
|
||||
base (if reply
|
||||
(+ base constants/reply-container-height)
|
||||
base)
|
||||
view-height (- window-height keyboard-height (:top insets))
|
||||
container-height (bounded-val
|
||||
(* (/ constants/mentions-max-height 4) size)
|
||||
@@ -166,8 +153,7 @@
|
||||
:cursor-position (reagent/atom 0)
|
||||
:saved-cursor-position (reagent/atom 0)
|
||||
:gradient-z-index (reagent/atom 0)
|
||||
:kb-default-height (reagent/atom 0)
|
||||
:kb-height (reagent/atom 0)
|
||||
:kb-default-height (reagent/atom nil)
|
||||
:gesture-enabled? (reagent/atom true)
|
||||
:lock-selection? (reagent/atom true)
|
||||
:focused? (reagent/atom false)
|
||||
@@ -177,21 +163,8 @@
|
||||
:recording? (reagent/atom false)
|
||||
:first-level? (reagent/atom true)
|
||||
:menu-items (reagent/atom selection/first-level-menu-items)})
|
||||
|
||||
(defn init-subs
|
||||
[]
|
||||
(let [chat-input (rf/sub [:chats/current-chat-input])]
|
||||
{:images (seq (rf/sub [:chats/sending-image]))
|
||||
:audio (rf/sub [:chats/sending-audio])
|
||||
:reply (rf/sub [:chats/reply-message])
|
||||
:edit (rf/sub [:chats/edit-message])
|
||||
:input-with-mentions (rf/sub [:chat/input-with-mentions])
|
||||
:input-text (:input-text chat-input)
|
||||
:input-content-height (:input-content-height chat-input)}))
|
||||
|
||||
(defn init-animations
|
||||
[{:keys [input-text images reply audio]}
|
||||
lines content-height max-height opacity background-y]
|
||||
[lines input-text images reply audio content-height max-height opacity background-y]
|
||||
(let [initial-height (if (> lines 1)
|
||||
constants/multiline-minimized-height
|
||||
constants/input-height)]
|
||||
|
||||
@@ -4,10 +4,10 @@
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.hooks :as hooks]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[reagent.core :as reagent]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[status-im2.contexts.chat.composer.style :as style]
|
||||
[status-im2.contexts.chat.composer.images.view :as images]
|
||||
[status-im2.contexts.chat.composer.reply.view :as reply]
|
||||
@@ -16,6 +16,7 @@
|
||||
[status-im2.contexts.chat.composer.utils :as utils]
|
||||
[status-im2.contexts.chat.composer.constants :as constants]
|
||||
[status-im2.contexts.chat.composer.actions.view :as actions]
|
||||
[status-im2.contexts.chat.composer.keyboard :as kb]
|
||||
[status-im2.contexts.chat.composer.sub-view :as sub-view]
|
||||
[status-im2.contexts.chat.composer.effects :as effects]
|
||||
[status-im2.contexts.chat.composer.gesture :as drag-gesture]
|
||||
@@ -25,46 +26,60 @@
|
||||
|
||||
(defn sheet-component
|
||||
[{:keys [insets window-height blur-height opacity background-y]} props state]
|
||||
(let [subs (utils/init-subs)
|
||||
content-height (reagent/atom (or (:input-content-height subs)
|
||||
constants/input-height))
|
||||
{:keys [keyboard-shown]} (hooks/use-keyboard)
|
||||
max-height (utils/calc-max-height subs
|
||||
window-height
|
||||
@(:kb-height state)
|
||||
insets)
|
||||
lines (utils/calc-lines (- @content-height
|
||||
constants/extra-content-offset))
|
||||
max-lines (utils/calc-lines max-height)
|
||||
animations (utils/init-animations
|
||||
subs
|
||||
lines
|
||||
content-height
|
||||
max-height
|
||||
opacity
|
||||
background-y)
|
||||
dimensions {:content-height content-height
|
||||
:max-height max-height
|
||||
:window-height window-height
|
||||
:lines lines
|
||||
:max-lines max-lines}
|
||||
show-bottom-gradient? (utils/show-bottom-gradient? state dimensions)
|
||||
cursor-pos (utils/cursor-y-position-relative-to-container props
|
||||
state)]
|
||||
(let [images (rf/sub [:chats/sending-image])
|
||||
audio (rf/sub [:chats/sending-audio])
|
||||
reply (rf/sub [:chats/reply-message])
|
||||
edit (rf/sub [:chats/edit-message])
|
||||
input-with-mentions (rf/sub [:chat/input-with-mentions])
|
||||
{:keys [input-text input-content-height]
|
||||
:as chat-input} (rf/sub [:chats/current-chat-input])
|
||||
content-height (reagent/atom (or input-content-height
|
||||
constants/input-height))
|
||||
{:keys [keyboard-shown keyboard-height]} (hooks/use-keyboard)
|
||||
kb-height (kb/get-kb-height keyboard-height
|
||||
@(:kb-default-height state))
|
||||
max-height (utils/calc-max-height window-height
|
||||
kb-height
|
||||
insets
|
||||
(boolean (seq images))
|
||||
reply
|
||||
edit)
|
||||
lines (utils/calc-lines @content-height)
|
||||
max-lines (utils/calc-lines max-height)
|
||||
animations (utils/init-animations
|
||||
lines
|
||||
input-text
|
||||
images
|
||||
reply
|
||||
audio
|
||||
content-height
|
||||
max-height
|
||||
opacity
|
||||
background-y)
|
||||
dimensions {:content-height content-height
|
||||
:max-height max-height
|
||||
:window-height window-height
|
||||
:lines lines
|
||||
:max-lines max-lines}
|
||||
show-bottom-gradient? (utils/show-bottom-gradient? state dimensions)
|
||||
cursor-pos (utils/cursor-y-position-relative-to-container props
|
||||
state)]
|
||||
(effects/did-mount props)
|
||||
(effects/initialize props
|
||||
state
|
||||
animations
|
||||
dimensions
|
||||
subs)
|
||||
(effects/edit props state subs)
|
||||
(effects/reply props animations subs)
|
||||
(effects/update-input-mention props state subs)
|
||||
(effects/edit-mentions props state subs)
|
||||
chat-input
|
||||
keyboard-height
|
||||
(boolean (seq images))
|
||||
reply
|
||||
audio)
|
||||
(effects/edit-effect props state edit)
|
||||
(effects/reply-effect props animations reply)
|
||||
(effects/update-input-mention props state input-text)
|
||||
(effects/edit-mentions props state input-with-mentions)
|
||||
[:<>
|
||||
[sub-view/shell-button state animations subs]
|
||||
[mentions/view props state animations max-height cursor-pos (:images subs) (:reply subs)
|
||||
(:edit subs)]
|
||||
[mentions/view props state animations max-height cursor-pos]
|
||||
[gesture/gesture-detector
|
||||
{:gesture (drag-gesture/drag-gesture props state animations dimensions keyboard-shown)}
|
||||
[reanimated/view
|
||||
@@ -81,17 +96,17 @@
|
||||
[rn/selectable-text-input
|
||||
{:ref #(reset! (:selectable-input-ref props) %)
|
||||
:menu-items @(:menu-items state)
|
||||
:style (style/input-view state)}
|
||||
:style (style/input-view props state)}
|
||||
[rn/text-input
|
||||
{:ref #(reset! (:input-ref props) %)
|
||||
:default-value @(:text-value state)
|
||||
:on-focus #(handler/focus props state animations dimensions)
|
||||
:on-blur #(handler/blur state animations dimensions subs)
|
||||
:on-blur #(handler/blur state animations dimensions images reply)
|
||||
:on-content-size-change #(handler/content-size-change %
|
||||
state
|
||||
animations
|
||||
dimensions
|
||||
(or keyboard-shown (:edit subs)))
|
||||
(or keyboard-shown edit))
|
||||
:on-scroll #(handler/scroll % props state animations dimensions)
|
||||
:on-change-text #(handler/change-text % props state)
|
||||
:on-selection-change #(handler/selection-change % props state)
|
||||
@@ -101,20 +116,17 @@
|
||||
:multiline true
|
||||
:placeholder (i18n/label :t/type-something)
|
||||
:placeholder-text-color (colors/theme-colors colors/neutral-40 colors/neutral-50)
|
||||
:style (style/input-text props state)
|
||||
:style (style/input-text)
|
||||
:max-length constants/max-text-size
|
||||
:accessibility-label :chat-message-input}]]
|
||||
[gradients/view props state animations show-bottom-gradient?]]
|
||||
[images/images-list]
|
||||
[actions/view props state animations window-height insets subs]
|
||||
(when (and platform/android? (not @(:focused? state)))
|
||||
[rn/view {:style {:height constants/bottom-padding
|
||||
:background-color :transparent}}])
|
||||
]]]))
|
||||
[actions/view props state animations window-height insets edit
|
||||
(boolean (seq images))]]]]))
|
||||
|
||||
(defn composer
|
||||
[insets]
|
||||
(let [window-height (:height (rn/get-window))
|
||||
(let [window-height (rf/sub [:dimensions/window-height])
|
||||
opacity (reanimated/use-shared-value 0)
|
||||
background-y (reanimated/use-shared-value (- window-height))
|
||||
blur-height (reanimated/use-shared-value (+ constants/composer-default-height
|
||||
|
||||
@@ -102,8 +102,7 @@
|
||||
[]
|
||||
(fn []
|
||||
(let [pending-contact-requests (rf/sub [:activity-center/pending-contact-requests])
|
||||
selected-tab (or (rf/sub [:messages-home/selected-tab])
|
||||
:tab/recent)
|
||||
selected-tab (or (rf/sub [:messages-home/selected-tab]) :tab/recent)
|
||||
top (safe-area/get-top)]
|
||||
[:<>
|
||||
(if (= selected-tab :tab/contacts)
|
||||
@@ -123,7 +122,6 @@
|
||||
[quo/discover-card
|
||||
{:title (i18n/label :t/invite-friends-to-status)
|
||||
:description (i18n/label :t/share-invite-link)}]
|
||||
^{:key (str "tabs-" selected-tab)}
|
||||
[quo/tabs
|
||||
{:style style/tabs
|
||||
:size 32
|
||||
|
||||
@@ -9,10 +9,8 @@
|
||||
contact (rf/sub [:contacts/contact-by-address public-key])
|
||||
photo-path (when (seq (:images contact)) (rf/sub [:chats/photo-path public-key]))
|
||||
online? (rf/sub [:visibility-status-updates/online? public-key])]
|
||||
[rn/view {:style {:padding-top 2}}
|
||||
[rn/touchable-opacity
|
||||
{:active-opacity 1
|
||||
:on-press #(rf/dispatch [:chat.ui/show-profile public-key])}
|
||||
[rn/touchable-without-feedback {:on-press #(rf/dispatch [:chat.ui/show-profile public-key])}
|
||||
[rn/view {:padding-top 2}
|
||||
[quo/user-avatar
|
||||
{:full-name display-name
|
||||
:profile-picture photo-path
|
||||
|
||||