Compare commits
28
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66a69e5eaa | ||
|
|
afef011ac8 | ||
|
|
c76346f108 | ||
|
|
e4fb664fa5 | ||
|
|
c54830dd5b | ||
|
|
408f461ee8 | ||
|
|
183a78ae84 | ||
|
|
7529032c06 | ||
|
|
57069027c5 | ||
|
|
a27facbca4 | ||
|
|
fd133576b7 | ||
|
|
dcd06424f8 | ||
|
|
b4b403c5bb | ||
|
|
8fd2c75944 | ||
|
|
4e1efb512c | ||
|
|
efcf8b51a8 | ||
|
|
3d4dd1d59e | ||
|
|
a2d0121c08 | ||
|
|
5ecd471e59 | ||
|
|
a021f0a9bd | ||
|
|
541de5ac5f | ||
|
|
9ad254867e | ||
|
|
34d8c1621d | ||
|
|
124e23ed50 | ||
|
|
8e634aeb24 | ||
|
|
6ef0cfc2ca | ||
|
|
7b7cfe08dc | ||
|
|
598b985c72 |
@@ -375,25 +375,25 @@ test-contract: export SHADOW_NS_REGEXP := ^tests\.contract-test.*$$
|
||||
test-contract: ##@test Run contract tests
|
||||
test-contract: _test-clojure
|
||||
|
||||
android-test: jsbundle
|
||||
android-test: export TARGET := android
|
||||
android-test:
|
||||
test-android: jsbundle
|
||||
test-android: export TARGET := android
|
||||
test-android: ##@test Android Gradle test
|
||||
cd android && ./gradlew test
|
||||
|
||||
component-test-watch: export TARGET := clojure
|
||||
component-test-watch: export COMPONENT_TEST := true
|
||||
component-test-watch: export BABEL_ENV := test
|
||||
component-test-watch: export JEST_USE_SILENT_REPORTER := false
|
||||
component-test-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
test-component-watch: export TARGET := clojure
|
||||
test-component-watch: export COMPONENT_TEST := true
|
||||
test-component-watch: export BABEL_ENV := test
|
||||
test-component-watch: export JEST_USE_SILENT_REPORTER := false
|
||||
test-component-watch: ##@ Watch tests and re-run no changes to cljs files
|
||||
@scripts/check-metro-shadow-process.sh
|
||||
rm -rf ./component-spec
|
||||
nodemon --exec 'yarn shadow-cljs compile component-test && jest --config=test/jest/jest.config.js --testEnvironment node ' -e cljs
|
||||
|
||||
component-test: export TARGET := clojure
|
||||
component-test: export COMPONENT_TEST := true
|
||||
component-test: export BABEL_ENV := test
|
||||
component-test: export JEST_USE_SILENT_REPORTER := false
|
||||
component-test: ##@test Run component tests once in NodeJS
|
||||
test-component: export TARGET := clojure
|
||||
test-component: export COMPONENT_TEST := true
|
||||
test-component: export BABEL_ENV := test
|
||||
test-component: export JEST_USE_SILENT_REPORTER := false
|
||||
test-component: ##@test Run component tests once in NodeJS
|
||||
@scripts/check-metro-shadow-process.sh
|
||||
rm -rf ./component-spec
|
||||
yarn shadow-cljs compile component-test && \
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -34,10 +34,10 @@ pipeline {
|
||||
}
|
||||
|
||||
environment {
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = "android${utils.isE2EBuild() ? "-e2e" : ""}"
|
||||
LANG = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
PLATFORM = "android${utils.isE2EBuild() ? "-e2e" : ""}"
|
||||
BUILD_ENV = 'prod'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -34,10 +34,10 @@ pipeline {
|
||||
}
|
||||
|
||||
environment {
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = 'ios'
|
||||
LANG = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
PLATFORM = 'ios'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
BUNDLE_PATH = "${HOME}/.bundle"
|
||||
|
||||
+34
-41
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
/* Options section can't access functions in objects. */
|
||||
def isPRBuild = utils.isPRBuild()
|
||||
@@ -29,61 +29,47 @@ pipeline {
|
||||
description: 'Specify build type. Values: pr / e2e / nightly / release',
|
||||
defaultValue: 'pr',
|
||||
)
|
||||
booleanParam(
|
||||
name: 'RUN_CONTRACT_TESTS',
|
||||
description: 'Whether to run optional and slow contract tests.',
|
||||
defaultValue: false,
|
||||
)
|
||||
}
|
||||
|
||||
environment {
|
||||
LANG = "en_US.UTF-8"
|
||||
LC_ALL = "en_US.UTF-8"
|
||||
LANGUAGE = "en_US.UTF-8"
|
||||
TARGET = 'tests'
|
||||
LANG = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
PLATFORM = 'tests'
|
||||
BUILD_ENV = 'prod'
|
||||
NIX_CONF_DIR = "${env.WORKSPACE}/nix"
|
||||
LOG_FILE = utils.pkgFilename(ext: 'log', arch: 'tests')
|
||||
CLJ_LINTER_PRINT_WARNINGS = 'true'
|
||||
}
|
||||
|
||||
stages {
|
||||
stage('Checks') {
|
||||
stage('Test') {
|
||||
parallel {
|
||||
stage('Lint') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make lint CLJ_LINTER_PRINT_WARNINGS=true 2>&1 | tee ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
steps { make('lint') }
|
||||
}
|
||||
stage('Unit Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make test-unit 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
stage('Unit') {
|
||||
steps { make('test-unit') }
|
||||
}
|
||||
stage('Component') {
|
||||
steps { make('test-component') }
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Contract Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make test-contract 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('Integration Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make test-integration 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
}
|
||||
stage('Component Tests') {
|
||||
steps {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make component-test 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
stage('Heavy Test') {
|
||||
parallel {
|
||||
stage('Contract') {
|
||||
when { expression { params.RUN_CONTRACT_TESTS } }
|
||||
steps { make('test-contract') }
|
||||
}
|
||||
stage('Integration') {
|
||||
steps { make('test-integration') }
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Upload') {
|
||||
@@ -100,3 +86,10 @@ pipeline {
|
||||
always { sh 'make purge' }
|
||||
}
|
||||
}
|
||||
|
||||
def make(target) {
|
||||
sh """#!/bin/bash
|
||||
set -eo pipefail
|
||||
make ${target} 2>&1 | tee -a ${LOG_FILE}
|
||||
"""
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'macos' }
|
||||
|
||||
environment {
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
TARGET = 'ios'
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
PLATFORM = 'ios'
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
/* avoid writing to r/o /nix */
|
||||
GEM_HOME = '~/.rubygems'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
agent { label params.AGENT_LABEL }
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
agent { label 'linux' }
|
||||
|
||||
environment {
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
TARGET = 'ios'
|
||||
LANG = 'en_US.UTF-8'
|
||||
LANGUAGE = 'en_US.UTF-8'
|
||||
LC_ALL = 'en_US.UTF-8'
|
||||
PLATFORM = 'ios'
|
||||
FASTLANE_DISABLE_COLORS = 1
|
||||
/* avoid writing to r/o /nix */
|
||||
GEM_HOME = '~/.rubygems'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env groovy
|
||||
library 'status-jenkins-lib@v1.8.7'
|
||||
library 'status-jenkins-lib@v1.8.12'
|
||||
|
||||
pipeline {
|
||||
agent {
|
||||
|
||||
@@ -16,10 +16,10 @@ Both of these links are showing it for React-Testing-Library (not Native) howeve
|
||||
## Running the tests
|
||||
To run these tests there are two methods.
|
||||
|
||||
`make component-test`
|
||||
`make test-component`
|
||||
setups and runs the test suite once.
|
||||
|
||||
`make component-test-watch`
|
||||
`make test-component-watch`
|
||||
setups and runs the test suite and watches for code changes will then retrigger the test suite.
|
||||
|
||||
## Writing Tests
|
||||
@@ -38,7 +38,7 @@ There is a file of utility functions defined in "src/test_helpers/component.cljs
|
||||
## Configuration
|
||||
Status Mobile has a bespoke tech stack, as such there is more complexities to configuring the tests.
|
||||
|
||||
### Shadow-CLJS
|
||||
### Shadow-CLJS
|
||||
the configuration for compiling our tests are defined in the "shadow-cljs.edn" file.
|
||||
The three main parts of this are
|
||||
`:target :npm-module`
|
||||
@@ -47,9 +47,9 @@ Needed for the configuration we are using
|
||||
a vector of entry points for the test files.
|
||||
and the `ns-regexp` to specify what tests to find. Since we have multiple forms of tests we decided that "component-spec" is the least likely to detect the wrong file type.
|
||||
|
||||
It's worth knowing that our tests are compiled to JS and then run in the temporary folder `component-tests`.
|
||||
It's worth knowing that our tests are compiled to JS and then run in the temporary folder `component-tests`.
|
||||
|
||||
### Jest
|
||||
There is also further configuration for Jest in "test/jest". There is a jest config file which has some mostly standard configuration pieces, where the tests live, what environment variables are set etc. This is documented by Jest here: https://jestjs.io/docs/configuration
|
||||
|
||||
There is also a setup file which is used to set some global and default values. Additionally this file is used to mock some of the react native (among other) dependencies
|
||||
There is also a setup file which is used to set some global and default values. Additionally this file is used to mock some of the react native (among other) dependencies.
|
||||
|
||||
+2
-2
@@ -54,13 +54,13 @@ Here I'm showing a terminal-only experience using Tmux (left pane Emacs, right p
|
||||
To run tests:
|
||||
|
||||
```
|
||||
make component-test
|
||||
make test-component
|
||||
```
|
||||
|
||||
Also test watcher can be launched. It will re-run the entire test suite when any file is modified
|
||||
|
||||
```
|
||||
make component-test-watch
|
||||
make test-component-watch
|
||||
```
|
||||
|
||||
Check [component tests doc](./component-tests-overview.md) for more.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/bin/bash
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Increment a version string using Semantic Versioning (SemVer) terminology.
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
(ns legacy.status-im.data-store.chats
|
||||
(:require
|
||||
[clojure.set :as set]
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.data-store.messages :as messages]
|
||||
[legacy.status-im.utils.deprecated-types :as types]
|
||||
[re-frame.core :as re-frame]
|
||||
@@ -59,62 +60,73 @@
|
||||
:admins #{}
|
||||
:members-joined #{})))
|
||||
|
||||
(defn <-color
|
||||
[value]
|
||||
(if (and (some? value)
|
||||
(string/starts-with? value "#"))
|
||||
value
|
||||
(keyword value)))
|
||||
|
||||
(defn <-rpc
|
||||
[chat]
|
||||
(-> chat
|
||||
(set/rename-keys {:id :chat-id
|
||||
:communityId :community-id
|
||||
:syncedFrom :synced-from
|
||||
:syncedTo :synced-to
|
||||
:membershipUpdateEvents :membership-update-events
|
||||
:deletedAtClockValue :deleted-at-clock-value
|
||||
:chatType :chat-type
|
||||
:unviewedMessagesCount :unviewed-messages-count
|
||||
:unviewedMentionsCount :unviewed-mentions-count
|
||||
:lastMessage :last-message
|
||||
:lastClockValue :last-clock-value
|
||||
:invitationAdmin :invitation-admin
|
||||
:profile :profile-public-key
|
||||
:muteTill :muted-till})
|
||||
(set/rename-keys {:id :chat-id
|
||||
:communityId :community-id
|
||||
:syncedFrom :synced-from
|
||||
:syncedTo :synced-to
|
||||
:membershipUpdateEvents :membership-update-events
|
||||
:deletedAtClockValue :deleted-at-clock-value
|
||||
:chatType :chat-type
|
||||
:unviewedMessagesCount :unviewed-messages-count
|
||||
:unviewedMentionsCount :unviewed-mentions-count
|
||||
:lastMessage :last-message
|
||||
:lastClockValue :last-clock-value
|
||||
:invitationAdmin :invitation-admin
|
||||
:profile :profile-public-key
|
||||
:muteTill :muted-till
|
||||
:hideIfPermissionsNotMet :hide-if-permissions-not-met?})
|
||||
rpc->type
|
||||
unmarshal-members
|
||||
(update :last-message #(when % (messages/<-rpc %)))
|
||||
(update :color <-color)
|
||||
(dissoc :members)))
|
||||
|
||||
(defn <-rpc-js
|
||||
[^js chat]
|
||||
(-> {:name (.-name chat)
|
||||
:description (.-description chat)
|
||||
:color (.-color chat)
|
||||
:emoji (.-emoji chat)
|
||||
:timestamp (.-timestamp chat)
|
||||
:alias (.-alias chat)
|
||||
:muted (.-muted chat)
|
||||
:joined (.-joined chat)
|
||||
:muted-till (.-muteTill chat)
|
||||
:chat-id (.-id chat)
|
||||
:community-id (.-communityId chat)
|
||||
:synced-from (.-syncedFrom chat)
|
||||
:synced-to (.-syncedTo chat)
|
||||
:deleted-at-clock-value (.-deletedAtClockValue chat)
|
||||
:chat-type (.-chatType chat)
|
||||
:unviewed-messages-count (.-unviewedMessagesCount chat)
|
||||
:unviewed-mentions-count (.-unviewedMentionsCount chat)
|
||||
:last-message {:content {:text (.-text chat)
|
||||
:parsed-text (types/js->clj (.-parsedText chat))
|
||||
:response-to (.-responseTo chat)}
|
||||
:content-type (.-contentType chat)
|
||||
:community-id (.-contentCommunityId chat)
|
||||
:outgoing (boolean (.-outgoingStatus chat))
|
||||
:album-images-count (.-albumImagesCount chat)
|
||||
:from (.-from chat)
|
||||
:deleted? (.-deleted chat)
|
||||
:deleted-for-me? (.-deletedForMe chat)}
|
||||
:last-clock-value (.-lastClockValue chat)
|
||||
:profile-public-key (.-profile chat)
|
||||
:highlight (.-highlight chat)
|
||||
:active (.-active chat)
|
||||
:members (types/js->clj (.-members chat))}
|
||||
(-> {:name (.-name chat)
|
||||
:description (.-description chat)
|
||||
:color (<-color (.-color chat))
|
||||
:emoji (.-emoji chat)
|
||||
:timestamp (.-timestamp chat)
|
||||
:alias (.-alias chat)
|
||||
:muted (.-muted chat)
|
||||
:joined (.-joined chat)
|
||||
:muted-till (.-muteTill chat)
|
||||
:chat-id (.-id chat)
|
||||
:community-id (.-communityId chat)
|
||||
:synced-from (.-syncedFrom chat)
|
||||
:synced-to (.-syncedTo chat)
|
||||
:deleted-at-clock-value (.-deletedAtClockValue chat)
|
||||
:chat-type (.-chatType chat)
|
||||
:unviewed-messages-count (.-unviewedMessagesCount chat)
|
||||
:unviewed-mentions-count (.-unviewedMentionsCount chat)
|
||||
:last-message {:content {:text (.-text chat)
|
||||
:parsed-text (types/js->clj (.-parsedText
|
||||
chat))
|
||||
:response-to (.-responseTo chat)}
|
||||
:content-type (.-contentType chat)
|
||||
:community-id (.-contentCommunityId chat)
|
||||
:outgoing (boolean (.-outgoingStatus chat))
|
||||
:album-images-count (.-albumImagesCount chat)
|
||||
:from (.-from chat)
|
||||
:deleted? (.-deleted chat)
|
||||
:deleted-for-me? (.-deletedForMe chat)}
|
||||
:last-clock-value (.-lastClockValue chat)
|
||||
:profile-public-key (.-profile chat)
|
||||
:highlight (.-highlight chat)
|
||||
:active (.-active chat)
|
||||
:members (types/js->clj (.-members chat))
|
||||
:hide-if-permissions-not-met (.-hideIfPermissionsNotMet chat)}
|
||||
rpc->type
|
||||
unmarshal-members))
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
(deftest normalize-chat-test
|
||||
(let [chat {:id "chat-id"
|
||||
:color "color"
|
||||
:color "yellow"
|
||||
:name "name"
|
||||
:chatType 3
|
||||
:members [{:id "a"
|
||||
@@ -26,7 +26,7 @@
|
||||
:timestamp 2}
|
||||
expected-chat {:public? false
|
||||
:group-chat true
|
||||
:color "color"
|
||||
:color :yellow
|
||||
:chat-name "name"
|
||||
:contacts #{"a" "b" "c" "d"}
|
||||
:chat-type 3
|
||||
|
||||
@@ -27,10 +27,11 @@
|
||||
(assoc acc
|
||||
(name k)
|
||||
(-> v
|
||||
(assoc :token-gated? (:tokenGated v)
|
||||
:can-post? (:canPost v)
|
||||
:can-view? (:canView v))
|
||||
(dissoc :canPost :tokenGated :canView)
|
||||
(assoc :token-gated? (:tokenGated v)
|
||||
:can-post? (:canPost v)
|
||||
:can-view? (:canView v)
|
||||
:hide-if-permissions-not-met? (:hideIfPermissionsNotMet v))
|
||||
(dissoc :canPost :tokenGated :canView :hideIfPermissionsNotMet)
|
||||
(update :members walk/stringify-keys))))
|
||||
{}
|
||||
chats))
|
||||
@@ -63,6 +64,7 @@
|
||||
:canJoin :can-join?
|
||||
:requestedToJoinAt :requested-to-join-at
|
||||
:isMember :is-member?
|
||||
:outroMessage :outro-message
|
||||
:adminSettings :admin-settings
|
||||
:tokenPermissions :token-permissions
|
||||
:communityTokensMetadata :tokens-metadata
|
||||
|
||||
@@ -64,16 +64,6 @@
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]})
|
||||
|
||||
(rf/defn create
|
||||
{:events [:group-chats.ui/create-pressed]
|
||||
:interceptors [(re-frame/inject-cofx :random-guid-generator)]}
|
||||
[{:keys [db] :as cofx} group-name]
|
||||
(let [selected-contacts (:group/selected-contacts db)]
|
||||
{:json-rpc/call [{:method "wakuext_createGroupChatWithMembers"
|
||||
:params [nil group-name (into [] selected-contacts)]
|
||||
:js-response true
|
||||
:on-success #(re-frame/dispatch [:chat-updated %])}]}))
|
||||
|
||||
(rf/defn create-from-link
|
||||
{:events [:group-chats/create-from-link]}
|
||||
[cofx {:keys [chat-id invitation-admin chat-name]}]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
(:require
|
||||
[legacy.status-im.react-native.resources :as resources]
|
||||
[legacy.status-im.ui.components.colors :as quo.colors]
|
||||
[legacy.status-im.ui.components.fast-image :as fast-image]
|
||||
[legacy.status-im.ui.screens.chat.message.legacy-style :as style]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
@@ -145,23 +144,6 @@
|
||||
[rn/text {:style (style/status-text)}]
|
||||
(-> content :parsed-text peek :children))]])
|
||||
|
||||
;; EMOJI
|
||||
(defn emoji
|
||||
[]
|
||||
(fn [{:keys [content] :as message}]
|
||||
[rn/view (style/message-view message)
|
||||
[rn/view {:style (style/message-view-content)}
|
||||
[rn/view {:style (style/style-message-text)}
|
||||
[rn/text {:style (style/emoji-message message)}
|
||||
(:text content)]]]]))
|
||||
|
||||
;; STICKER
|
||||
(defn sticker
|
||||
[{:keys [content]}]
|
||||
[fast-image/fast-image
|
||||
{:style {:margin 10 :width 140 :height 140}
|
||||
:source {:uri (str (-> content :sticker :url) "&download=true")}}])
|
||||
|
||||
(defn contact-request-status-pending
|
||||
[]
|
||||
[rn/view {:style {:flex-direction :row}}
|
||||
|
||||
@@ -91,11 +91,6 @@
|
||||
:options {:insets {:top? true}}
|
||||
:component stickers/pack}
|
||||
|
||||
{:name :new-group
|
||||
:options {:insets {:top? true}}
|
||||
;;TODO custom subtitle
|
||||
:component group-chat/new-group}
|
||||
|
||||
{:name :currency-settings
|
||||
:options {:topBar (topbar-options :t/main-currency)
|
||||
:insets {:top? true}}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
:or {size :size-20
|
||||
customization-color :blue
|
||||
picture nil
|
||||
icon-name :i/group}}]
|
||||
icon-name :i/members}}]
|
||||
(let [container-size (get-in sizes [size :container])
|
||||
icon-size (get-in sizes [size :icon])]
|
||||
[rn/view
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
[quo.components.colors.color.constants :as constants]
|
||||
[quo.components.colors.color.view :as color]
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.core :as rn]))
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]))
|
||||
|
||||
(defn get-item-layout
|
||||
[_ index]
|
||||
@@ -52,7 +53,7 @@
|
||||
:index index
|
||||
:viewPosition 0.5})))))
|
||||
50)))
|
||||
[rn/flat-list
|
||||
[gesture/flat-list
|
||||
{:ref on-ref
|
||||
;; TODO: using :feng-shui? temporarily while b & w is being developed.
|
||||
;; https://github.com/status-im/status-mobile/discussions/16676
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
;; the `:or` destructuring won't work because it's only applied when the
|
||||
;; `:customization-color` key is non-existent. While deleting an account the key exists
|
||||
;; and has a `nil` value.
|
||||
(when customization-color
|
||||
(let [color-top (colors/resolve-color customization-color 50 20)
|
||||
color-bottom (colors/resolve-color customization-color 50 0)]
|
||||
(let [color-top (colors/resolve-color customization-color 50 20)
|
||||
color-bottom (colors/resolve-color customization-color 50 0)]
|
||||
(when (and color-top color-bottom)
|
||||
[linear-gradient/linear-gradient
|
||||
{:accessibility-label :gradient-cover
|
||||
:colors [color-top color-bottom]
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:placeholder-text-color
|
||||
colors/neutral-30))))))
|
||||
colors/neutral-40))))))
|
||||
|
||||
(h/test "on blur with text blur? true"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
@@ -75,7 +75,7 @@
|
||||
(h/fire-event :on-blur (h/get-by-label-text :address-text-input))
|
||||
(h/has-prop (h/get-by-label-text :address-text-input)
|
||||
:placeholder-text-color
|
||||
colors/neutral-80-opa-20))))))
|
||||
colors/neutral-80-opa-40))))))
|
||||
|
||||
(h/test "on blur with no text and blur? false"
|
||||
(with-redefs [clipboard/get-string #(% "")]
|
||||
|
||||
@@ -58,78 +58,64 @@
|
||||
[{:keys [default-value blur? on-change-text on-blur on-focus on-clear on-scan
|
||||
on-detect-ens on-detect-address on-detect-unclassified address-regex ens-regex
|
||||
valid-ens-or-address? container-style]}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[status set-status] (rn/use-state :default)
|
||||
value (rn/use-ref-atom nil)
|
||||
[_ trigger-render-value] (rn/use-state @value)
|
||||
[focused? set-focused] (rn/use-state false)
|
||||
on-change (rn/use-callback
|
||||
(fn [text]
|
||||
(let [address? (when address-regex
|
||||
(boolean (re-matches address-regex text)))
|
||||
ens? (when ens-regex
|
||||
(boolean (re-matches ens-regex text)))]
|
||||
(reset! value text)
|
||||
(if (> (count text) 0)
|
||||
(set-status :typing)
|
||||
(set-status :active))
|
||||
(when on-change-text
|
||||
(on-change-text text))
|
||||
(when (and on-detect-ens ens?)
|
||||
(set-status :loading)
|
||||
(on-detect-ens text #(set-status :typing)))
|
||||
(when (and address? on-detect-address)
|
||||
(set-status :loading)
|
||||
(on-detect-address text))
|
||||
(when (and (not address?)
|
||||
(not ens?)
|
||||
on-detect-unclassified)
|
||||
(on-detect-unclassified text)))))
|
||||
set-value (rn/use-callback
|
||||
(fn [new-value]
|
||||
(reset! value new-value)
|
||||
(on-change new-value)
|
||||
(trigger-render-value new-value)))
|
||||
on-paste (rn/use-callback
|
||||
(fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard]
|
||||
(when-not (empty? clipboard)
|
||||
(set-value clipboard))))))
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(set-value "")
|
||||
(set-status (if focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
[focused?])
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(set-value "")
|
||||
(set-status (if focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
[focused?])
|
||||
on-scan (when on-scan (rn/use-callback #(on-scan set-value)))
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(when (= (count @value) 0)
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
[status set-status] (rn/use-state :default)
|
||||
[value set-value] (rn/use-state nil)
|
||||
[focused? set-focused] (rn/use-state false)
|
||||
on-change (rn/use-callback
|
||||
(fn [text]
|
||||
(let [address? (when address-regex
|
||||
(boolean (re-matches address-regex text)))
|
||||
ens? (when ens-regex
|
||||
(boolean (re-matches ens-regex text)))]
|
||||
(set-value text)
|
||||
(if (> (count text) 0)
|
||||
(set-status :typing)
|
||||
(set-status :active))
|
||||
(set-focused true)
|
||||
(when on-focus (on-focus))))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(when (= status :active)
|
||||
(set-status :default))
|
||||
(set-focused false)
|
||||
(when on-blur (on-blur)))
|
||||
[status])
|
||||
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
|
||||
[status theme blur?])]
|
||||
(when on-change-text
|
||||
(on-change-text text))
|
||||
(when (and on-detect-ens ens?)
|
||||
(set-status :loading)
|
||||
(on-detect-ens text #(set-status :typing)))
|
||||
(when (and address? on-detect-address)
|
||||
(set-status :loading)
|
||||
(on-detect-address text))
|
||||
(when (and (not address?)
|
||||
(not ens?)
|
||||
on-detect-unclassified)
|
||||
(on-detect-unclassified text)))))
|
||||
on-paste (rn/use-callback
|
||||
(fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard]
|
||||
(when-not (empty? clipboard)
|
||||
(on-change clipboard))))))
|
||||
on-clear (rn/use-callback
|
||||
(fn []
|
||||
(on-change "")
|
||||
(set-status (if focused? :active :default))
|
||||
(when on-change-text
|
||||
(on-change-text ""))
|
||||
(when on-clear
|
||||
(on-clear)))
|
||||
[focused?])
|
||||
on-scan (rn/use-callback #(when on-scan (on-scan on-change))
|
||||
[on-scan])
|
||||
on-focus (rn/use-callback
|
||||
(fn []
|
||||
(when (= (count value) 0)
|
||||
(set-status :active))
|
||||
(set-focused true)
|
||||
(when on-focus (on-focus))))
|
||||
on-blur (rn/use-callback
|
||||
(fn []
|
||||
(when (= status :active)
|
||||
(set-status :default))
|
||||
(set-focused false)
|
||||
(when on-blur (on-blur)))
|
||||
[status])
|
||||
placeholder-text-color (rn/use-memo #(get-placeholder-text-color status theme blur?)
|
||||
[status theme blur?])]
|
||||
(rn/use-mount #(on-change (or default-value "")))
|
||||
[rn/view {:style (style/container container-style)}
|
||||
[rn/text-input
|
||||
@@ -137,7 +123,7 @@
|
||||
:style (style/input-text theme)
|
||||
:placeholder (i18n/label :t/name-ens-or-address)
|
||||
:placeholder-text-color placeholder-text-color
|
||||
:value @value
|
||||
:value value
|
||||
:auto-complete (when platform/ios? :off)
|
||||
:auto-capitalize :none
|
||||
:auto-correct false
|
||||
|
||||
@@ -57,14 +57,19 @@
|
||||
"Custom properties that must be removed from properties map passed to InputText."
|
||||
[:type :blur? :error? :right-icon :left-icon :disabled? :small? :button
|
||||
:label :char-limit :on-char-limit-reach :icon-name :multiline? :on-focus :on-blur
|
||||
:container-style])
|
||||
:container-style :ref])
|
||||
|
||||
(defn- base-input
|
||||
[{:keys [blur? error? right-icon left-icon disabled? small? button
|
||||
label char-limit multiline? clearable? on-focus on-blur container-style
|
||||
on-change-text on-char-limit-reach weight default-value]
|
||||
on-change-text on-char-limit-reach weight default-value on-clear]
|
||||
:as props}]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
ref (rn/use-ref-atom nil)
|
||||
on-ref (rn/use-callback (fn [value]
|
||||
(when (:ref props)
|
||||
((:ref props) value))
|
||||
(reset! ref value)))
|
||||
[status set-status] (rn/use-state :default)
|
||||
internal-on-focus (rn/use-callback #(set-status :focus))
|
||||
internal-on-blur (rn/use-callback #(set-status :default))
|
||||
@@ -93,6 +98,15 @@
|
||||
:else status)
|
||||
colors-by-status (style/status-colors status-kw blur? theme)
|
||||
variant-colors (style/variants-colors blur? theme)
|
||||
clear-on-press (rn/use-callback (fn []
|
||||
(.clear ^js @ref)
|
||||
(when on-clear (on-clear)))
|
||||
[on-clear])
|
||||
right-icon (or right-icon
|
||||
(when clearable?
|
||||
{:style-fn style/clear-icon
|
||||
:icon-name :i/clear
|
||||
:on-press clear-on-press}))
|
||||
clean-props (apply dissoc props custom-props)]
|
||||
[rn/view {:style container-style}
|
||||
(when (or label char-limit)
|
||||
@@ -108,7 +122,8 @@
|
||||
:small? small?
|
||||
:icon-name icon-name}])
|
||||
[rn/text-input
|
||||
(cond-> {:style (style/input colors-by-status small? multiple-lines? weight)
|
||||
(cond-> {:ref on-ref
|
||||
:style (style/input colors-by-status small? multiple-lines? weight)
|
||||
:accessibility-label :input
|
||||
:placeholder-text-color (:placeholder colors-by-status)
|
||||
:keyboard-appearance (quo.theme/theme-value :light :dark theme)
|
||||
@@ -147,7 +162,10 @@
|
||||
[{:keys [default-shown?]
|
||||
:or {default-shown? false}
|
||||
:as props}]
|
||||
(let [[password-shown? set-password-shown] (rn/use-state default-shown?)]
|
||||
(let [[password-shown?
|
||||
set-password-shown] (rn/use-state default-shown?)
|
||||
on-press (rn/use-callback #(set-password-shown (not password-shown?))
|
||||
[password-shown?])]
|
||||
[base-input
|
||||
(assoc props
|
||||
:accessibility-label :password-input
|
||||
@@ -156,7 +174,7 @@
|
||||
:secure-text-entry (not password-shown?)
|
||||
:right-icon {:style-fn style/password-icon
|
||||
:icon-name (if password-shown? :i/hide-password :i/reveal)
|
||||
:on-press #(set-password-shown (not password-shown?))})]))
|
||||
:on-press on-press})]))
|
||||
|
||||
(defn input
|
||||
"This input supports the following properties:
|
||||
@@ -182,15 +200,11 @@
|
||||
- :on-change-text
|
||||
...
|
||||
"
|
||||
[{:keys [type clearable? on-clear icon-name]
|
||||
[{:keys [type icon-name]
|
||||
:or {type :text}
|
||||
:as props}]
|
||||
(let [base-props (cond-> props
|
||||
icon-name (assoc-in [:left-icon :icon-name] icon-name)
|
||||
clearable? (assoc :right-icon
|
||||
{:style-fn style/clear-icon
|
||||
:icon-name :i/clear
|
||||
:on-press #(when on-clear (on-clear))}))]
|
||||
icon-name (assoc-in [:left-icon :icon-name] icon-name))]
|
||||
(if (= type :password)
|
||||
[password-input base-props]
|
||||
[base-input base-props])))
|
||||
|
||||
@@ -188,21 +188,21 @@
|
||||
nil))]]])
|
||||
|
||||
(defn- view-internal
|
||||
[props]
|
||||
(let [[component-width
|
||||
[{provided-width :width :as props}]
|
||||
(let [[calculated-width
|
||||
set-component-width] (rn/use-state nil)
|
||||
on-layout (rn/use-callback #(set-component-width
|
||||
(oops/oget % "nativeEvent.layout.width")))
|
||||
props (-> props
|
||||
(assoc :component-width component-width)
|
||||
(assoc :component-width (or provided-width calculated-width))
|
||||
(clojure.set/rename-keys {:type :share-qr-type}))]
|
||||
[quo.theme/provider {:theme :dark}
|
||||
[rn/view
|
||||
{:accessibility-label :share-qr-code
|
||||
:style style/outer-container
|
||||
:on-layout on-layout}
|
||||
:on-layout (when-not provided-width on-layout)}
|
||||
[rn/view {:style {:background-color style/overlay-color}}
|
||||
(when component-width
|
||||
(when (:component-width props)
|
||||
[share-qr-code props])]]]))
|
||||
|
||||
(def view (schema/instrument #'view-internal component-schema/?schema))
|
||||
|
||||
@@ -100,8 +100,7 @@
|
||||
:or {customization-color :blue}}]
|
||||
(let [time-frame-string (time-string time-frame time-frame-string)
|
||||
up? (= metrics :positive)]
|
||||
[rn/view
|
||||
{:style style/account-overview-wrapper}
|
||||
[rn/view {:style style/account-overview-wrapper}
|
||||
(if (= :loading state)
|
||||
[loading-state (colors/theme-colors colors/neutral-5 colors/neutral-90 theme)]
|
||||
[rn/view
|
||||
@@ -113,19 +112,17 @@
|
||||
:size :heading-1
|
||||
:style style/current-value}
|
||||
current-value]
|
||||
[rn/view
|
||||
{:style style/row-centered}
|
||||
[:<>
|
||||
(when (seq time-frame-string)
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/bottom-time-text (and (not= :custom time-frame)
|
||||
(seq time-frame-to-string)))}
|
||||
time-frame-string])
|
||||
(when (and (= :custom time-frame)
|
||||
(seq time-frame-to-string))
|
||||
[custom-time-frame time-frame-to-string])]
|
||||
[rn/view {:style style/row-centered}
|
||||
(when (seq time-frame-string)
|
||||
[text/text
|
||||
{:weight :medium
|
||||
:size :paragraph-2
|
||||
:style (style/bottom-time-text (and (not= :custom time-frame)
|
||||
(seq time-frame-to-string)))}
|
||||
time-frame-string])
|
||||
(when (and (= :custom time-frame)
|
||||
(seq time-frame-to-string))
|
||||
[custom-time-frame time-frame-to-string])
|
||||
(when (and (seq percentage-change)
|
||||
(seq currency-change))
|
||||
[numeric-changes percentage-change currency-change customization-color theme up?])]])]))
|
||||
|
||||
+13
-11
@@ -156,17 +156,19 @@
|
||||
(defn get-js-deps
|
||||
[deps]
|
||||
(if deps
|
||||
(let [prev-state (use-ref-atom {:value false :deps nil})
|
||||
prev-deps (:deps @prev-state)
|
||||
prev-value (:value @prev-state)]
|
||||
(if (and (not (nil? prev-deps)) (not= (count deps) (count prev-deps)))
|
||||
(throw (js/Error. "Hooks can't have a different number of dependencies across re-renders"))
|
||||
(if (not= deps prev-deps)
|
||||
(let [new-value (not prev-value)]
|
||||
(reset! prev-state {:value new-value
|
||||
:deps deps})
|
||||
#js [new-value])
|
||||
#js [prev-value])))
|
||||
(if (empty? deps)
|
||||
#js [true]
|
||||
(let [prev-state (use-ref-atom {:value false :deps nil})
|
||||
prev-deps (:deps @prev-state)
|
||||
prev-value (:value @prev-state)]
|
||||
(if (and (not (nil? prev-deps)) (not= (count deps) (count prev-deps)))
|
||||
(throw (js/Error. "Hooks can't have a different number of dependencies across re-renders"))
|
||||
(if (not= deps prev-deps)
|
||||
(let [new-value (not prev-value)]
|
||||
(reset! prev-state {:value new-value
|
||||
:deps deps})
|
||||
#js [new-value])
|
||||
#js [prev-value]))))
|
||||
js/undefined))
|
||||
|
||||
(defn use-effect
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
db (assoc-in db [:alert-banners (:type banner)] banner)]
|
||||
(cond-> {:db db}
|
||||
(zero? current-banners-count)
|
||||
(assoc :show-alert-banner nil))))
|
||||
(assoc :show-alert-banner (:view-id db)))))
|
||||
|
||||
(defn remove-alert-banner
|
||||
[{:keys [db]} [banner-type]]
|
||||
@@ -15,12 +15,12 @@
|
||||
new-count (count (get db :alert-banners))]
|
||||
(cond-> {:db db}
|
||||
(zero? new-count)
|
||||
(assoc :hide-alert-banner nil))))
|
||||
(assoc :hide-alert-banner (:view-id db)))))
|
||||
|
||||
(defn remove-all-alert-banners
|
||||
[{:keys [db]}]
|
||||
{:db (dissoc db :alert-banners)
|
||||
:hide-alert-banner nil})
|
||||
:hide-alert-banner (:view-id db)})
|
||||
|
||||
(re-frame/reg-event-fx :alert-banners/add add-alert-banner)
|
||||
(re-frame/reg-event-fx :alert-banners/remove remove-alert-banner)
|
||||
|
||||
@@ -148,28 +148,26 @@
|
||||
(reset! search-text ""))
|
||||
|
||||
(defn f-view
|
||||
[{:keys [search-text on-change-text clear-states active-category scroll-ref theme]
|
||||
[{:keys [search-active? on-change-text clear-states active-category scroll-ref theme]
|
||||
:as sheet-opts}]
|
||||
(let [search-active? (pos? (count @search-text))]
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/flex-spacer
|
||||
:keyboard-vertical-offset 8}
|
||||
[rn/view {:style style/flex-spacer}
|
||||
[rn/view {:style style/search-input-container}
|
||||
[quo/input
|
||||
{:small? true
|
||||
:placeholder (i18n/label :t/emoji-search-placeholder)
|
||||
:icon-name :i/search
|
||||
:value @search-text
|
||||
:on-change-text on-change-text
|
||||
:clearable? search-active?
|
||||
:on-clear clear-states}]]
|
||||
[render-list sheet-opts]
|
||||
(when-not search-active?
|
||||
[footer
|
||||
{:theme theme
|
||||
:active-category active-category
|
||||
:scroll-ref scroll-ref}])]]))
|
||||
[rn/keyboard-avoiding-view
|
||||
{:style style/flex-spacer
|
||||
:keyboard-vertical-offset 8}
|
||||
[rn/view {:style style/flex-spacer}
|
||||
[rn/view {:style style/search-input-container}
|
||||
[quo/input
|
||||
{:small? true
|
||||
:placeholder (i18n/label :t/emoji-search-placeholder)
|
||||
:icon-name :i/search
|
||||
:on-change-text on-change-text
|
||||
:clearable? search-active?
|
||||
:on-clear clear-states}]]
|
||||
[render-list sheet-opts]
|
||||
(when-not search-active?
|
||||
[footer
|
||||
{:theme theme
|
||||
:active-category active-category
|
||||
:scroll-ref scroll-ref}])]])
|
||||
|
||||
(defn- view-internal
|
||||
[_]
|
||||
@@ -202,7 +200,7 @@
|
||||
(fn [sheet-opts]
|
||||
[:f> f-view
|
||||
(assoc sheet-opts
|
||||
:search-text search-text
|
||||
:search-active? (pos? (count @search-text))
|
||||
:on-change-text on-change-text
|
||||
:clear-states clear-states
|
||||
:filtered-data @filtered-data
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
[oops.core :as oops]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.gesture :as gesture]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
@@ -90,7 +91,7 @@
|
||||
{:on-layout set-header-height
|
||||
:style header-container-style}
|
||||
header]
|
||||
[rn/scroll-view
|
||||
[gesture/scroll-view
|
||||
{:on-scroll set-content-y-scroll
|
||||
:scroll-event-throttle 64
|
||||
:content-container-style {:flex-grow 1}}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.common.home.banner.style
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[react-native.platform :as platform]
|
||||
[react-native.reanimated :as reanimated]
|
||||
[react-native.safe-area :as safe-area]))
|
||||
@@ -23,27 +24,29 @@
|
||||
(reanimated/interpolate scroll-shared-value [0 max-scroll] [0 (+ max-scroll)] :clamp))
|
||||
|
||||
(defn banner-card-blur-layer
|
||||
[scroll-shared-value]
|
||||
[scroll-shared-value theme]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:translate-y (animated-card-translation-y scroll-shared-value)}]}
|
||||
{:overflow (if platform/ios? :visible :hidden)
|
||||
:z-index 1
|
||||
:position :absolute
|
||||
:top 0
|
||||
:right 0
|
||||
:left 0
|
||||
:height (+ (safe-area/get-top) 244)}))
|
||||
{:overflow (if platform/ios? :visible :hidden)
|
||||
:z-index 1
|
||||
:position :absolute
|
||||
:top 0
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
|
||||
:right 0
|
||||
:left 0
|
||||
:height (+ (safe-area/get-top) 244)}))
|
||||
|
||||
(defn banner-card-hiding-layer
|
||||
[scroll-shared-value]
|
||||
[scroll-shared-value theme]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:translate-y (animated-card-translation-y-reverse scroll-shared-value)}]}
|
||||
{:z-index 2
|
||||
:position :absolute
|
||||
:top 0
|
||||
:right 0
|
||||
:left 0
|
||||
:padding-top (safe-area/get-top)}))
|
||||
{:z-index 2
|
||||
:position :absolute
|
||||
:top 0
|
||||
:right 0
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
|
||||
:left 0
|
||||
:padding-top (+ (safe-area/get-top) 8)}))
|
||||
|
||||
(defn animated-banner-card
|
||||
[scroll-shared-value]
|
||||
@@ -53,16 +56,17 @@
|
||||
{}))
|
||||
|
||||
(defn banner-card-tabs-layer
|
||||
[scroll-shared-value]
|
||||
[scroll-shared-value theme]
|
||||
(reanimated/apply-animations-to-style
|
||||
{:transform [{:translate-y (animated-card-translation-y scroll-shared-value)}]}
|
||||
{:z-index 3
|
||||
:position :absolute
|
||||
:top (+ (safe-area/get-top) 192)
|
||||
:right 0
|
||||
:left 0}))
|
||||
{:z-index 3
|
||||
:position :absolute
|
||||
:top (+ (safe-area/get-top) 192)
|
||||
:right 0
|
||||
:background-color (colors/theme-colors colors/white colors/neutral-95 theme)
|
||||
:left 0}))
|
||||
|
||||
(def banner-card-tabs
|
||||
{:padding-horizontal 20
|
||||
:padding-top 8
|
||||
:padding-bottom 12})
|
||||
:padding-top 12
|
||||
:padding-bottom 16})
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[oops.core :as oops]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme :as theme]
|
||||
[quo.theme]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
@@ -31,21 +31,22 @@
|
||||
|
||||
(defn- banner-card-blur-layer
|
||||
[scroll-shared-value child]
|
||||
(let [open-sheet? (-> (rf/sub [:bottom-sheet]) :sheets seq)]
|
||||
[reanimated/view {:style (style/banner-card-blur-layer scroll-shared-value)}
|
||||
(let [open-sheet? (-> (rf/sub [:bottom-sheet]) :sheets seq)
|
||||
theme (quo.theme/use-theme-value)]
|
||||
[reanimated/view {:style (style/banner-card-blur-layer scroll-shared-value theme)}
|
||||
[blur/view
|
||||
{:style style/fill-space
|
||||
:blur-amount (if platform/ios? 20 10)
|
||||
:blur-type (theme/theme-value (if platform/ios? :light :xlight) :dark)
|
||||
:blur-type (quo.theme/theme-value (if platform/ios? :light :xlight) :dark)
|
||||
:overlay-color (if open-sheet?
|
||||
(colors/theme-colors colors/white colors/neutral-95-opa-70)
|
||||
(theme/theme-value nil colors/neutral-95-opa-70))}
|
||||
(quo.theme/theme-value nil colors/neutral-95-opa-70))}
|
||||
child]]))
|
||||
|
||||
(defn- banner-card-hiding-layer
|
||||
[{:keys [title-props card-props scroll-shared-value]}]
|
||||
[{:keys [title-props card-props scroll-shared-value theme]}]
|
||||
(let [customization-color (rf/sub [:profile/customization-color])]
|
||||
[reanimated/view {:style (style/banner-card-hiding-layer scroll-shared-value)}
|
||||
[reanimated/view {:style (style/banner-card-hiding-layer scroll-shared-value theme)}
|
||||
[top-nav/view]
|
||||
[title-column/view (assoc title-props :customization-color customization-color)]
|
||||
[rn/view {:style {:overflow @card-banner-overflow}}
|
||||
@@ -53,8 +54,8 @@
|
||||
[quo/discover-card card-props]]]]))
|
||||
|
||||
(defn- banner-card-tabs-layer
|
||||
[{:keys [selected-tab tabs on-tab-change scroll-ref scroll-shared-value customization-color]}]
|
||||
[reanimated/view {:style (style/banner-card-tabs-layer scroll-shared-value)}
|
||||
[{:keys [selected-tab tabs on-tab-change scroll-ref scroll-shared-value customization-color theme]}]
|
||||
[reanimated/view {:style (style/banner-card-tabs-layer scroll-shared-value theme)}
|
||||
^{:key (str "tabs-" selected-tab)}
|
||||
[quo/tabs
|
||||
{:style style/banner-card-tabs
|
||||
@@ -71,16 +72,19 @@
|
||||
|
||||
(defn animated-banner
|
||||
[{:keys [scroll-ref tabs selected-tab on-tab-change scroll-shared-value content customization-color]}]
|
||||
[:<>
|
||||
[:f> banner-card-blur-layer scroll-shared-value
|
||||
[:f> banner-card-hiding-layer (assoc content :scroll-shared-value scroll-shared-value)]]
|
||||
[:f> banner-card-tabs-layer
|
||||
{:scroll-shared-value scroll-shared-value
|
||||
:selected-tab selected-tab
|
||||
:tabs tabs
|
||||
:on-tab-change on-tab-change
|
||||
:scroll-ref scroll-ref
|
||||
:customization-color customization-color}]])
|
||||
(let [theme (quo.theme/use-theme-value)]
|
||||
[:<>
|
||||
[:f> banner-card-blur-layer scroll-shared-value
|
||||
[:f> banner-card-hiding-layer
|
||||
(assoc content :scroll-shared-value scroll-shared-value :theme theme)]]
|
||||
[:f> banner-card-tabs-layer
|
||||
{:scroll-shared-value scroll-shared-value
|
||||
:selected-tab selected-tab
|
||||
:tabs tabs
|
||||
:on-tab-change on-tab-change
|
||||
:scroll-ref scroll-ref
|
||||
:customization-color customization-color
|
||||
:theme theme}]]))
|
||||
|
||||
(defn set-scroll-shared-value
|
||||
[{:keys [shared-value scroll-input]}]
|
||||
|
||||
@@ -89,4 +89,3 @@
|
||||
:i/face-id])]
|
||||
(when error?
|
||||
[error-info error-message processing shell?])]))
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
(update :toasts dissoc :hide-toasts-timer-set))}
|
||||
|
||||
(and (not update?) (= (count ordered) 1))
|
||||
(assoc :show-toasts [])
|
||||
(assoc :show-toasts (:view-id db))
|
||||
|
||||
(not (:id opts))
|
||||
(update-in [:db :toasts :next-toast-number] inc))))
|
||||
@@ -28,8 +28,9 @@
|
||||
{:events [:toasts/hide-with-check]}
|
||||
[{:keys [db]}]
|
||||
(when (get-in db [:toasts :hide-toasts-timer-set])
|
||||
{:db (update db :toasts dissoc :hide-toasts-timer-set)
|
||||
:hide-toasts nil}))
|
||||
{:db (update db :toasts dissoc :hide-toasts-timer-set)
|
||||
:hide-toasts nil
|
||||
:reload-status-nav-color-fx (:view-id db)}))
|
||||
|
||||
(rf/defn close
|
||||
{:events [:toasts/close]}
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
(ns status-im.common.validation.profile
|
||||
(:require [clojure.string :as string]
|
||||
[status-im.constants :as constants]
|
||||
utils.emojilib
|
||||
[utils.i18n :as i18n]))
|
||||
|
||||
;; NOTE - validation should match with Desktop
|
||||
;; https://github.com/status-im/status-desktop/blob/2ba96803168461088346bf5030df750cb226df4c/ui/imports/utils/Constants.qml#L468
|
||||
(def min-length 5)
|
||||
|
||||
(def emoji-regex
|
||||
#"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])")
|
||||
|
||||
(def status-regex #"^[a-zA-Z0-9\-_ ]+$")
|
||||
|
||||
(def common-names ["Ethereum" "Bitcoin"])
|
||||
|
||||
(defn has-emojis? [s] (boolean (re-find emoji-regex s)))
|
||||
(defn has-emojis? [s] (boolean (re-find utils.emojilib/emoji-regex s)))
|
||||
|
||||
(defn has-common-names? [s] (pos? (count (filter #(string/includes? s %) common-names))))
|
||||
|
||||
|
||||
@@ -122,6 +122,7 @@
|
||||
|
||||
(def ^:const min-password-length 6)
|
||||
(def ^:const max-group-chat-participants 20)
|
||||
(def ^:const max-group-chat-name-length 24)
|
||||
(def ^:const default-number-of-messages 20)
|
||||
(def ^:const default-number-of-pin-messages 3)
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.contacts.events :as contacts-store]
|
||||
status-im.contexts.chat.effects
|
||||
status-im.contexts.chat.group-create.events
|
||||
[status-im.contexts.chat.messenger.composer.link-preview.events :as link-preview]
|
||||
status-im.contexts.chat.messenger.messages.content.reactions.events
|
||||
[status-im.contexts.chat.messenger.messages.delete-message-for-me.events :as delete-for-me]
|
||||
@@ -78,17 +79,10 @@
|
||||
:invitation-admin
|
||||
(:invitation-admin chat)))))
|
||||
|
||||
(rf/defn leave-removed-chat
|
||||
{:events [:chat/leave-removed-chat]}
|
||||
[{{:keys [view-id current-chat-id chats]} :db
|
||||
:as cofx}]
|
||||
(when (and (= view-id :chat)
|
||||
(not (contains? chats current-chat-id)))
|
||||
(navigation/navigate-back cofx)))
|
||||
|
||||
(defn ensure-chats
|
||||
[{:keys [db] :as cofx} [chats]]
|
||||
(let [{:keys [all-chats chats-home-list removed-chats]}
|
||||
(let [{:keys [view-id current-chat-id]} db
|
||||
{:keys [all-chats chats-home-list removed-chats]}
|
||||
(reduce
|
||||
(fn [acc {:keys [chat-id profile-public-key timeline? community-id active muted] :as chat}]
|
||||
(if (not (or active muted))
|
||||
@@ -109,7 +103,8 @@
|
||||
(update :chats-home-list set/difference removed-chats))
|
||||
:fx [(when (not-empty removed-chats)
|
||||
[:effects/push-notifications-clear-message-notifications removed-chats])
|
||||
[:dispatch [:chat/leave-removed-chat]]]}))
|
||||
(when (and (= view-id :chat) (removed-chats current-chat-id))
|
||||
[:dispatch [:navigate-back]])]}))
|
||||
|
||||
(re-frame/reg-event-fx :chat/ensure-chats ensure-chats)
|
||||
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
(ns status-im.contexts.chat.group-create.events
|
||||
(:require [legacy.status-im.data-store.chats :as data-store.chats]
|
||||
[oops.core :as oops]
|
||||
[re-frame.core :as rf]))
|
||||
|
||||
(rf/reg-event-fx :group-chat/create
|
||||
(fn [{:keys [db]} [group-name color image]]
|
||||
(let [selected-contacts (:group/selected-contacts db)]
|
||||
{:json-rpc/call [{:method "wakuext_createGroupChatWithMembers"
|
||||
:params [nil group-name (into [] selected-contacts)]
|
||||
:js-response true
|
||||
:on-success (fn [response]
|
||||
(let [chat-id (-> (oops/oget response :chats)
|
||||
first
|
||||
(oops/oget :id))]
|
||||
(rf/dispatch [:chat-updated response])
|
||||
(rf/dispatch [:group-chat/edit
|
||||
{:chat-id chat-id
|
||||
:group-name group-name
|
||||
:color color
|
||||
:image image}])))}]})))
|
||||
|
||||
(rf/reg-event-fx :group-chat/edit-success
|
||||
(fn [{:keys [db]} [{:keys [chat-id name color image]}]]
|
||||
(let [new-chat {:name name :color color :image image}]
|
||||
{:db (update-in db [:chats chat-id] #(merge % new-chat))})))
|
||||
|
||||
(rf/reg-event-fx :group-chat/edit
|
||||
(fn [_ [{:keys [chat-id group-name color image]}]]
|
||||
{:json-rpc/call [{:method "chat_editChat"
|
||||
:params ["" chat-id group-name (name color) image]
|
||||
:js-response true
|
||||
:on-success #(rf/dispatch [:group-chat/edit-success
|
||||
(data-store.chats/<-rpc-js %)])}]}))
|
||||
@@ -0,0 +1,22 @@
|
||||
(ns status-im.contexts.chat.group-create.style
|
||||
(:require [quo.foundations.colors :as colors]))
|
||||
|
||||
(def avatar {:width 88 :margin-top 12 :margin-left 20})
|
||||
|
||||
(def hole
|
||||
{:y (- 80 32)
|
||||
:x (+ (- 80 32) 8)
|
||||
:width 32
|
||||
:height 32
|
||||
:borderRadius 10})
|
||||
|
||||
(def camera {:position :absolute :right 0 :bottom 0})
|
||||
|
||||
(defn color-label
|
||||
[theme]
|
||||
{:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)
|
||||
:padding-horizontal 20})
|
||||
|
||||
(def tags {:flex-direction :row :flex-wrap :wrap :padding-horizontal 20 :padding-top 12})
|
||||
|
||||
(def tag {:margin-right 8 :margin-bottom 8})
|
||||
@@ -0,0 +1,132 @@
|
||||
(ns status-im.contexts.chat.group-create.view
|
||||
(:require [clojure.string :as string]
|
||||
[quo.core :as quo]
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[status-im.common.floating-button-page.view :as floating-button-page]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.group-create.style :as style]
|
||||
[status-im.contexts.profile.utils :as profile.utils]
|
||||
[utils.debounce :as debounce]
|
||||
utils.emojilib
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.responsiveness :as responsiveness]))
|
||||
|
||||
(defn avatar
|
||||
[{:keys [customization-color]}]
|
||||
[rn/pressable {:style style/avatar}
|
||||
;;NOTE with hole-view group-avatar doesn't change it's background color
|
||||
#_[hole-view/hole-view
|
||||
{:holes [style/hole]}]
|
||||
[quo/group-avatar
|
||||
{:customization-color customization-color
|
||||
:size :size-80}]
|
||||
[quo/button
|
||||
{:on-press (fn []
|
||||
#_(rf/dispatch
|
||||
[:show-bottom-sheet
|
||||
{:content (fn []
|
||||
[profile-picture-picker/view
|
||||
{:update-profile-pic-callback on-change-profile-pic
|
||||
:has-picture? has-picture?}])
|
||||
:theme :dark
|
||||
:shell? true}]))
|
||||
:container-style style/camera
|
||||
:icon-only? true
|
||||
:type :grey
|
||||
:background :photo
|
||||
:size 32}
|
||||
:i/camera]])
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [theme (quo.theme/use-theme-value)
|
||||
{window-width :width} (rn/get-window)
|
||||
profile (rf/sub [:profile/profile-with-image])
|
||||
contacts (rf/sub [:selected-group-contacts])
|
||||
contacts-count (count contacts)
|
||||
default-value (rn/use-memo
|
||||
(fn []
|
||||
(let [contact-string (string/join ", "
|
||||
(map
|
||||
profile.utils/displayed-name
|
||||
contacts))]
|
||||
(subs contact-string
|
||||
0
|
||||
(min (count contact-string)
|
||||
constants/max-group-chat-name-length))))
|
||||
[])
|
||||
[group-name set-group-name] (rn/use-state default-value)
|
||||
[error-message
|
||||
set-error-message] (rn/use-state nil)
|
||||
group-name-empty? (not (and (string? group-name) (not-empty group-name)))
|
||||
[group-color set-group-color] (rn/use-state (rand-nth colors/account-colors))
|
||||
create-group-on-press (rn/use-callback #(debounce/throttle-and-dispatch
|
||||
[:group-chat/create group-name group-color]
|
||||
300)
|
||||
[group-name group-color])
|
||||
back-on-press (rn/use-callback #(rf/dispatch [:navigate-back]))
|
||||
on-change-text (rn/use-callback
|
||||
(fn [text]
|
||||
(if (boolean (re-find utils.emojilib/emoji-regex text))
|
||||
(set-error-message (i18n/label :t/are-not-allowed
|
||||
{:check (i18n/label
|
||||
:t/emojis)}))
|
||||
(set-error-message nil))
|
||||
(set-group-name text)))]
|
||||
[floating-button-page/view
|
||||
{:customization-color group-color
|
||||
:gradient-cover? true
|
||||
:header-container-style {:margin-top 8}
|
||||
:header [quo/page-nav
|
||||
{:background :photo
|
||||
:type :no-title
|
||||
:icon-name :i/arrow-left
|
||||
:on-press back-on-press}]
|
||||
:footer [quo/button
|
||||
{:customization-color group-color
|
||||
:disabled? (boolean (or group-name-empty? error-message))
|
||||
:on-press create-group-on-press}
|
||||
(i18n/label :t/create-group-chat)]}
|
||||
[:<>
|
||||
[avatar {:customization-color group-color}]
|
||||
[quo/title-input
|
||||
{:on-change-text on-change-text
|
||||
:default-value default-value
|
||||
:container-style {:padding-horizontal 20 :padding-top 12 :padding-bottom (if error-message 0 16)}
|
||||
:placeholder (i18n/label :t/name-your-group)
|
||||
:max-length constants/max-group-chat-name-length}]
|
||||
(when error-message
|
||||
[quo/info-message
|
||||
{:type :error
|
||||
:icon :i/info
|
||||
:size :default
|
||||
:style {:margin-top 8 :margin-left 20 :margin-bottom 16}}
|
||||
error-message])
|
||||
[quo/divider-line]
|
||||
[rn/view
|
||||
{:style {:padding-vertical 7}}
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :medium
|
||||
:style (style/color-label theme)}
|
||||
(i18n/label :t/accent-colour)]
|
||||
[quo/color-picker
|
||||
{:default-selected group-color
|
||||
:on-change set-group-color
|
||||
:container-style {:padding-top 15
|
||||
:padding-bottom 9
|
||||
:padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width
|
||||
window-width)}}]]
|
||||
[quo/divider-label
|
||||
(i18n/label :t/n-m-people {:n (inc contacts-count) :m constants/max-group-chat-participants})]
|
||||
[rn/view {:style style/tags}
|
||||
(for [contact (conj contacts profile)]
|
||||
^{:key contact}
|
||||
[quo/context-tag
|
||||
{:container-style style/tag
|
||||
:size 24
|
||||
:profile-picture (profile.utils/photo contact)
|
||||
:full-name (profile.utils/displayed-name contact)}])]]]))
|
||||
@@ -135,7 +135,7 @@
|
||||
{:container-style style/actions-view
|
||||
:actions [{:accessibility-label :pinned-messages
|
||||
:label (i18n/label :t/pinned-messages)
|
||||
:color color
|
||||
:customization-color color
|
||||
:icon :i/pin
|
||||
:counter-value (count pinned-messages)
|
||||
:on-press (fn []
|
||||
@@ -143,14 +143,14 @@
|
||||
(rf/dispatch [:pin-message/show-pins-bottom-sheet
|
||||
chat-id]))}
|
||||
{:accessibility-label :toggle-mute
|
||||
:color color
|
||||
:customization-color color
|
||||
:icon (if muted :i/muted :i/activity-center)
|
||||
:label (i18n/label (if muted :unmute-group :mute-group))
|
||||
:on-press #(rf/dispatch [:chat.ui/mute chat-id (not muted)
|
||||
(when-not muted
|
||||
constants/mute-till-unmuted)])}
|
||||
{:accessibility-label :manage-members
|
||||
:color color
|
||||
:customization-color color
|
||||
:icon :i/add-user
|
||||
:label (i18n/label (if admin? :t/manage-members :t/add-members))
|
||||
:counter-value (count contacts)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
[quo.core :as quo]
|
||||
[react-native.clipboard :as clipboard]
|
||||
[react-native.core :as rn]
|
||||
[reagent.core :as reagent]
|
||||
[status-im.contexts.chat.home.add-new-contact.style :as style]
|
||||
[utils.address :as address]
|
||||
[utils.debounce :as debounce]
|
||||
@@ -51,57 +50,66 @@
|
||||
|
||||
(defn- search-input
|
||||
[]
|
||||
(reagent/with-let [input-value (reagent/atom nil)
|
||||
input-ref (atom nil)
|
||||
clear-input (fn []
|
||||
(reset! input-value nil)
|
||||
(rf/dispatch [:contacts/clear-new-identity]))
|
||||
paste-on-input #(clipboard/get-string
|
||||
(fn [clipboard-text]
|
||||
(reset! input-value clipboard-text)
|
||||
(rf/dispatch [:contacts/set-new-identity
|
||||
{:input clipboard-text}])))]
|
||||
(let [{:keys [scanned] contact-public-key :id} (rf/sub [:contacts/new-identity])
|
||||
contact-public-key-or-scanned (or contact-public-key scanned)
|
||||
empty-input? (and (string/blank? @input-value)
|
||||
(string/blank? contact-public-key-or-scanned))]
|
||||
[rn/view {:style style/input-and-scan-container}
|
||||
[quo/input
|
||||
{:accessibility-label :enter-contact-code-input
|
||||
:ref #(reset! input-ref %)
|
||||
:container-style {:flex 1}
|
||||
:auto-capitalize :none
|
||||
:multiline? true
|
||||
:blur-on-submit true
|
||||
:return-key-type :done
|
||||
:label (i18n/label :t/ens-or-chat-key)
|
||||
:placeholder (i18n/label :t/type-some-chat-key)
|
||||
:clearable? (not empty-input?)
|
||||
:on-clear clear-input
|
||||
:button (when empty-input?
|
||||
{:on-press paste-on-input
|
||||
:text (i18n/label :t/paste)})
|
||||
;; NOTE: `contact-public-key-or-scanned` has priority over `@input-value`,
|
||||
;; we clean it when the input is updated so that it's `nil` and
|
||||
;; `@input-value`is shown. To fastly clean it, we use `dispatch-sync`.
|
||||
;; This call could be avoided if `::qr-scanner/scan-code` were able to
|
||||
;; receive a callback function, not only a re-frame event as callback.
|
||||
:value (or contact-public-key-or-scanned @input-value)
|
||||
:on-change-text (fn [new-text]
|
||||
(reset! input-value new-text)
|
||||
(as-> [:contacts/set-new-identity {:input new-text}] $
|
||||
(if (string/blank? contact-public-key-or-scanned)
|
||||
(debounce/debounce-and-dispatch $ 600)
|
||||
(rf/dispatch-sync $))))}]
|
||||
[rn/view {:style style/scan-button-container}
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:icon-only? true
|
||||
:size 40
|
||||
:on-press #(rf/dispatch [:open-modal :scan-profile-qr-code])}
|
||||
:i/scan]]])
|
||||
(finally
|
||||
(rf/dispatch [:contacts/clear-new-identity]))))
|
||||
(let [[input-value set-input-value] (rn/use-state nil)
|
||||
input-ref (rn/use-ref-atom nil)
|
||||
on-ref (rn/use-callback #(reset! input-ref %))
|
||||
{:keys [scanned]
|
||||
contact-public-key :id} (rf/sub [:contacts/new-identity])
|
||||
contact-public-key-or-scanned (or contact-public-key scanned)
|
||||
empty-input? (and (string/blank? input-value)
|
||||
(string/blank? contact-public-key-or-scanned))
|
||||
clear-input (rn/use-callback
|
||||
(fn []
|
||||
(set-input-value nil)
|
||||
(rf/dispatch [:contacts/clear-new-identity])))
|
||||
paste-on-input (rn/use-callback
|
||||
(fn []
|
||||
(clipboard/get-string
|
||||
(fn [clipboard-text]
|
||||
(set-input-value clipboard-text)
|
||||
(rf/dispatch [:contacts/set-new-identity
|
||||
{:input clipboard-text}])))))
|
||||
on-change-text (rn/use-callback
|
||||
(fn [new-text]
|
||||
(set-input-value new-text)
|
||||
(if (string/blank? contact-public-key-or-scanned)
|
||||
(debounce/debounce-and-dispatch [:contacts/set-new-identity
|
||||
{:input new-text}]
|
||||
600)
|
||||
(rf/dispatch-sync [:contacts/set-new-identity
|
||||
{:input new-text}])))
|
||||
[contact-public-key-or-scanned])]
|
||||
(rn/use-unmount #(rf/dispatch [:contacts/clear-new-identity]))
|
||||
[rn/view {:style style/input-and-scan-container}
|
||||
[quo/input
|
||||
{:accessibility-label :enter-contact-code-input
|
||||
:ref on-ref
|
||||
:container-style {:flex 1}
|
||||
:auto-capitalize :none
|
||||
:multiline? true
|
||||
:blur-on-submit true
|
||||
:return-key-type :done
|
||||
:label (i18n/label :t/ens-or-chat-key)
|
||||
:placeholder (i18n/label :t/type-some-chat-key)
|
||||
:clearable? (not empty-input?)
|
||||
:on-clear clear-input
|
||||
:button (when empty-input?
|
||||
{:on-press paste-on-input
|
||||
:text (i18n/label :t/paste)})
|
||||
;; NOTE: `contact-public-key-or-scanned` has priority over `input-value`,
|
||||
;; we clean it when the input is updated so that it's `nil` and
|
||||
;; `input-value`is shown. To fastly clean it, we use `dispatch-sync`.
|
||||
;; This call could be avoided if `::qr-scanner/scan-code` were able to
|
||||
;; receive a callback function, not only a re-frame event as callback.
|
||||
:value (or contact-public-key-or-scanned input-value)
|
||||
:on-change-text on-change-text}]
|
||||
[rn/view {:style style/scan-button-container}
|
||||
[quo/button
|
||||
{:type :outline
|
||||
:icon-only? true
|
||||
:size 40
|
||||
:on-press #(rf/dispatch [:open-modal :scan-profile-qr-code])}
|
||||
:i/scan]]]))
|
||||
|
||||
(defn- invalid-text
|
||||
[message]
|
||||
|
||||
@@ -148,7 +148,7 @@
|
||||
:on-press (fn []
|
||||
(if one-contact-selected?
|
||||
(rf/dispatch [:chat.ui/start-chat public-key])
|
||||
(rf/dispatch [:navigate-to :new-group])))}
|
||||
(rf/dispatch [:open-modal :group-create])))}
|
||||
(if one-contact-selected?
|
||||
(i18n/label :t/chat-with {:selected-user primary-name})
|
||||
(i18n/label :t/setup-group-chat))]])]))
|
||||
|
||||
@@ -38,7 +38,8 @@
|
||||
(let [cache (get-in db [:chat/link-previews :cache])
|
||||
previews (urls->previews cache urls)
|
||||
new-urls (->> previews
|
||||
(filter :loading?)
|
||||
(filter (fn [{:keys [loading? status-link-preview?]}]
|
||||
(or loading? status-link-preview?)))
|
||||
(map :url))
|
||||
;; `request-id` is a must because we need to process only the last
|
||||
;; unfurling event, as well as avoid needlessly updating the app db
|
||||
@@ -139,14 +140,18 @@
|
||||
sent."
|
||||
{:events [:link-preview/reset-unfurled]}
|
||||
[{:keys [db]}]
|
||||
{:db (update db :chat/link-previews dissoc :unfurled :request-id :cleared)})
|
||||
{:db (-> db
|
||||
(update :chat/link-previews dissoc :unfurled :request-id :cleared)
|
||||
(update :chat/status-link-previews dissoc :unfurled :request-id :cleared))})
|
||||
|
||||
(rf/defn reset-all
|
||||
"Reset all preview state. It is especially important to delete any cached
|
||||
URLs, as failing to do so results in its unbounded growth."
|
||||
{:events [:link-preview/reset-all]}
|
||||
[{:keys [db]}]
|
||||
{:db (dissoc db :chat/link-previews)})
|
||||
{:db (-> db
|
||||
(dissoc :chat/link-previews)
|
||||
(dissoc :chat/status-link-previews))})
|
||||
|
||||
(rf/defn clear-link-previews
|
||||
"Mark current unfurled URLs as `cleared`, meaning the user won't see previews
|
||||
@@ -156,4 +161,5 @@
|
||||
(let [unfurled-urls (set (map :url (get-in db [:chat/link-previews :unfurled])))]
|
||||
{:db (-> db
|
||||
(update :chat/link-previews dissoc :unfurled :request-id)
|
||||
(update :chat/status-link-previews dissoc :unfurled :request-id)
|
||||
(assoc-in [:chat/link-previews :cleared] unfurled-urls))}))
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
(ns status-im.contexts.chat.messenger.messages.content.emoji-message.style)
|
||||
|
||||
(defn emoji-container
|
||||
[margin-top]
|
||||
{:flex-direction :row
|
||||
:margin-top margin-top})
|
||||
|
||||
(def emoji-text
|
||||
{:font-size 36
|
||||
:line-height 42})
|
||||
@@ -0,0 +1,10 @@
|
||||
(ns status-im.contexts.chat.messenger.messages.content.emoji-message.view
|
||||
(:require [react-native.core :as rn]
|
||||
[status-im.contexts.chat.messenger.messages.content.emoji-message.style :as style]))
|
||||
|
||||
(defn view
|
||||
[{:keys [content last-in-group? pinned in-pinned-view?]}]
|
||||
(let [margin-top (if (or last-in-group? in-pinned-view? pinned) 8 0)]
|
||||
[rn/view {:style (style/emoji-container margin-top)}
|
||||
[rn/text {:style style/emoji-text}
|
||||
(:text content)]]))
|
||||
@@ -0,0 +1,10 @@
|
||||
(ns status-im.contexts.chat.messenger.messages.content.sticker-message.view
|
||||
(:require [react-native.core :as rn]
|
||||
[react-native.fast-image :as fast-image]))
|
||||
|
||||
(defn view
|
||||
[{:keys [url]}]
|
||||
[rn/view {:style {:margin-top 6 :margin-bottom 4}}
|
||||
[fast-image/fast-image
|
||||
{:style {:width 120 :height 120}
|
||||
:source {:uri (str url "&download=true")}}]])
|
||||
@@ -17,10 +17,12 @@
|
||||
[status-im.contexts.chat.messenger.messages.content.album.view :as album]
|
||||
[status-im.contexts.chat.messenger.messages.content.audio.view :as audio]
|
||||
[status-im.contexts.chat.messenger.messages.content.deleted.view :as content.deleted]
|
||||
[status-im.contexts.chat.messenger.messages.content.emoji-message.view :as emoji-message]
|
||||
[status-im.contexts.chat.messenger.messages.content.image.view :as image]
|
||||
[status-im.contexts.chat.messenger.messages.content.pin.view :as pin]
|
||||
[status-im.contexts.chat.messenger.messages.content.reactions.view :as reactions]
|
||||
[status-im.contexts.chat.messenger.messages.content.status.view :as status]
|
||||
[status-im.contexts.chat.messenger.messages.content.sticker-message.view :as sticker-message]
|
||||
[status-im.contexts.chat.messenger.messages.content.style :as style]
|
||||
[status-im.contexts.chat.messenger.messages.content.system.text.view :as system.text]
|
||||
[status-im.contexts.chat.messenger.messages.content.text.view :as content.text]
|
||||
@@ -150,38 +152,37 @@
|
||||
(let [show-delivery-state? (reagent/atom false)]
|
||||
(fn [{:keys [message-data context keyboard-shown? show-reactions? in-reaction-and-action-menu?
|
||||
show-user-info? preview? theme]}]
|
||||
(let [{:keys [content-type quoted-message content
|
||||
outgoing outgoing-status pinned-by
|
||||
message-id chat-id]} message-data
|
||||
{:keys [disable-message-long-press?]} context
|
||||
first-image (first (:album message-data))
|
||||
outgoing-status (if (= content-type
|
||||
constants/content-type-album)
|
||||
(:outgoing-status first-image)
|
||||
outgoing-status)
|
||||
outgoing (if (= content-type
|
||||
constants/content-type-album)
|
||||
(:outgoing first-image)
|
||||
outgoing)
|
||||
context (assoc context
|
||||
:on-long-press
|
||||
#(on-long-press message-data
|
||||
context
|
||||
keyboard-shown?))
|
||||
response-to (:response-to content)
|
||||
height (rf/sub [:dimensions/window-height])
|
||||
(let [{:keys [content-type quoted-message content outgoing outgoing-status pinned-by pinned
|
||||
last-in-group? message-id chat-id]} message-data
|
||||
{:keys [disable-message-long-press?]} context
|
||||
first-image (first (:album message-data))
|
||||
outgoing-status (if (= content-type
|
||||
constants/content-type-album)
|
||||
(:outgoing-status first-image)
|
||||
outgoing-status)
|
||||
outgoing (if (= content-type
|
||||
constants/content-type-album)
|
||||
(:outgoing first-image)
|
||||
outgoing)
|
||||
context (assoc context
|
||||
:on-long-press
|
||||
#(on-long-press message-data
|
||||
context
|
||||
keyboard-shown?))
|
||||
response-to (:response-to content)
|
||||
height (rf/sub [:dimensions/window-height])
|
||||
{window-width :width
|
||||
window-scale :scale} (rn/get-window)
|
||||
message-container-data {:window-width window-width
|
||||
:padding-right 20
|
||||
:padding-left 20
|
||||
:avatar-container-width 32
|
||||
:message-margin-left 8}
|
||||
reactions (rf/sub [:chats/message-reactions message-id
|
||||
chat-id])
|
||||
six-reactions? (-> reactions
|
||||
count
|
||||
(= 6))]
|
||||
window-scale :scale} (rn/get-window)
|
||||
message-container-data {:window-width window-width
|
||||
:padding-right 20
|
||||
:padding-left 20
|
||||
:avatar-container-width 32
|
||||
:message-margin-left 8}
|
||||
reactions (rf/sub [:chats/message-reactions message-id
|
||||
chat-id])
|
||||
six-reactions? (-> reactions
|
||||
count
|
||||
(= 6))]
|
||||
[rn/touchable-highlight
|
||||
{:accessibility-label (if (and outgoing (= outgoing-status :sending))
|
||||
:message-sending
|
||||
@@ -231,10 +232,14 @@
|
||||
[content.text/text-content message-data context]
|
||||
|
||||
constants/content-type-emoji
|
||||
[not-implemented/not-implemented [old-message/emoji message-data]]
|
||||
[emoji-message/view
|
||||
{:content content
|
||||
:last-in-group? last-in-group?
|
||||
:pinned pinned
|
||||
:in-pinned-view? (:in-pinned-view? context)}]
|
||||
|
||||
constants/content-type-sticker
|
||||
[not-implemented/not-implemented [old-message/sticker message-data]]
|
||||
[sticker-message/view {:url (-> message-data :content :sticker :url)}]
|
||||
|
||||
constants/content-type-audio
|
||||
[audio/audio-message message-data context]
|
||||
|
||||
@@ -20,6 +20,13 @@
|
||||
has-permissions? (rf/sub [:communities/has-permissions? id])
|
||||
airdrop-account (rf/sub [:communities/airdrop-account id])
|
||||
revealed-accounts (rf/sub [:communities/accounts-to-reveal id])
|
||||
revealed-accounts-count (count revealed-accounts)
|
||||
wallet-accounts-count (count (rf/sub [:wallet/accounts-without-watched-accounts]))
|
||||
addresses-shared-text (if (= revealed-accounts-count wallet-accounts-count)
|
||||
(i18n/label :t/all-addresses)
|
||||
(i18n/label-pluralize
|
||||
revealed-accounts-count
|
||||
:t/address-count))
|
||||
{:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id])
|
||||
highest-role-text (i18n/label (communities.utils/role->translation-key
|
||||
highest-permission-role
|
||||
@@ -108,7 +115,7 @@
|
||||
:label :preview
|
||||
:label-props {:type :accounts
|
||||
:data revealed-accounts}
|
||||
:description-props {:text (i18n/label :t/all-addresses)}}
|
||||
:description-props {:text addresses-shared-text}}
|
||||
{:title (i18n/label :t/for-airdrops)
|
||||
:on-press show-airdrop-addresses
|
||||
:description :text
|
||||
|
||||
@@ -79,7 +79,6 @@
|
||||
;; incorrect highest permission role.
|
||||
{:db (update db :communities/permissions-checks-for-selection dissoc community-id)}
|
||||
(let [{:keys [checking?]} (get-in db [:communities/permissions-checks-for-selection community-id])]
|
||||
(when-not checking?
|
||||
{:db (assoc-in db [:communities/permissions-checks-for-selection community-id :checking?] true)
|
||||
:fx [[:json-rpc/call
|
||||
[{:method :wakuext_checkPermissionsToJoinCommunity
|
||||
@@ -87,7 +86,7 @@
|
||||
:on-success [:communities/check-permissions-to-join-during-selection-success
|
||||
community-id]
|
||||
:on-error [:communities/check-permissions-to-join-during-selection-failure
|
||||
community-id addresses]}]]]}))))
|
||||
community-id addresses]}]]]})))
|
||||
|
||||
;; This event should be used to check permissions temporarily because it won't
|
||||
;; mutate the state `:communities/permissions-check` (used by many other
|
||||
|
||||
+1
-8
@@ -103,11 +103,4 @@
|
||||
community-id]
|
||||
:on-error [:communities/check-permissions-to-join-during-selection-failure
|
||||
community-id addresses]}]]]}
|
||||
(sut/check-permissions-to-join-for-selection cofx [community-id addresses])))))
|
||||
|
||||
(testing "when there are addresses to check permissions, but currently checking, then skip the check"
|
||||
(let [addresses ["0xA"]
|
||||
cofx {:db {:communities/permissions-checks-for-selection
|
||||
{"other-comm-id" {}
|
||||
community-id {:checking? true}}}}]
|
||||
(is (nil? (sut/check-permissions-to-join-for-selection cofx [community-id addresses]))))))
|
||||
(sut/check-permissions-to-join-for-selection cofx [community-id addresses]))))))
|
||||
|
||||
@@ -195,41 +195,23 @@
|
||||
:button-type :grey
|
||||
:on-button-press open-permission-sheet))])]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||
{:keys [color joined] outro-message :outroMessage} (rf/sub [:communities/community id])
|
||||
|
||||
highest-role (rf/sub [:communities/highest-role-for-selection id])
|
||||
[unmodified-role _] (rn/use-state highest-role)
|
||||
|
||||
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
||||
pending? (boolean (rf/sub [:communities/my-pending-request-to-join id]))
|
||||
|
||||
wallet-accounts (rf/sub [:wallet/accounts-without-watched-accounts])
|
||||
unmodified-addresses-to-reveal (rf/sub [:communities/addresses-to-reveal id])
|
||||
[addresses-to-reveal set-addresses-to-reveal] (rn/use-state unmodified-addresses-to-reveal)
|
||||
|
||||
unmodified-flag-share-all-addresses (rf/sub [:communities/share-all-addresses? id])
|
||||
[flag-share-all-addresses
|
||||
set-flag-share-all-addresses] (rn/use-state unmodified-flag-share-all-addresses)
|
||||
|
||||
identical-choices? (and (= unmodified-addresses-to-reveal addresses-to-reveal)
|
||||
(= unmodified-flag-share-all-addresses flag-share-all-addresses))
|
||||
|
||||
toggle-flag-share-all-addresses
|
||||
(fn []
|
||||
(let [new-value (not flag-share-all-addresses)]
|
||||
(set-flag-share-all-addresses new-value)
|
||||
(when new-value
|
||||
(set-addresses-to-reveal (set (map :address wallet-accounts))))))
|
||||
(defn selection-bottom-actions
|
||||
[id
|
||||
{:keys [flag-share-all-addresses
|
||||
addresses-to-reveal
|
||||
cancel-selection
|
||||
can-edit-addresses?
|
||||
identical-choices?]}]
|
||||
(let [color (rf/sub [:communities/community-color id])
|
||||
outro-message (rf/sub [:communities/community-outro-message id])
|
||||
joined (rf/sub [:communities/community-joined id])
|
||||
checking? (rf/sub [:communities/permissions-check-for-selection-checking? id])
|
||||
|
||||
cancel-join-request
|
||||
(rn/use-callback
|
||||
(fn []
|
||||
(rf/dispatch [:show-bottom-sheet
|
||||
{:content (fn [] [cancel-join-request-drawer id])}])))
|
||||
|
||||
leave-community
|
||||
(rn/use-callback
|
||||
(fn []
|
||||
@@ -237,14 +219,6 @@
|
||||
{:content (fn [] [leave-community-drawer id outro-message])}]))
|
||||
[outro-message])
|
||||
|
||||
cancel-selection
|
||||
(fn []
|
||||
(rf/dispatch [:communities/check-permissions-to-join-community
|
||||
id
|
||||
unmodified-addresses-to-reveal
|
||||
:based-on-client-selection])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
|
||||
confirm-changes
|
||||
(fn []
|
||||
(if can-edit-addresses?
|
||||
@@ -263,7 +237,107 @@
|
||||
(rf/dispatch [:hide-bottom-sheet]))}]))}])
|
||||
(do
|
||||
(rf/dispatch [:communities/set-share-all-addresses id flag-share-all-addresses])
|
||||
(rf/dispatch [:communities/set-addresses-to-reveal id addresses-to-reveal]))))]
|
||||
(rf/dispatch [:communities/set-addresses-to-reveal id addresses-to-reveal]))))
|
||||
pending? (rf/sub [:communities/has-pending-request-to-join? id])
|
||||
highest-role (rf/sub [:communities/highest-role-for-selection id])
|
||||
[unmodified-role _] (rn/use-state highest-role)]
|
||||
|
||||
[quo/bottom-actions
|
||||
(cond-> {:role (role-keyword highest-role)
|
||||
:description (if highest-role
|
||||
:top
|
||||
:top-error)
|
||||
:button-one-props {:customization-color color
|
||||
:on-press confirm-changes
|
||||
:disabled? (or checking?
|
||||
(empty? addresses-to-reveal)
|
||||
(not highest-role)
|
||||
identical-choices?)}}
|
||||
can-edit-addresses?
|
||||
(->
|
||||
(assoc :actions :one-action
|
||||
:button-one-label (cond
|
||||
(and pending? (not highest-role))
|
||||
(i18n/label :t/cancel-request)
|
||||
|
||||
(and joined (not highest-role))
|
||||
(i18n/label :t/leave-community)
|
||||
|
||||
:else
|
||||
(i18n/label :t/confirm-changes))
|
||||
:description-top-text (cond
|
||||
(and pending? highest-role)
|
||||
(i18n/label :t/eligible-to-join-as)
|
||||
|
||||
(and joined (= highest-role unmodified-role))
|
||||
(i18n/label :t/you-are-a)
|
||||
|
||||
(and joined (not= highest-role unmodified-role))
|
||||
(i18n/label :t/you-will-be-a))
|
||||
:error-message (cond
|
||||
(and pending? (not highest-role))
|
||||
(i18n/label :t/community-join-requirements-not-met)
|
||||
|
||||
(and joined (not highest-role))
|
||||
(i18n/label :t/membership-requirements-not-met)))
|
||||
(update :button-one-props
|
||||
merge
|
||||
(cond (and pending? (not highest-role))
|
||||
{:type :danger
|
||||
:disabled? false
|
||||
:on-press cancel-join-request}
|
||||
|
||||
(and joined (not highest-role))
|
||||
{:type :danger
|
||||
:disabled? false
|
||||
:on-press leave-community})))
|
||||
|
||||
(not can-edit-addresses?)
|
||||
(assoc :actions :two-actions
|
||||
:button-one-label (i18n/label :t/confirm-changes)
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press cancel-selection}
|
||||
:error-message (cond
|
||||
(empty? addresses-to-reveal)
|
||||
(i18n/label :t/no-addresses-selected)
|
||||
|
||||
(not highest-role)
|
||||
(i18n/label :t/addresses-dont-contain-tokens-needed))))]))
|
||||
|
||||
(defn view
|
||||
[]
|
||||
(let [{id :community-id} (rf/sub [:get-screen-params])
|
||||
|
||||
color (rf/sub [:communities/community-color id])
|
||||
|
||||
can-edit-addresses? (rf/sub [:communities/can-edit-shared-addresses? id])
|
||||
|
||||
wallet-accounts (rf/sub [:wallet/accounts-without-watched-accounts])
|
||||
unmodified-addresses-to-reveal (rf/sub [:communities/addresses-to-reveal id])
|
||||
[addresses-to-reveal set-addresses-to-reveal] (rn/use-state unmodified-addresses-to-reveal)
|
||||
|
||||
unmodified-flag-share-all-addresses (rf/sub [:communities/share-all-addresses? id])
|
||||
[flag-share-all-addresses
|
||||
set-flag-share-all-addresses] (rn/use-state unmodified-flag-share-all-addresses)
|
||||
|
||||
identical-choices? (and (= unmodified-addresses-to-reveal addresses-to-reveal)
|
||||
(= unmodified-flag-share-all-addresses flag-share-all-addresses))
|
||||
|
||||
cancel-selection
|
||||
(fn []
|
||||
(rf/dispatch [:communities/check-permissions-to-join-community
|
||||
id
|
||||
unmodified-addresses-to-reveal
|
||||
:based-on-client-selection])
|
||||
(rf/dispatch [:hide-bottom-sheet]))
|
||||
|
||||
toggle-flag-share-all-addresses
|
||||
(fn []
|
||||
(let [new-value (not flag-share-all-addresses)]
|
||||
(set-flag-share-all-addresses new-value)
|
||||
(when new-value
|
||||
(set-addresses-to-reveal (set (map :address wallet-accounts))))))]
|
||||
|
||||
(rn/use-mount
|
||||
(fn []
|
||||
@@ -274,7 +348,6 @@
|
||||
(fn []
|
||||
(rf/dispatch [:communities/check-permissions-to-join-during-selection id addresses-to-reveal]))
|
||||
[id addresses-to-reveal])
|
||||
|
||||
[:<>
|
||||
[page-top
|
||||
{:community-id id
|
||||
@@ -303,64 +376,14 @@
|
||||
:key-fn :address
|
||||
:data wallet-accounts}]
|
||||
|
||||
[quo/bottom-actions
|
||||
(cond-> {:role (role-keyword highest-role)
|
||||
:description (if highest-role
|
||||
:top
|
||||
:top-error)
|
||||
:button-one-props {:customization-color color
|
||||
:on-press confirm-changes
|
||||
:disabled? (or (empty? addresses-to-reveal)
|
||||
(not highest-role)
|
||||
identical-choices?)}}
|
||||
can-edit-addresses?
|
||||
(->
|
||||
(assoc :actions :one-action
|
||||
:button-one-label (cond
|
||||
(and pending? (not highest-role))
|
||||
(i18n/label :t/cancel-request)
|
||||
|
||||
(and joined (not highest-role))
|
||||
(i18n/label :t/leave-community)
|
||||
|
||||
:else
|
||||
(i18n/label :t/confirm-changes))
|
||||
:description-top-text (cond
|
||||
(and pending? highest-role)
|
||||
(i18n/label :t/eligible-to-join-as)
|
||||
|
||||
(and joined (= highest-role unmodified-role))
|
||||
(i18n/label :t/you-are-a)
|
||||
|
||||
(and joined (not= highest-role unmodified-role))
|
||||
(i18n/label :t/you-will-be-a))
|
||||
:error-message (cond
|
||||
(and pending? (not highest-role))
|
||||
(i18n/label :t/community-join-requirements-not-met)
|
||||
|
||||
(and joined (not highest-role))
|
||||
(i18n/label :t/membership-requirements-not-met)))
|
||||
(update :button-one-props
|
||||
merge
|
||||
(cond (and pending? (not highest-role))
|
||||
{:type :danger
|
||||
:disabled? false
|
||||
:on-press cancel-join-request}
|
||||
|
||||
(and joined (not highest-role))
|
||||
{:type :danger
|
||||
:disabled? false
|
||||
:on-press leave-community})))
|
||||
|
||||
(not can-edit-addresses?)
|
||||
(assoc :actions :two-actions
|
||||
:button-one-label (i18n/label :t/confirm-changes)
|
||||
:button-two-label (i18n/label :t/cancel)
|
||||
:button-two-props {:type :grey
|
||||
:on-press cancel-selection}
|
||||
:error-message (cond
|
||||
(empty? addresses-to-reveal)
|
||||
(i18n/label :t/no-addresses-selected)
|
||||
|
||||
(not highest-role)
|
||||
(i18n/label :t/addresses-dont-contain-tokens-needed))))]]))
|
||||
[selection-bottom-actions id
|
||||
{:flag-share-all-addresses
|
||||
flag-share-all-addresses
|
||||
:addresses-to-reveal
|
||||
addresses-to-reveal
|
||||
:cancel-selection
|
||||
cancel-selection
|
||||
:can-edit-addresses?
|
||||
can-edit-addresses?
|
||||
:identical-choices?
|
||||
identical-choices?}]]))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def commmunity-keys-renamed
|
||||
(def community-keys-renamed
|
||||
{:requestedAccessAt :requested-access-at
|
||||
:fileSize :file-size
|
||||
:communityTokensMetadata :community-tokens-metadata
|
||||
@@ -35,7 +35,7 @@
|
||||
[k]
|
||||
(let [s (name k)
|
||||
starts-with-digit? (re-matches #"^\d.*" s)
|
||||
existing-rename (k commmunity-keys-renamed)]
|
||||
existing-rename (k community-keys-renamed)]
|
||||
(cond starts-with-digit? s
|
||||
existing-rename existing-rename
|
||||
:else (keyword s))))
|
||||
|
||||
@@ -178,23 +178,16 @@
|
||||
:container-style {:margin-horizontal 12 :margin-top 12 :margin-bottom 12}
|
||||
:disabled? (not can-request-access?)
|
||||
:icon-left (if can-request-access? :i/unlocked :i/locked)}
|
||||
(i18n/label :t/join-open-community)]])))
|
||||
(i18n/label :t/request-to-join)]])))
|
||||
|
||||
(defn- join-community
|
||||
[{:keys [id joined permissions can-request-access?] :as community}]
|
||||
[{:keys [id joined permissions] :as community}]
|
||||
(let [pending? (rf/sub [:communities/my-pending-request-to-join id])
|
||||
access-type (get-access-type (:access permissions))
|
||||
unknown-access? (= access-type :unknown-access)
|
||||
invite-only? (= access-type :invite-only)]
|
||||
[:<>
|
||||
(when-not (or joined pending? invite-only? unknown-access?)
|
||||
[token-requirements community])
|
||||
(when (and can-request-access? (not joined))
|
||||
[quo/text
|
||||
{:size :paragraph-2
|
||||
:weight :regular
|
||||
:style style/review-notice}
|
||||
(i18n/label :t/community-admins-will-review-your-request)])]))
|
||||
(when-not (or joined pending? invite-only? unknown-access?)
|
||||
[token-requirements community])))
|
||||
|
||||
(defn- status-tag
|
||||
[community-id joined]
|
||||
|
||||
@@ -153,7 +153,7 @@
|
||||
@full-name
|
||||
(i18n/label :t/your-name))
|
||||
:customization-color @custom-color}
|
||||
:title-input-props {:default-value @full-name
|
||||
:title-input-props {:default-value display-name
|
||||
:auto-focus true
|
||||
:max-length c/profile-name-max-length
|
||||
:on-change-text on-change-text}}]]
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
[quo.theme :as quo.theme]
|
||||
[re-frame.core :as rf]
|
||||
[react-native.blur :as blur]
|
||||
[react-native.clipboard :as clipboard]
|
||||
[react-native.core :as rn]
|
||||
[react-native.safe-area :as safe-area]
|
||||
[reagent.core :as reagent]
|
||||
@@ -340,29 +341,38 @@
|
||||
{:style (style/panel-basic)
|
||||
:shows-vertical-scroll-indicator false
|
||||
:content-container-style (when full-screen? {:flex 1})}
|
||||
[rn/pressable
|
||||
{:style (when full-screen? {:flex 1})
|
||||
:on-press rn/dismiss-keyboard!}
|
||||
(when descriptor
|
||||
[rn/view {:style style/customizer-container}
|
||||
[customizer state descriptor]])
|
||||
(if blur?
|
||||
[rn/view {:style (merge style/component-container component-container-style)}
|
||||
(into [blur-view
|
||||
{:theme theme
|
||||
:show-blur-background? show-blur-background?
|
||||
:height blur-height
|
||||
:style (merge {:width "100%"
|
||||
:flex-grow 1}
|
||||
(when-not show-blur-background?
|
||||
{:padding-horizontal 0
|
||||
:top 0})
|
||||
blur-container-style)
|
||||
:blur-view-props (merge {:blur-type theme}
|
||||
blur-view-props)}]
|
||||
children)]
|
||||
(into [rn/view {:style (merge style/component-container component-container-style)}]
|
||||
children))]]]))
|
||||
[:<>
|
||||
[rn/pressable
|
||||
{:style (when full-screen? {:flex 1})
|
||||
:on-press rn/dismiss-keyboard!}
|
||||
(when descriptor
|
||||
[rn/view {:style style/customizer-container}
|
||||
[customizer state descriptor]])
|
||||
(if blur?
|
||||
[rn/view {:style (merge style/component-container component-container-style)}
|
||||
(into [blur-view
|
||||
{:theme theme
|
||||
:show-blur-background? show-blur-background?
|
||||
:height blur-height
|
||||
:style (merge {:width "100%"
|
||||
:flex-grow 1}
|
||||
(when-not show-blur-background?
|
||||
{:padding-horizontal 0
|
||||
:top 0})
|
||||
blur-container-style)
|
||||
:blur-view-props (merge {:blur-type theme}
|
||||
blur-view-props)}]
|
||||
children)]
|
||||
(into [rn/view {:style (merge style/component-container component-container-style)}]
|
||||
children))]
|
||||
(when state
|
||||
(let [decr-state (if descriptor (select-keys @state (mapv :key (flatten descriptor))) @state)
|
||||
state-str (with-out-str (cljs.pprint/pprint decr-state))]
|
||||
[rn/view {:style {:margin 50}}
|
||||
[quo/text {:style {:margin-bottom 10}} "State map (click on map to copy)"]
|
||||
[rn/pressable
|
||||
{:on-press #(clipboard/set-string state-str)}
|
||||
[quo/text state-str]]]))]]]))
|
||||
|
||||
(defn preview-container
|
||||
[& args]
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
|
||||
:else
|
||||
[[:profile.settings/switch-theme-fx
|
||||
[(or (get-in db [:profile/profile :appearance])
|
||||
[(or (:appearance settings)
|
||||
constants/theme-type-dark)
|
||||
:shell-stack
|
||||
false]]
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
(ns status-im.contexts.profile.settings.effects
|
||||
(:require [native-module.core :as native-module]
|
||||
[quo.foundations.colors :as colors]
|
||||
[re-frame.core :as re-frame]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.common.theme.core :as theme]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.shell.jump-to.utils :as shell.utils]
|
||||
[status-im.setup.hot-reload :as hot-reload]))
|
||||
[status-im.setup.hot-reload :as hot-reload]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(re-frame/reg-fx
|
||||
:profile.settings/blank-preview-flag-changed
|
||||
@@ -22,19 +21,14 @@
|
||||
(re-frame/reg-fx
|
||||
:profile.settings/switch-theme-fx
|
||||
(fn [[theme-type view-id reload-ui?]]
|
||||
(let [[theme status-bar-theme nav-bar-color]
|
||||
;; Status bar theme represents status bar icons colors, so opposite to app theme
|
||||
(if (or (= theme-type constants/theme-type-dark)
|
||||
(and (= theme-type constants/theme-type-system)
|
||||
(theme/device-theme-dark?)))
|
||||
[:dark :light colors/neutral-100]
|
||||
[:light :dark colors/white])]
|
||||
(let [theme (if (or (= theme-type constants/theme-type-dark)
|
||||
(and (= theme-type constants/theme-type-system)
|
||||
(theme/device-theme-dark?)))
|
||||
:dark
|
||||
:light)]
|
||||
(theme/set-theme theme)
|
||||
(re-frame/dispatch [:change-shell-status-bar-style
|
||||
(if (shell.utils/home-stack-open?) status-bar-theme :light)])
|
||||
(rf/dispatch [:reload-status-nav-color view-id])
|
||||
(when reload-ui?
|
||||
(re-frame/dispatch [:dismiss-all-overlays])
|
||||
(when js/goog.DEBUG
|
||||
(hot-reload/reload))
|
||||
(when-not (= view-id :shell-stack)
|
||||
(re-frame/dispatch [:change-shell-nav-bar-color nav-bar-color]))))))
|
||||
(hot-reload/reload))))))
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
(ns status-im.contexts.shell.activity-center.notification.reply.view
|
||||
(:require
|
||||
[clojure.string :as string]
|
||||
[legacy.status-im.ui.screens.chat.message.legacy-view :as old-message]
|
||||
[quo.core :as quo]
|
||||
[react-native.gesture :as gesture]
|
||||
[status-im.common.not-implemented :as not-implemented]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.chat.messenger.messages.content.sticker-message.view :as sticker-message]
|
||||
[status-im.contexts.shell.activity-center.notification.common.view :as common]
|
||||
[status-im.contexts.shell.activity-center.notification.reply.style :as style]
|
||||
[utils.datetime :as datetime]
|
||||
@@ -34,7 +34,7 @@
|
||||
:message-text (get-in message [:content :text])}])
|
||||
|
||||
constants/content-type-sticker
|
||||
[old-message/sticker message]
|
||||
[sticker-message/view {:url (-> message :content :sticker :url)}]
|
||||
|
||||
constants/content-type-system-pinned-message
|
||||
[not-implemented/not-implemented
|
||||
|
||||
@@ -14,9 +14,7 @@
|
||||
(reanimated/set-shared-value (:home-stack-state @state/shared-values-atom) home-stack-state-value)
|
||||
(utils/change-selected-stack-id stack-id true home-stack-state-value)
|
||||
(js/setTimeout
|
||||
(fn []
|
||||
(utils/load-stack stack-id)
|
||||
(utils/change-shell-status-bar-style))
|
||||
#(utils/load-stack stack-id)
|
||||
(if animate? shell.constants/shell-animation-time 0))))
|
||||
|
||||
(defn change-tab
|
||||
@@ -41,7 +39,6 @@
|
||||
(reanimated/set-shared-value (:animate-home-stack-left @state/shared-values-atom) true)
|
||||
(reanimated/set-shared-value (:home-stack-state @state/shared-values-atom) home-stack-state-value)
|
||||
(utils/change-selected-stack-id stack-id true home-stack-state-value)
|
||||
(utils/change-shell-status-bar-style)
|
||||
(when animate? (utils/update-view-id (or stack-id :shell)))))
|
||||
|
||||
;;;; Floating Screen
|
||||
|
||||
@@ -108,16 +108,6 @@
|
||||
:dispatch [:set-view-id :shell]
|
||||
:effects.shell/navigate-to-jump-to nil}))
|
||||
|
||||
(rf/defn change-shell-status-bar-style
|
||||
{:events [:change-shell-status-bar-style]}
|
||||
[_ style]
|
||||
{:merge-options {:id "shell-stack" :options {:statusBar {:style style}}}})
|
||||
|
||||
(rf/defn change-shell-nav-bar-color
|
||||
{:events [:change-shell-nav-bar-color]}
|
||||
[_ color]
|
||||
{:merge-options {:id "shell-stack" :options {:navigationBar {:backgroundColor color}}}})
|
||||
|
||||
(rf/defn shell-navigate-to
|
||||
{:events [:shell/navigate-to]}
|
||||
[{:keys [db now]} go-to-view-id screen-params animation hidden-screen?]
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
(ns status-im.contexts.shell.jump-to.utils
|
||||
(:require
|
||||
[quo.theme :as quo.theme]
|
||||
[react-native.async-storage :as async-storage]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
@@ -136,12 +135,3 @@
|
||||
(defn update-view-id
|
||||
[view-id]
|
||||
(rf/dispatch [:set-view-id view-id]))
|
||||
|
||||
;;; Misc
|
||||
(defn change-shell-status-bar-style
|
||||
[]
|
||||
(rf/dispatch [:change-shell-status-bar-style
|
||||
(if (or (= :dark (quo.theme/get-theme))
|
||||
(not (home-stack-open?)))
|
||||
:light
|
||||
:dark)]))
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
(load-and-show-profile scanned-text)
|
||||
|
||||
(eth-address? scanned-text)
|
||||
(debounce/debounce-and-dispatch [:navigate-to :wallet-accounts scanned-text] 300)
|
||||
(debounce/debounce-and-dispatch [:navigate-to :screen/wallet.accounts scanned-text] 300)
|
||||
|
||||
(eip681-address? scanned-text)
|
||||
(do
|
||||
|
||||
@@ -16,16 +16,18 @@
|
||||
[]
|
||||
(let [{:keys [emoji-hash
|
||||
universal-profile-url]
|
||||
:as profile} (rf/sub [:profile/profile-with-image])
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
abbreviated-url (address/get-abbreviated-profile-url
|
||||
universal-profile-url)
|
||||
emoji-hash-string (string/join emoji-hash)]
|
||||
:as profile} (rf/sub [:profile/profile-with-image])
|
||||
{window-width :width} (rn/get-window)
|
||||
customization-color (rf/sub [:profile/customization-color])
|
||||
abbreviated-url (address/get-abbreviated-profile-url
|
||||
universal-profile-url)
|
||||
emoji-hash-string (string/join emoji-hash)]
|
||||
[rn/scroll-view
|
||||
{:content-container-style {:padding-bottom 16}}
|
||||
[rn/view {:style style/qr-code-container}
|
||||
[qr-codes/share-qr-code
|
||||
{:type :profile
|
||||
:width (- window-width (* style/screen-padding 2))
|
||||
:qr-data universal-profile-url
|
||||
:qr-data-label-shown abbreviated-url
|
||||
:on-share-press #(list-selection/open-share {:message universal-profile-url})
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
(def screen-padding 20)
|
||||
|
||||
|
||||
(def header-row
|
||||
{:flex-direction :row
|
||||
:justify-content :space-between
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
(ns status-im.contexts.shell.share.wallet.view
|
||||
(:require
|
||||
[oops.core :as oops]
|
||||
[quo.core :as quo]
|
||||
[react-native.core :as rn]
|
||||
[react-native.platform :as platform]
|
||||
@@ -11,6 +12,7 @@
|
||||
[status-im.contexts.wallet.sheets.network-preferences.view :as network-preferences]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.image-server :as image-server]
|
||||
[utils.number]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(def qr-size 500)
|
||||
@@ -44,14 +46,14 @@
|
||||
(rf/dispatch [:hide-bottom-sheet])
|
||||
(reset! selected-networks (map #(get utils/id->network %)
|
||||
chain-ids)))}])}]))
|
||||
(defn- wallet-qr-code-item-internal
|
||||
[props]
|
||||
(let [{:keys [account width index]} props
|
||||
selected-networks (reagent/atom [:ethereum :optimism :arbitrum])
|
||||
wallet-type (reagent/atom :legacy)
|
||||
on-settings-press #(open-preferences selected-networks)
|
||||
on-legacy-press #(reset! wallet-type :legacy)
|
||||
on-multichain-press #(reset! wallet-type :multichain)]
|
||||
(defn- wallet-qr-code-item
|
||||
[{:keys [account index]}]
|
||||
(let [{window-width :width} (rn/get-window)
|
||||
selected-networks (reagent/atom [:ethereum :optimism :arbitrum])
|
||||
wallet-type (reagent/atom :legacy)
|
||||
on-settings-press #(open-preferences selected-networks)
|
||||
on-legacy-press #(reset! wallet-type :legacy)
|
||||
on-multichain-press #(reset! wallet-type :multichain)]
|
||||
(fn []
|
||||
(let [share-title (str (:name account) " " (i18n/label :t/address))
|
||||
qr-url (utils/get-wallet-qr {:wallet-type @wallet-type
|
||||
@@ -62,10 +64,11 @@
|
||||
:port (rf/sub [:mediaserver/port])
|
||||
:qr-size qr-size
|
||||
:error-level :highest})]
|
||||
[rn/view {:style {:height qr-size :width width :margin-left (if (zero? index) 0 -30)}}
|
||||
[rn/view {:style {:width window-width :margin-left (if (zero? index) 0 -30)}}
|
||||
[rn/view {:style style/qr-code-container}
|
||||
[quo/share-qr-code
|
||||
{:type :wallet
|
||||
:width (- window-width (* style/screen-padding 2))
|
||||
:address @wallet-type
|
||||
:qr-image-uri qr-media-server-uri
|
||||
:qr-data qr-url
|
||||
@@ -79,54 +82,54 @@
|
||||
:on-legacy-press on-legacy-press
|
||||
:on-settings-press on-settings-press}]]]))))
|
||||
|
||||
(def wallet-qr-code-item (memoize wallet-qr-code-item-internal))
|
||||
|
||||
(defn- indicator
|
||||
[active?]
|
||||
[rn/view
|
||||
{:style (wallet-style/indicator-wrapper-style active?)}])
|
||||
[rn/view {:style (wallet-style/indicator-wrapper-style active?)}])
|
||||
|
||||
(defn- indicator-list
|
||||
[indicator-count current-index]
|
||||
[rn/view
|
||||
{:style wallet-style/indicator-list-style}
|
||||
(for [i (range indicator-count)]
|
||||
(let [current-index (cond (<= current-index 0) 0
|
||||
(>= current-index (dec indicator-count)) (dec indicator-count)
|
||||
:else current-index)]
|
||||
^{:key i} [indicator (= current-index i)]))])
|
||||
[num-indicators current-index]
|
||||
[rn/view {:style wallet-style/indicator-list-style}
|
||||
(for [i (range num-indicators)]
|
||||
^{:key i} [indicator (= current-index i)])])
|
||||
|
||||
(defn render-item
|
||||
[item]
|
||||
(let [width (rf/sub [:dimensions/window-width])]
|
||||
[wallet-qr-code-item
|
||||
{:account item
|
||||
:index (:position item)
|
||||
:width width}]))
|
||||
[wallet-qr-code-item
|
||||
{:account item
|
||||
:index (:position item)}])
|
||||
|
||||
(defn- qr-code-visualized-index
|
||||
[offset qr-code-size num-qr-codes]
|
||||
(-> (+ (/ offset qr-code-size) 0.5)
|
||||
(int)
|
||||
(utils.number/value-in-range 0 (dec num-qr-codes))))
|
||||
|
||||
(defn wallet-tab
|
||||
[]
|
||||
(let [accounts (rf/sub [:wallet/accounts])
|
||||
width (rf/sub [:dimensions/window-width])
|
||||
current-index (reagent/atom 0)]
|
||||
(let [current-index (reagent/atom 0)
|
||||
{window-width :width} (rn/get-window)
|
||||
qr-code-size (- window-width 30)]
|
||||
(fn []
|
||||
[rn/view
|
||||
[rn/flat-list
|
||||
{:horizontal true
|
||||
:deceleration-rate 0.9
|
||||
:snap-to-alignment :start
|
||||
:snap-to-interval (- width 30)
|
||||
:disable-interval-momentum true
|
||||
:scroll-event-throttle 64
|
||||
:data accounts
|
||||
:directional-lock-enabled true
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:on-scroll (fn [e]
|
||||
(reset! current-index (js/Math.ceil
|
||||
(/ e.nativeEvent.contentOffset.x
|
||||
width))))
|
||||
:render-fn render-item}]
|
||||
(when (> (count accounts) 1)
|
||||
[rn/view
|
||||
{:style {:margin-top 20}}
|
||||
(indicator-list (count accounts) @current-index)])])))
|
||||
(let [accounts (rf/sub [:wallet/accounts])
|
||||
num-accounts (count accounts)
|
||||
on-scroll (rn/use-callback
|
||||
(fn [e]
|
||||
(let [offset-x (oops/oget e "nativeEvent.contentOffset.x")
|
||||
index (qr-code-visualized-index offset-x qr-code-size num-accounts)]
|
||||
(reset! current-index index))))]
|
||||
[rn/view
|
||||
[rn/flat-list
|
||||
{:horizontal true
|
||||
:deceleration-rate 0.9
|
||||
:snap-to-alignment :start
|
||||
:snap-to-interval qr-code-size
|
||||
:disable-interval-momentum true
|
||||
:scroll-event-throttle 64
|
||||
:data accounts
|
||||
:directional-lock-enabled true
|
||||
:shows-horizontal-scroll-indicator false
|
||||
:on-scroll on-scroll
|
||||
:render-fn render-item}]
|
||||
(when (> num-accounts 1)
|
||||
[rn/view {:style {:margin-top 20}}
|
||||
[indicator-list num-accounts @current-index]])]))))
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
[status-im.feature-flags :as ff]
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]
|
||||
[utils.responsiveness :refer [iphone-11-Pro-20-pixel-from-width]]
|
||||
[utils.responsiveness :as responsiveness]
|
||||
[utils.security.core :as security]
|
||||
[utils.string]))
|
||||
|
||||
@@ -146,7 +146,8 @@
|
||||
{:default-selected @account-color
|
||||
:on-change #(reset! account-color %)
|
||||
:container-style {:padding-vertical 12
|
||||
:padding-left (iphone-11-Pro-20-pixel-from-width window-width)}}]]
|
||||
:padding-left (responsiveness/iphone-11-Pro-20-pixel-from-width
|
||||
window-width)}}]]
|
||||
[quo/divider-line]
|
||||
[quo/category
|
||||
{:list-type :settings
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
(:require [status-im.common.scan-qr-code.view :as scan-qr-code]
|
||||
[status-im.constants :as constants]
|
||||
[utils.debounce :as debounce]
|
||||
[utils.i18n :as i18n]))
|
||||
[utils.i18n :as i18n]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- contains-address?
|
||||
[s]
|
||||
@@ -14,11 +15,15 @@
|
||||
|
||||
(defn view
|
||||
[]
|
||||
[scan-qr-code/view
|
||||
{:title (i18n/label :t/scan-qr)
|
||||
:subtitle (i18n/label :t/scan-an-account-qr-code)
|
||||
:error-message (i18n/label :t/oops-this-qr-does-not-contain-an-address)
|
||||
:validate-fn #(contains-address? %)
|
||||
:on-success-scan #(debounce/debounce-and-dispatch [:wallet/scan-address-success
|
||||
(extract-address %)]
|
||||
300)}])
|
||||
(let [{:keys [on-result]} (rf/sub [:get-screen-params])]
|
||||
[scan-qr-code/view
|
||||
{:title (i18n/label :t/scan-qr)
|
||||
:subtitle (i18n/label :t/scan-an-account-qr-code)
|
||||
:error-message (i18n/label :t/oops-this-qr-does-not-contain-an-address)
|
||||
:validate-fn #(contains-address? %)
|
||||
:on-success-scan (fn [result]
|
||||
(let [address (extract-address result)]
|
||||
(when on-result (on-result address))
|
||||
(debounce/debounce-and-dispatch
|
||||
[:wallet/scan-address-success address]
|
||||
300)))}]))
|
||||
|
||||
@@ -35,10 +35,11 @@
|
||||
[quo/address-input
|
||||
{:on-focus #(reset! input-focused? true)
|
||||
:on-blur #(reset! input-focused? false)
|
||||
:on-scan (fn []
|
||||
:on-scan (fn [on-result]
|
||||
(rn/dismiss-keyboard!)
|
||||
(rf/dispatch [:wallet/clean-scanned-address])
|
||||
(rf/dispatch [:open-modal :screen/wallet.scan-address]))
|
||||
(rf/dispatch [:open-modal :screen/wallet.scan-address
|
||||
{:on-result on-result}]))
|
||||
:ens-regex constants/regx-ens
|
||||
:scanned-value (or (when recipient-plain-address? send-address) scanned-address)
|
||||
:address-regex constants/regx-multichain-address
|
||||
|
||||
@@ -83,7 +83,9 @@
|
||||
:on-press #(rf/dispatch [:navigate-back])
|
||||
:background :blur
|
||||
:right-side [{:icon-name :i/scan
|
||||
:on-press #(js/alert "To be implemented")}]
|
||||
:on-press (fn []
|
||||
(rf/dispatch [:navigate-back])
|
||||
(rf/dispatch [:open-modal :shell-qr-reader]))}]
|
||||
:accessibility-label :top-bar}]
|
||||
[quo/page-top
|
||||
{:title title
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
(ns status-im.navigation.effects
|
||||
(:require
|
||||
[quo.foundations.colors :as colors]
|
||||
[quo.theme]
|
||||
[react-native.core :as rn]
|
||||
[react-native.navigation :as navigation]
|
||||
[react-native.platform :as platform]
|
||||
[status-im.contexts.shell.jump-to.constants :as shell.constants]
|
||||
[status-im.contexts.shell.jump-to.utils :as jump-to.utils]
|
||||
[status-im.navigation.options :as options]
|
||||
[status-im.navigation.roots :as roots]
|
||||
[status-im.navigation.state :as state]
|
||||
@@ -10,20 +14,48 @@
|
||||
[taoensso.timbre :as log]
|
||||
[utils.re-frame :as rf]))
|
||||
|
||||
(defn- set-status-bar-color
|
||||
[theme]
|
||||
(rn/set-status-bar-style
|
||||
(if (= theme :dark)
|
||||
"light-content"
|
||||
"dark-content")
|
||||
true))
|
||||
(defn get-status-nav-color
|
||||
[view-id]
|
||||
(let [theme (or (get-in views/screens [view-id :options :theme])
|
||||
(quo.theme/get-theme))
|
||||
[rnn-status-bar rn-status-bar]
|
||||
(if (or (= theme :dark)
|
||||
@state/alert-banner-shown?
|
||||
(and (= view-id :shell-stack) (not (jump-to.utils/home-stack-open?))))
|
||||
[:light "light-content"]
|
||||
[:dark "dark-content"])
|
||||
home-stack? (some #(= view-id %) shell.constants/stacks-ids)
|
||||
;; Home screen nav bar always dark due to bottom tabs
|
||||
nav-bar-color (if (or home-stack?
|
||||
(= view-id :shell-stack)
|
||||
(= theme :dark))
|
||||
colors/neutral-100
|
||||
colors/white)
|
||||
comp-id (if (or home-stack?
|
||||
(jump-to.utils/shell-navigation? view-id)
|
||||
(= view-id :shell))
|
||||
:shell-stack
|
||||
view-id)]
|
||||
[rnn-status-bar rn-status-bar nav-bar-color comp-id]))
|
||||
|
||||
(defn reload-status-nav-color-fx
|
||||
[view-id]
|
||||
(when (and (= @state/root-id :shell-stack) view-id)
|
||||
(let [[rnn-status-bar rn-status-bar nav-bar-color comp-id] (get-status-nav-color view-id)]
|
||||
(if platform/ios?
|
||||
(rn/set-status-bar-style rn-status-bar true)
|
||||
(navigation/merge-options
|
||||
(name comp-id)
|
||||
{:statusBar {:style rnn-status-bar}
|
||||
:navigationBar {:backgroundColor nav-bar-color}})))))
|
||||
|
||||
(rf/reg-fx :reload-status-nav-color-fx reload-status-nav-color-fx)
|
||||
|
||||
(rf/reg-fx :set-view-id-fx
|
||||
(fn [view-id]
|
||||
(reload-status-nav-color-fx view-id)
|
||||
(rf/dispatch [:screens/on-will-focus view-id])
|
||||
(when-let [{:keys [on-focus options]} (get views/screens view-id)]
|
||||
(set-status-bar-color (or (:theme options)
|
||||
(quo.theme/get-theme)))
|
||||
(when-let [{:keys [on-focus]} (get views/screens view-id)]
|
||||
(when on-focus
|
||||
(rf/dispatch on-focus)))))
|
||||
|
||||
@@ -167,11 +199,12 @@
|
||||
opts)}})))
|
||||
|
||||
(rf/reg-fx :show-toasts
|
||||
(fn []
|
||||
(show-overlay "toasts"
|
||||
{:overlay {:interceptTouchOutside false}
|
||||
:layout {:componentBackgroundColor :transparent
|
||||
:orientation ["portrait"]}})))
|
||||
(fn [view-id]
|
||||
(let [[rnn-status-bar nav-bar-color] (get-status-nav-color view-id)]
|
||||
(show-overlay "toasts"
|
||||
(assoc (options/statusbar-and-navbar-options nil rnn-status-bar nav-bar-color)
|
||||
:overlay
|
||||
{:interceptTouchOutside false})))))
|
||||
|
||||
(rf/reg-fx :hide-toasts
|
||||
(fn [] (navigation/dissmiss-overlay "toasts")))
|
||||
@@ -186,10 +219,16 @@
|
||||
|
||||
;;;; Alert Banner
|
||||
(rf/reg-fx :show-alert-banner
|
||||
(fn [] (show-overlay "alert-banner" {:overlay {:interceptTouchOutside false}})))
|
||||
(fn [view-id]
|
||||
(show-overlay "alert-banner" {:overlay {:interceptTouchOutside false}})
|
||||
(reset! state/alert-banner-shown? true)
|
||||
(reload-status-nav-color-fx view-id)))
|
||||
|
||||
(rf/reg-fx :hide-alert-banner
|
||||
(fn [] (navigation/dissmiss-overlay "alert-banner")))
|
||||
(fn [view-id]
|
||||
(navigation/dissmiss-overlay "alert-banner")
|
||||
(reset! state/alert-banner-shown? false)
|
||||
(reload-status-nav-color-fx view-id)))
|
||||
|
||||
;;;; Merge options
|
||||
|
||||
|
||||
@@ -101,8 +101,9 @@
|
||||
(let [{:keys [sheets]} (:bottom-sheet db)
|
||||
rest-sheets (butlast sheets)]
|
||||
(merge
|
||||
{:db (assoc db :bottom-sheet {:sheets rest-sheets :hide? false})
|
||||
:hide-bottom-sheet nil}
|
||||
{:db (assoc db :bottom-sheet {:sheets rest-sheets :hide? false})
|
||||
:hide-bottom-sheet nil
|
||||
:reload-status-nav-color-fx (:view-id db)}
|
||||
(when (seq rest-sheets)
|
||||
{:dispatch [:show-next-bottom-sheet]}))))
|
||||
|
||||
@@ -134,7 +135,11 @@
|
||||
(rf/defn set-view-id
|
||||
{:events [:set-view-id]}
|
||||
[{:keys [db]} view-id]
|
||||
(when-not (= view-id (:view-id db))
|
||||
(let [view-id (if (= view-id :shell-stack) (shell.utils/calculate-view-id) view-id)]
|
||||
{:db (assoc db :view-id view-id)
|
||||
:set-view-id-fx view-id})))
|
||||
(let [view-id (if (= view-id :shell-stack) (shell.utils/calculate-view-id) view-id)]
|
||||
{:db (assoc db :view-id view-id)
|
||||
:set-view-id-fx view-id}))
|
||||
|
||||
(rf/defn reload-status-nav-color
|
||||
{:events [:reload-status-nav-color]}
|
||||
[{:keys [db]} view-id]
|
||||
{:reload-status-nav-color-fx (or view-id (:view-id db))})
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[status-im.common.emoji-picker.view :as emoji-picker]
|
||||
[status-im.common.lightbox.view :as lightbox]
|
||||
[status-im.config :as config]
|
||||
[status-im.contexts.chat.group-create.view :as group-create]
|
||||
[status-im.contexts.chat.group-details.view :as group-details]
|
||||
[status-im.contexts.chat.home.add-new-contact.scan.scan-profile-qr-page :as scan-profile-qr-page]
|
||||
[status-im.contexts.chat.home.add-new-contact.views :as add-new-contact]
|
||||
@@ -116,6 +117,11 @@
|
||||
:options {:sheet? true}
|
||||
:component group-details/add-manage-members}
|
||||
|
||||
{:name :group-create
|
||||
:options {:sheet? true
|
||||
:skip-background? true}
|
||||
:component group-create/view}
|
||||
|
||||
{:name :community-requests-to-join
|
||||
:options {:sheet? true}
|
||||
:component join-menu/view}
|
||||
@@ -444,11 +450,7 @@
|
||||
:component settings-password/view}]
|
||||
|
||||
[{:name :shell
|
||||
:options {:theme :dark}}
|
||||
{:name :communities-stack}
|
||||
{:name :chats-stack}
|
||||
{:name :wallet-stack}
|
||||
{:name :browser-stack}]
|
||||
:options {:theme :dark}}]
|
||||
|
||||
(when js/goog.DEBUG
|
||||
[{:name :dev-component-preview
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
(defonce root-id (atom nil))
|
||||
(defonce modals (atom []))
|
||||
(defonce dissmissing (atom false))
|
||||
(defonce alert-banner-shown? (atom false))
|
||||
|
||||
(defonce ^:private navigation-state (atom []))
|
||||
|
||||
|
||||
@@ -57,20 +57,21 @@
|
||||
|
||||
(reagent.core/reactify-component
|
||||
(fn []
|
||||
(let [screen-details (get (if js/goog.DEBUG
|
||||
(get-screens)
|
||||
screens)
|
||||
(keyword screen-key))
|
||||
qualified-screen-details (get (if js/goog.DEBUG
|
||||
(get-screens)
|
||||
screens)
|
||||
(keyword "screen" screen-key))
|
||||
{:keys [component options]} (or qualified-screen-details screen-details)
|
||||
{:keys [insets sheet? theme]} options
|
||||
user-theme (theme/get-theme)
|
||||
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
|
||||
background-color (or (get-in options [:layout :backgroundColor])
|
||||
(when sheet? :transparent))]
|
||||
(let [screen-details (get (if js/goog.DEBUG
|
||||
(get-screens)
|
||||
screens)
|
||||
(keyword screen-key))
|
||||
qualified-screen-details (get (if js/goog.DEBUG
|
||||
(get-screens)
|
||||
screens)
|
||||
(keyword "screen" screen-key))
|
||||
{:keys [component options]} (or qualified-screen-details screen-details)
|
||||
{:keys [insets sheet? theme
|
||||
skip-background?]} options
|
||||
user-theme (theme/get-theme)
|
||||
alert-banners-top-margin (rf/sub [:alert-banners/top-margin])
|
||||
background-color (or (get-in options [:layout :backgroundColor])
|
||||
(when sheet? :transparent))]
|
||||
^{:key (str "root" screen-key @reloader/cnt)}
|
||||
[theme/provider {:theme (or theme user-theme)}
|
||||
[rn/view
|
||||
@@ -80,7 +81,7 @@
|
||||
:alert-banners-top-margin alert-banners-top-margin))}
|
||||
[inactive]
|
||||
(if sheet?
|
||||
[bottom-sheet-screen/view {:content component}]
|
||||
[bottom-sheet-screen/view {:content component :skip-background? skip-background?}]
|
||||
[component])]
|
||||
(when js/goog.DEBUG
|
||||
[:<>
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
[legacy.status-im.ui.screens.profile.visibility-status.utils :as visibility-status-utils]
|
||||
[re-frame.core :as re-frame]
|
||||
[status-im.constants :as constants]
|
||||
[status-im.contexts.wallet.common.utils :as wallet.utils]
|
||||
[utils.i18n :as i18n]))
|
||||
[utils.i18n :as i18n]
|
||||
[utils.money :as money]))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/fetching-community
|
||||
@@ -32,21 +32,38 @@
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/community-chats
|
||||
:<- [:communities]
|
||||
(fn [communities [_ id]]
|
||||
(get-in communities [id :chats])))
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [chats]}] _]
|
||||
chats))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/community-color
|
||||
:<- [:communities]
|
||||
(fn [communities [_ id]]
|
||||
(get-in communities [id :color])))
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [color]}] _]
|
||||
color))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/community-outro-message
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [outro-message]}] _]
|
||||
outro-message))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/community-joined
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [joined]}] _]
|
||||
joined))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/community-members
|
||||
:<- [:communities]
|
||||
(fn [communities [_ id]]
|
||||
(get-in communities [id :members])))
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:communities/community community-id])])
|
||||
(fn [[{:keys [members]}] _]
|
||||
members))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/current-community-members
|
||||
@@ -160,6 +177,13 @@
|
||||
(fn [requests [_ community-id]]
|
||||
(:id (get requests community-id))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/has-pending-request-to-join?
|
||||
(fn [[_ community-id]]
|
||||
(re-frame/subscribe [:communities/my-pending-request-to-join community-id]))
|
||||
(fn [request]
|
||||
(boolean request)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/edited-community
|
||||
:<- [:communities]
|
||||
@@ -243,7 +267,8 @@
|
||||
emoji
|
||||
can-view?
|
||||
can-post?
|
||||
token-gated?]}]]
|
||||
token-gated?
|
||||
hide-if-permissions-not-met?]}]]
|
||||
(let [category-id (if (seq categoryID) categoryID constants/empty-category-id)
|
||||
{:keys [unviewed-messages-count
|
||||
unviewed-mentions-count
|
||||
@@ -259,19 +284,21 @@
|
||||
:collapsed? (get collapsed-categories
|
||||
category-id)
|
||||
:chats [])))
|
||||
categorized-chat {:name name
|
||||
:emoji emoji
|
||||
:muted? muted
|
||||
:unread-messages? (pos? unviewed-messages-count)
|
||||
:position position
|
||||
:mentions-count (or unviewed-mentions-count 0)
|
||||
:can-post? can-post?
|
||||
locked? (when token-gated?
|
||||
(and (not can-view?)
|
||||
(not can-post?)))
|
||||
categorized-chat {:name name
|
||||
:emoji emoji
|
||||
:muted? muted
|
||||
:unread-messages? (pos? unviewed-messages-count)
|
||||
:position position
|
||||
:mentions-count (or unviewed-mentions-count 0)
|
||||
:can-post? can-post?
|
||||
;; NOTE: this is a troolean nil->no permissions, true->no access, false
|
||||
;; -> has access
|
||||
:locked? (when token-gated?
|
||||
(and (not can-view?)
|
||||
(not can-post?)))
|
||||
:id id}]
|
||||
:locked? locked?
|
||||
:hide-if-permissions-not-met? (and hide-if-permissions-not-met? locked?)
|
||||
:id id}]
|
||||
(update-in acc-with-category [category-id :chats] conj categorized-chat))))
|
||||
|
||||
(re-frame/reg-sub
|
||||
@@ -292,7 +319,12 @@
|
||||
(reduce reduce-fn {})
|
||||
(sort-by (comp :position second))
|
||||
(map (fn [[k v]]
|
||||
[k (update v :chats #(sort-by :position %))])))]
|
||||
[k
|
||||
(-> v
|
||||
(update :chats #(sort-by :position %))
|
||||
(update :chats
|
||||
#(filter (comp not :hide-if-permissions-not-met?)
|
||||
%)))])))]
|
||||
categories-and-chats)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
@@ -306,12 +338,13 @@
|
||||
[checking-permissions?
|
||||
token-images
|
||||
{:keys [satisfied criteria]}]
|
||||
(let [sym (:symbol criteria)
|
||||
amount (:amount criteria)]
|
||||
(let [sym (:symbol criteria)
|
||||
amount-in-wei (:amountInWei criteria)
|
||||
decimals (:decimals criteria)]
|
||||
{:symbol sym
|
||||
:sufficient? satisfied
|
||||
:loading? checking-permissions?
|
||||
:amount (wallet.utils/remove-trailing-zeroes amount)
|
||||
:amount (money/to-fixed (money/token->unit amount-in-wei decimals))
|
||||
:img-src (get token-images sym)}))
|
||||
|
||||
(re-frame/reg-sub
|
||||
@@ -320,6 +353,7 @@
|
||||
(fn [permissions [_ id]]
|
||||
(get permissions id)))
|
||||
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/checking-permissions-all-by-id
|
||||
:<- [:communities/permissions-check-all]
|
||||
|
||||
@@ -289,19 +289,23 @@
|
||||
checks {:checking? checking-permissions?
|
||||
:check
|
||||
{:satisfied true
|
||||
:highestRole {:type constants/community-token-permission-become-admin
|
||||
:criteria [{:tokenRequirement [{:satisfied true
|
||||
:criteria {:contract_addresses
|
||||
{:5 "0x0"}
|
||||
:type 1
|
||||
:symbol "DAI"
|
||||
:amount "5.0"
|
||||
:decimals 18}}]}
|
||||
{:tokenRequirement [{:satisfied false
|
||||
:criteria {:type 1
|
||||
:symbol "ETH"
|
||||
:amount "0.002"
|
||||
:decimals 18}}]}]}
|
||||
:highestRole
|
||||
{:type constants/community-token-permission-become-admin
|
||||
:criteria [{:tokenRequirement [{:satisfied true
|
||||
:criteria {:contract_addresses
|
||||
{:5 "0x0"}
|
||||
:type 1
|
||||
:symbol "DAI"
|
||||
:amountInWei
|
||||
"5000000000000000000"
|
||||
:amount "5.0"
|
||||
:decimals 18}}]}
|
||||
{:tokenRequirement [{:satisfied false
|
||||
:criteria {:type 1
|
||||
:symbol "ETH"
|
||||
:amountInWei "2000000000000000"
|
||||
:amount "0.002"
|
||||
:decimals 18}}]}]}
|
||||
|
||||
:permissions
|
||||
{:a3dd5b6b-d93b-452c-b22a-09a8f42ec566 {:criteria [true false
|
||||
@@ -341,7 +345,7 @@
|
||||
:members {"0x04" {"roles" [1]}}}}
|
||||
:members {"0x04" {"roles" [1]}}
|
||||
:can-request-access? false
|
||||
:outroMessage "bla"
|
||||
:outro-message "bla"
|
||||
:verified false}]
|
||||
(swap! rf-db/app-db assoc-in [:communities community-id] community)
|
||||
(swap! rf-db/app-db assoc-in [:communities/permissions-check community-id] checks)
|
||||
@@ -435,7 +439,7 @@
|
||||
:token-images {"ETH" token-image-eth}
|
||||
:name "Community super name"
|
||||
:can-request-access? false
|
||||
:outroMessage "bla"
|
||||
:outro-message "bla"
|
||||
:verified false}]
|
||||
(swap! rf-db/app-db assoc-in [:communities community-id] community)
|
||||
(swap! rf-db/app-db assoc-in [:communities/permissions-check-all community-id] checks)
|
||||
@@ -471,7 +475,7 @@
|
||||
:token-images {"ETH" token-image-eth}
|
||||
:name "Community super name"
|
||||
:can-request-access? false
|
||||
:outroMessage "bla"
|
||||
:outro-message "bla"
|
||||
:verified false}]
|
||||
(swap! rf-db/app-db assoc-in [:communities community-id] community)
|
||||
(swap! rf-db/app-db assoc-in [:communities/permissions-check-all community-id] checks)
|
||||
|
||||
@@ -40,6 +40,13 @@
|
||||
(fn [permissions [_ id]]
|
||||
(get permissions id)))
|
||||
|
||||
(re-frame/reg-sub
|
||||
:communities/permissions-check-for-selection-checking?
|
||||
(fn [[_ community-id]]
|
||||
(re-frame/subscribe [:communities/permissions-check-for-selection community-id]))
|
||||
(fn [check]
|
||||
(:checking? check)))
|
||||
|
||||
(re-frame/reg-sub :communities/highest-role-for-selection
|
||||
(fn [[_ community-id]]
|
||||
[(re-frame/subscribe [:communities/permissions-check-for-selection community-id])])
|
||||
|
||||
@@ -120,12 +120,12 @@
|
||||
(re-frame/reg-sub
|
||||
:dimensions/window-width
|
||||
:<- [:dimensions/window]
|
||||
:width)
|
||||
:-> :width)
|
||||
|
||||
(re-frame/reg-sub
|
||||
:dimensions/window-height
|
||||
:<- [:dimensions/window]
|
||||
:height)
|
||||
:-> :height)
|
||||
|
||||
(re-frame/reg-sub
|
||||
:dimensions/small-screen?
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
[goog.object :as object]
|
||||
utils.string))
|
||||
|
||||
(def emoji-regex
|
||||
#"(\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])")
|
||||
|
||||
(def lib (.-lib emojis))
|
||||
|
||||
(defn get-char
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"_comment": "Instead use: scripts/update-status-go.sh <rev>",
|
||||
"owner": "status-im",
|
||||
"repo": "status-go",
|
||||
"version": "v0.177.0",
|
||||
"commit-sha1": "894eb5758e8ff8f449312f92149f8698058d0fbb",
|
||||
"src-sha256": "1q0l7ndm6s4kai6zn86mka5fxk2hl60qhlhfy9wh9lrl6a62r15p"
|
||||
"version": "release/0.177.x",
|
||||
"commit-sha1": "3d57d86dd91340cd1435d5e0d6224c958a647c81",
|
||||
"src-sha256": "1j1px8pxxmzaa2n68gxszbb8kp8rjaw4q61g8f6858bmqj3fvi1f"
|
||||
}
|
||||
|
||||
@@ -128,8 +128,7 @@ class TestDeepLinksOneDevice(MultipleSharedDeviceTestCase):
|
||||
community_url = "https://status.app/c/Ow==#zQ3shbmfT3hvh4mKa1v6uAjjyztQEroh8Mfn6Ckegjd7LT3XK"
|
||||
self.home.open_link_from_google_search_app(community_url, app_package)
|
||||
self.sign_in.sign_in()
|
||||
if not self.home.element_by_translation_id(
|
||||
"community-admins-will-review-your-request").is_element_displayed(10):
|
||||
if not self.community_view.join_button.is_element_displayed(10):
|
||||
self.errors.append("Closed community was not requested to join by the url %s" % community_url)
|
||||
|
||||
# ToDo: enable when https://github.com/status-im/status-mobile/issues/18074 is fixed
|
||||
|
||||
@@ -834,7 +834,7 @@ class ChatView(BaseView):
|
||||
self.edit_group_chat_name_button = Button(self.driver, accessibility_id="edit-button")
|
||||
self.edit_group_chat_name_edit_box = EditBox(self.driver, accessibility_id="new-chat-name")
|
||||
self.done_button = Button(self.driver, accessibility_id="done")
|
||||
self.create_button = Button(self.driver, accessibility_id="create-group-chat-button")
|
||||
self.create_group_chat_button = Button(self.driver, accessibility_id="Create group chat")
|
||||
## Group invites
|
||||
self.group_invite_button = Button(self.driver, accessibility_id="invite-chat-button")
|
||||
self.group_invite_link_text = Text(self.driver,
|
||||
|
||||
@@ -442,8 +442,8 @@ class HomeView(BaseView):
|
||||
"User with the name '%s' is not in contacts list so can't create a group chat" % user_name)
|
||||
check_box.click_until_presence_of_element(chat.get_username_checkbox(user_name, state_on=True))
|
||||
self.setup_chat_button.click()
|
||||
chat.chat_name_editbox.send_keys(group_chat_name)
|
||||
chat.create_button.click()
|
||||
self.get_sign_in_view().profile_title_input.send_keys(group_chat_name)
|
||||
chat.create_group_chat_button.click()
|
||||
self.driver.info("## Group chat %s is created successfully!" % group_chat_name, device=False)
|
||||
return chat
|
||||
|
||||
|
||||
@@ -187,7 +187,7 @@ class SignInView(BaseView):
|
||||
|
||||
# New onboarding
|
||||
self.generate_keys_button = Button(self.driver, translation_id="lets-go")
|
||||
self.profile_your_name_edit_box = EditBox(self.driver, accessibility_id="profile-title-input")
|
||||
self.profile_title_input = EditBox(self.driver, accessibility_id="profile-title-input")
|
||||
self.profile_continue_button = Button(self.driver, accessibility_id="submit-create-profile-button")
|
||||
self.profile_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-1")
|
||||
self.profile_repeat_password_edit_box = EditBox(self.driver, translation_id="password-creation-placeholder-2")
|
||||
@@ -213,7 +213,7 @@ class SignInView(BaseView):
|
||||
self.profile_confirm_password_button.click()
|
||||
|
||||
def set_profile(self, username: str, set_image=False):
|
||||
self.profile_your_name_edit_box.send_keys(username)
|
||||
self.profile_title_input.send_keys(username)
|
||||
self.profile_continue_button.click_until_presence_of_element(self.profile_password_edit_box)
|
||||
if set_image:
|
||||
pass
|
||||
@@ -231,7 +231,7 @@ class SignInView(BaseView):
|
||||
self.show_profiles_button.click()
|
||||
self.plus_profiles_button.click()
|
||||
self.create_new_profile_button.click()
|
||||
self.generate_keys_button.click_until_presence_of_element(self.profile_your_name_edit_box)
|
||||
self.generate_keys_button.click_until_presence_of_element(self.profile_title_input)
|
||||
self.set_profile(username)
|
||||
self.set_password(password)
|
||||
if self.enable_biometric_maybe_later_button.is_element_displayed(10):
|
||||
@@ -270,7 +270,7 @@ class SignInView(BaseView):
|
||||
self.create_new_profile_button.click()
|
||||
self.use_recovery_phrase_button.click()
|
||||
self.passphrase_edit_box.send_keys(passphrase)
|
||||
self.continue_button.click_until_presence_of_element(self.profile_your_name_edit_box)
|
||||
self.continue_button.click_until_presence_of_element(self.profile_title_input)
|
||||
self.set_profile(username, set_image)
|
||||
self.set_password(password)
|
||||
if self.enable_biometric_maybe_later_button.is_element_displayed(10):
|
||||
|
||||
@@ -235,7 +235,6 @@
|
||||
"membership-title": "Membership requirement",
|
||||
"create-channel-title": "New channel",
|
||||
"edit-channel-title": "Edit channel",
|
||||
"community-admins-will-review-your-request": "Community admins will review your request",
|
||||
"community-thumbnail-image": "Thumbnail image",
|
||||
"community-emoji-thumbnail-title": "Thumbnail",
|
||||
"community-thumbnail-upload": "Upload",
|
||||
@@ -312,6 +311,7 @@
|
||||
"create-a-pin": "Create a 6-digit passcode",
|
||||
"create-a-puk": "Create a 12-digit PUK",
|
||||
"create-group-chat": "Create group chat",
|
||||
"name-your-group": "Name your group",
|
||||
"create-multiaccount": "Generate keys",
|
||||
"create-new-key": "Get new keys",
|
||||
"create-pin": "Create 6-digit passcode",
|
||||
@@ -2411,6 +2411,7 @@
|
||||
"no-other-accounts": "No other accounts",
|
||||
"here-is-a-cat-in-a-box-instead": "Here’s a cat in a box instead",
|
||||
"accounts-count": "{{count}} accounts",
|
||||
"n-m-people": "{{n}}/{{m}} people",
|
||||
"enter-eth": "Enter any ETH address or ENS name.",
|
||||
"eth-or-ens": "ETH address or ENS name.",
|
||||
"type-pairing-code": "Type or paste pairing code",
|
||||
@@ -2556,5 +2557,9 @@
|
||||
"ledger-live": "Ledger live",
|
||||
"keep-key": "KeepKey",
|
||||
"type-your-path": "Type your own derivation path",
|
||||
"default-format": "Default format"
|
||||
"default-format": "Default format",
|
||||
"address-count": {
|
||||
"one": "1 address",
|
||||
"other": "{{count}} addresses"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user