diff --git a/.gitignore b/.gitignore index e4c7e47f89c..ca93eceb4c0 100644 --- a/.gitignore +++ b/.gitignore @@ -195,5 +195,5 @@ test/appium/tests/users.py ## git hooks lefthook.yml -## metro server logs -metro-server-logs.log +## build time logs +/logs/*.log diff --git a/Makefile b/Makefile index 11a8d1de954..18ca317c783 100644 --- a/Makefile +++ b/Makefile @@ -36,6 +36,8 @@ endif export TMPDIR = /tmp/tmp-status-mobile-$(BUILD_TAG) # This has to be specified for both the Node.JS server process and the Qt process. export REACT_SERVER_PORT ?= 5001 +# Default metro port used by scripts/run-android.sh. +export RCT_METRO_PORT ?= 8081 # Fix for ERR_OSSL_EVP_UNSUPPORTED error. export NODE_OPTIONS += --openssl-legacy-provider # The path can be anything, but home is usually safest. @@ -294,11 +296,8 @@ show-ios-devices: ##@other shows connected ios device and its name # TODO: fix IOS_STATUS_GO_TARGETS to be either amd64 or arm64 when RN is upgraded run-ios-device: export TARGET := ios run-ios-device: export IOS_STATUS_GO_TARGETS := ios/arm64;iossimulator/amd64 -run-ios-device: ##@run iOS app and start it on a connected device by its name -ifndef DEVICE_NAME - $(error Usage: make run-ios-device DEVICE_NAME=your-device-name) -endif - react-native run-ios --device "$(DEVICE_NAME)" +run-ios-device: ##@run iOS app and start it on the first connected iPhone + @scripts/run-ios-device.sh #-------------- # Tests diff --git a/README.md b/README.md index f38b72c1a80..e7a56e20814 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ project dependencies, coding guidelines and testing procedures. Check out our [coding guidelines](doc/new-guidelines.md). - **Community Management** -Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and the long-lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.im/about) +Metcalfe's law states that the value of a network is proportional to the square of the number of connected users of the system - without community Status is meaningless. We're looking to create a positive, fun environment to explore new ideas, experiment and grow the Status community. Building a community takes a lot of work but the people you'll meet and the long-lasting relationships you form will be well worth it, check out our [Mission and Community Principles](https://status.app/manifesto) - **Specification / Documentation** John Dewey once said, "Education is not preparation for life; education is life *itself* ". Developers and Designers need guidance and it all starts from documentation and specifications. Our software is only as good as its documentation, check out our [docs](doc/) and see how you can improve what we have. @@ -53,10 +53,10 @@ Status is a visual interface to make permanent changes on the Blockchain, it han - **Evangelism** Help us spread the word! Tell a friend *right now*, in fact, tell **everyone** - yell from a mountain if you have to, every person counts! If you've got a great story to tell or have some interesting way you've spread the word about Status let us know about it in our [chat](https://join.status.im/chat/public/status) - + ## Give me Binaries! -You can get our Beta builds for both Android and iOS on our [website](https://status.im), through our [nightly builds](https://status.im/nightly/), or by [building it yourself](https://status.im/technical/build_status/). +You can get our Beta builds for both Android and iOS on our [website](https://status.app), through our [nightly builds](https://status.im/nightly/), or by [building it yourself](doc/starting-guide.md). ## Core Contributors diff --git a/ci/Jenkinsfile.combined b/ci/Jenkinsfile.combined index c2a2f72d246..c9a1fc86b1d 100644 --- a/ci/Jenkinsfile.combined +++ b/ci/Jenkinsfile.combined @@ -35,8 +35,6 @@ pipeline { stage('Prep') { steps { script { println("Current JOB: ${env.JOB_NAME}") - /* just for a shorter access */ - btype = utils.getBuildType() } } } stage('Build') { @@ -84,10 +82,8 @@ pipeline { when { expression { params.PUBLISH } } steps { script { switch (btype) { - case 'nightly': - /* Create JSON file with newest build URLs */ + case 'nightly': /* Create JSON file with newest build URLs */ s3.updateBucketJSON(urls, 'latest.json'); - build(job: 'website/status.im', wait: false); break; case 'release': github.publishReleaseFiles(repo: 'status-mobile'); diff --git a/doc/README.md b/doc/README.md index e446b5a81a6..637ce86026d 100644 --- a/doc/README.md +++ b/doc/README.md @@ -28,6 +28,8 @@ [Contributing to status-go](status-go-changes.md) +[Malli schemas (recorded demo)](https://www.youtube.com/watch?v=SlRio70aYVI) ([slides](files/forging-code-with-schemas-sep-2023-slides.pdf)) + ## Testing [How to run local tests](testing.md) diff --git a/doc/files/forging-code-with-schemas-sep-2023-slides.pdf b/doc/files/forging-code-with-schemas-sep-2023-slides.pdf new file mode 100644 index 00000000000..7d8f65c7f22 Binary files /dev/null and b/doc/files/forging-code-with-schemas-sep-2023-slides.pdf differ diff --git a/doc/starting-guide.md b/doc/starting-guide.md index 0d1fff25140..959f098c9a1 100644 --- a/doc/starting-guide.md +++ b/doc/starting-guide.md @@ -4,21 +4,41 @@ This document provides information on how to start developing Status App. # Getting Started -To start developing start a shell for the platform you are interested in. +To start developing clone the status-mobile repo in the directory of your choice. ``` -make shell TARGET=android +git clone https://github.com/status-im/status-mobile.git ``` -This step will take a while the first time as it will download all dependencies. -# Development +Then open a terminal and cd into this directory. -There are three steps necessary to start development, in this case for Android: +``` +cd status-mobile +``` + +Then build the clojure terminal + +``` +make run-clojure +``` + +note: ⚠️ This might take a while if this is your first time. + +This command installs `nix` and pulls in all the dependencies. +Do answer with "Y" to all the prompts and press "Enter" when `nix` setup asks you to Acknowledge. +This command builds the `jsbundle` and then compiles `Clojure` into `JavaScript`, watches for changes on `cljs` files, and hot-reloads code in the app. -1. `make run-clojure` - Compiles Clojure into JavaScript, watches for changes on cljs files, and hot-reloads code in the app. -2. `make run-android` or `make run-ios` - Builds the Android/iOS app, starts it on the device and starts metro bundler. +wait till you see the following message : -The first two will continue watching for changes and keep re-building the app. They need to be ready first. -The last one will exit once the app is up and ready. +``` +[:mobile] Build completed. (1801 files, 52 compiled, 0 warnings, 9.52s) +``` + +Once the clojure terminal is running you need to run the appropriate command next for your platform in a separate terminal : + +`make run-android` or `make run-ios` + +These commands will build the app, start a metro bundler and deploy the app on your simulator OR connected device (android only). For building and deploying to connected iPhones use `make run-ios-device` instead of `make run-ios` +Also check [developing on a physical iOS Device](#Additional-requirements-for-developing-on-physical-ios-device). ## Simulators and Devices ### Android @@ -45,13 +65,9 @@ Running `make run-ios` will target `iPhone 13` by default. If you need to run on any other simulator, you can specify the simulator type by adding the `SIMULATOR` flag: ```sh -make run-ios SIMULATOR="iPhone 13" +make run-ios SIMULATOR="iPhone 15" ``` -#### Running on a physical device - -Some manual steps are necessary for [developing on a physical iOS Device](#physical-ios-device). - # Build release To build the app, you can simply run on of the following: @@ -101,16 +117,15 @@ Steps: 3. [Setup Git to sign commits](https://help.github.com/en/github/authenticating-to-github/signing-commits) 4. [Setup GitHub to validate commits](https://help.github.com/en/github/authenticating-to-github/adding-a-new-gpg-key-to-your-github-account) -## Physical iOS Device +## Additional requirements for developing on Physical iOS Device To use a physical iPhone your device UDID must be added to provisioning profiles and your Apple account invited as Developer to Status team. 1. [Get your UDID of your iPhone.](https://www.extentia.com/post/finding-the-udid-of-an-ios-device) 2. Request from someone with access like @cammellos or @jakubgs to - - Add the UDID to development devices on Apple Developer Portal. - - Invite your Apple account to be Developer in Status team. -3. Run a build in XCode using the project from `status-mobile/ios` directory. - - You might see error: `Select a development team in the Signing & Capabilities editor` - - Select `Status Research & Development GmbH` as the development team and rebuild again. - -Once build finishes Status should start on your iPhone with its logs in terminal running `make run-metro`. +- Add the UDID to development devices on Apple Developer Portal. +- Invite your Apple account to be Developer in Status team. +3. Open XCode using the project from `status-mobile/ios` directory. +- You might see error: `Select a development team in the Signing & Capabilities editor` +- Select `Status Research & Development GmbH` as the development team. +4. In a new terminal execute `make clean` and then `make xcode-clean` diff --git a/doc/testing.md b/doc/testing.md index 82b14078ff1..c78d5b6e9c3 100644 --- a/doc/testing.md +++ b/doc/testing.md @@ -2,14 +2,12 @@ ## Unit & integration tests -To run tests: +To run all tests: ``` make test ``` - - Also test watcher can be launched. It will re-run the entire test suite when any file is modified ``` @@ -51,18 +49,46 @@ Here I'm showing a terminal-only experience using Tmux (left pane Emacs, right p [2022-12-19 13-17.webm](https://user-images.githubusercontent.com/46027/208471199-1909c446-c82d-42a0-9350-0c15ca562713.webm) -## Component tests +## Component tests only To run tests: ``` - make component-test +make component-test ``` Also test watcher can be launched. It will re-run the entire test suite when any file is modified ``` - make component-test-watch +make component-test-watch ``` Check [component tests doc](./component-tests-overview.md) for more. + +## Unit tests only + +To run unit tests: + +``` +make test-unit +``` + +Also test watcher can be launched. It will re-run the entire test suite when any file is modified + +``` +make test-unit WATCH=true +``` + +## Integration tests only + +To run integration tests: + +``` +make test-integration +``` + +Also test watcher can be launched. It will re-run the entire test suite when any file is modified + +``` +make test-integration WATCH=true +``` diff --git a/doc/troubleshooting.md b/doc/troubleshooting.md index e4c1b97d37b..a2a6f7204ae 100644 --- a/doc/troubleshooting.md +++ b/doc/troubleshooting.md @@ -88,6 +88,7 @@ info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this Update yarn.lock file. In order to do this, perform the following steps on a clean `status-mobile` repo: ``` cd status-mobile +make shell yarn install ``` and don't forget to commit updated `yarn.lock` together with `package.json`. @@ -127,23 +128,3 @@ Status-mobile uses `shadow-cljs` for hot reloading changes and uses its own [rel ### Solution Open react native's [In-App Developer Menu](https://reactnative.dev/docs/debugging#accessing-the-in-app-developer-menu) and press "Disable Fast Refresh" or "Disable Hot Reloading" - -## App Crashes after few reloads - -### Cause -For x86 CPU architecture Android Devices, Hermes is creating the issue and the app crashes after a few reloads. -([Original Issue](https://github.com/status-im/status-mobile/issues/14031)) - -
- How to Find CPU architecture - - CPU architecture of android device can be found using - - `adb shell uname -m` or - - `adb shell getprop ro.product.cpu.abilist` - -
- -### Solution -Disable Hermes while building the app - -`make run-android DISABLE_HERMES=true` diff --git a/logs/README.md b/logs/README.md new file mode 100644 index 00000000000..eaea0d52ed6 --- /dev/null +++ b/logs/README.md @@ -0,0 +1,18 @@ +# Description + +This directory is the destination of logs created during build time of debug builds. + +# Logs + +* `xcrun_device_install.log` - Output from `status-mobile/scripts/run-ios-device.sh`. + - Created by redirecting output of `xcrun simctl install "$UDID" "$APP_PATH"`. +* `xcrun_device_process_launch.log` - Output from `status-mobile/scripts/run-ios-device.sh`. + - Created by specifying `--json-output` flag for `xcrun devicectl device process launch --no-activate --verbose --device "${DEVICE_UUID}" "${INSTALLATION_URL}"`. +* `xcrun_device_process_resume.log` - Output from `status-mobile/scripts/run-ios-device.sh`. + - Created by redirecting output of `xcrun devicectl device process resume --device "${DEVICE_UUID}" --pid "${STATUS_PID}"`. +* `adb_install.log` - Output from `scripts/run-android.sh`. + - Created by redirecting output of `adb install -r ./result/app-debug.apk`. +* `adb_shell_monkey.log` - Output from `status-mobile/scripts/run-android.sh`. + - Created by redirecting output of `adb shell monkey -p im.status.ethereum.debug 1 >`. +* `ios_simulators_list.log` - Output from `status-mobile/scripts/run-ios.sh`. + - Created by redirecting output of `xcrun simctl list devices -j`. diff --git a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/AccountManager.java b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/AccountManager.java index fd25e086047..02b78658da3 100644 --- a/modules/react-native-status/android/src/main/java/im/status/ethereum/module/AccountManager.java +++ b/modules/react-native-status/android/src/main/java/im/status/ethereum/module/AccountManager.java @@ -342,4 +342,14 @@ public void deleteMultiaccount(final String keyUID, final Callback callback) thr final String keyStoreDir = this.utils.getKeyStorePath(keyUID); this.utils.executeRunnableStatusGoMethod(() -> Statusgo.deleteMultiaccount(keyUID, keyStoreDir), callback); } + + @ReactMethod + public void getRandomMnemonic(final Callback callback) throws JSONException { + this.utils.executeRunnableStatusGoMethod(() -> Statusgo.getRandomMnemonic(), callback); + } + + @ReactMethod + public void createAccountFromMnemonicAndDeriveAccountsForPaths(final String mnemonic, final Callback callback) throws JSONException { + this.utils.executeRunnableStatusGoMethod(() -> Statusgo.createAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic), callback); + } } diff --git a/modules/react-native-status/ios/RCTStatus/AccountManager.m b/modules/react-native-status/ios/RCTStatus/AccountManager.m index 01d55601875..7092ef5fe66 100644 --- a/modules/react-native-status/ios/RCTStatus/AccountManager.m +++ b/modules/react-native-status/ios/RCTStatus/AccountManager.m @@ -214,4 +214,20 @@ -(NSString *) prepareDirAndUpdateConfig:(NSString *)config NSLog(@"%@", result); } +RCT_EXPORT_METHOD(getRandomMnemonic:(RCTResponseSenderBlock)callback) { +#if DEBUG + NSLog(@"GetRandomMnemonic() method called"); +#endif + NSString *result = StatusgoGetRandomMnemonic(); + callback(@[result]); +} + +RCT_EXPORT_METHOD(createAccountFromMnemonicAndDeriveAccountsForPaths:(NSString *)mnemonic callback:(RCTResponseSenderBlock)callback) { +#if DEBUG + NSLog(@"createAccountFromMnemonicAndDeriveAccountsForPaths() method called"); +#endif + NSString *result = StatusgoCreateAccountFromMnemonicAndDeriveAccountsForPaths(mnemonic); + callback(@[result]); +} + @end diff --git a/nix/mobile/ios/default.nix b/nix/mobile/ios/default.nix index affb530363c..ca423f50f17 100644 --- a/nix/mobile/ios/default.nix +++ b/nix/mobile/ios/default.nix @@ -20,8 +20,8 @@ in { buildInputs = with pkgs; [ xcodeWrapper watchman procps flock # used in nix/scripts/node_modules.sh - ios-deploy # used in 'make run-ios-device' xcbeautify # used in 'make run-ios' + libimobiledevice # used in `make run-ios-device` ]; # WARNING: Executes shellHook in reverse order. diff --git a/nix/overlay.nix b/nix/overlay.nix index 63875026fd6..b0029f92f7c 100644 --- a/nix/overlay.nix +++ b/nix/overlay.nix @@ -26,18 +26,6 @@ in { react-native = callPackage ./deps/react-native { }; }; - # Fix for missing libarclite_macosx.a in Xcode 14.3. - # https://github.com/ios-control/ios-deploy/issues/580 - ios-deploy = super.darwin.ios-deploy.overrideAttrs (old: rec { - version = "1.12.2"; - src = super.fetchFromGitHub { - owner = "ios-control"; - repo = "ios-deploy"; - rev = version; - sha256 = "sha256-TVGC+f+1ow3b93CK3PhIL70le5SZxxb2ug5OkIg8XCA"; - }; - }); - # Clojure's linter receives frequent upgrades, and we want to take advantage # of the latest available rules. clj-kondo = super.clj-kondo.override rec { diff --git a/scripts/run-android.sh b/scripts/run-android.sh index 8f4c11aa84a..a013b174a6e 100755 --- a/scripts/run-android.sh +++ b/scripts/run-android.sh @@ -1,37 +1,9 @@ #!/usr/bin/env bash set -euo pipefail -set -m # needed to access jobs GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel) - -# We run Metro in background while calling adb. -cleanupMetro() { - pkill -f run-metro.sh - rm -f metro-server-logs.log -} - -# Using function gives a neater jobspec name. -runMetro() { - nohup "${GIT_ROOT}/scripts/run-metro.sh" 2>&1 \ - | tee metro-server-logs.log -} - -waitForMetro() { - set +e # Allow grep command to fail in the loop. - TIMEOUT=5 - echo "Waiting for Metro server..." >&2 - while ! grep -q "Welcome to Metro" metro-server-logs.log; do - echo -n "." >&2 - sleep 1 - if ((TIMEOUT == 0)); then - echo -e "\nMetro server timed out, exiting" >&2 - set -e # Restore errexit for rest of script. - return 1 - fi - ((TIMEOUT--)) - done - set -e # Restore errexit for rest of script. -} +ADB_INSTALL_LOG_FILE="${GIT_ROOT}/logs/adb_install.log" +ADB_SHELL_MONKEY_LOG_FILE="${GIT_ROOT}/logs/adb_shell_monkey.log" # Generate android debug build. export ANDROID_ABI_INCLUDE=$("${GIT_ROOT}/scripts/adb_devices_abis.sh") @@ -40,14 +12,19 @@ export BUILD_TYPE=debug "${GIT_ROOT}/scripts/build-android.sh" # Install the APK on running emulator or android device. -adb install ./result/app-debug.apk - -trap cleanupMetro EXIT ERR INT QUIT -runMetro & -waitForMetro +installAndLaunchApp() { + adb install -r ./result/app-debug.apk > "${ADB_INSTALL_LOG_FILE}" 2>&1 + "${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1 + # connected android devices need this port to be exposed for metro + adb reverse "tcp:${RCT_METRO_PORT}" "tcp:${RCT_METRO_PORT}" + adb shell monkey -p im.status.ethereum.debug 1 > "${ADB_SHELL_MONKEY_LOG_FILE}" 2>&1 +} -# Start the installed app. -adb shell monkey -p im.status.ethereum.debug 1 +showAdbLogs() { + cat "${ADB_INSTALL_LOG_FILE}" >&2; + cat "${ADB_SHELL_MONKEY_LOG_FILE}" >&2; +} -# bring metro job to foreground -fg 'runMetro' +trap showAdbLogs EXIT ERR INT QUIT +installAndLaunchApp & +exec "${GIT_ROOT}/scripts/run-metro.sh" 2>&1 diff --git a/scripts/run-ios-device.sh b/scripts/run-ios-device.sh new file mode 100755 index 00000000000..11cbd5f2dd2 --- /dev/null +++ b/scripts/run-ios-device.sh @@ -0,0 +1,55 @@ +#!/usr/bin/env bash +set -euo pipefail +set -m # needed to access jobs + +GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel) +XCRUN_DEVICE_INSTALL_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_install.log" +XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_process_launch.log" +XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR="${GIT_ROOT}/logs/xcrun_device_process_resume.log" + +# Install on the connected device +installAndLaunchApp() { + xcrun devicectl device install app --device "${DEVICE_UUID}" "${APP_PATH}" --json-output "${XCRUN_DEVICE_INSTALL_LOG_DIR}" 2>&1 + + # Extract installationURL + INSTALLATION_URL=$(jq -r '.result.installedApplications[0].installationURL' "${XCRUN_DEVICE_INSTALL_LOG_DIR}") + + # launch the app and put it in background + xcrun devicectl device process launch --no-activate --verbose --device "${DEVICE_UUID}" "${INSTALLATION_URL}" --json-output "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}" + + # Extract background PID of status app + STATUS_PID=$(jq -r '.result.process.processIdentifier' "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}") + "${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1 + + # now that metro is ready, resume the app from background + xcrun devicectl device process resume --device "${DEVICE_UUID}" --pid "${STATUS_PID}" > "${XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR}" 2>&1 +} + +showXcrunLogs() { + cat "${XCRUN_DEVICE_INSTALL_LOG_DIR}" >&2; + cat "${XCRUN_DEVICE_PROCESS_LAUNCH_LOG_DIR}" >&2; + cat "${XCRUN_DEVICE_PROCESS_RESUME_LOG_DIR}" >&2; +} + +# find the first connected iPhone's UUID +DEVICE_UUID=$(idevice_id -l) + +# Check if any device is connected +if [ -z "${DEVICE_UUID}" ]; then + echo "No connected iPhone device detected." + exit 1 +else + echo "Connected iPhone UDID: ${DEVICE_UUID}" +fi + +BUILD_DIR="${GIT_ROOT}/build" + +#iOS build of debug scheme +xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="${DEVICE_UUID}" -derivedDataPath "${BUILD_DIR}" -verbose | xcbeautify + +APP_PATH="${BUILD_DIR}/Build/Products/Debug-iphoneos/StatusIm.app" + +trap showXcrunLogs EXIT ERR INT QUIT +installAndLaunchApp & +exec "${GIT_ROOT}/scripts/run-metro.sh" 2>&1 + diff --git a/scripts/run-ios.sh b/scripts/run-ios.sh index f9f94c661b5..49a3ae45fce 100755 --- a/scripts/run-ios.sh +++ b/scripts/run-ios.sh @@ -3,34 +3,21 @@ set -euo pipefail set -m # needed to access jobs GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel) +XCRUN_INSTALL_LOG_FILE="${GIT_ROOT}/logs/xcrun_install.log" +XCRUN_LAUNCH_LOG_FILE="${GIT_ROOT}/logs/xcrun_launch.log" +XCRUN_SIMULATOR_JSON_FILE="${GIT_ROOT}/logs/ios_simulators_list.log" -# We run Metro in background while calling adb. -cleanupMetro() { - pkill -f run-metro.sh - rm -f metro-server-logs.log -} +# Install on the simulator +installAndLaunchApp() { + xcrun simctl install "$UDID" "$APP_PATH" > "${XCRUN_INSTALL_LOG_FILE}" 2>&1 + "${GIT_ROOT}/scripts/wait-for-metro-port.sh" 2>&1 + xcrun simctl launch "$UDID" im.status.ethereum.debug > "${XCRUN_LAUNCH_LOG_FILE}" 2>&1 -# Using function gives a neater jobspec name. -runMetro() { - nohup "${GIT_ROOT}/scripts/run-metro.sh" 2>&1 \ - | tee metro-server-logs.log } -waitForMetro() { - set +e # Allow grep command to fail in the loop. - TIMEOUT=5 - echo "Waiting for Metro server..." >&2 - while ! grep -q "Welcome to Metro" metro-server-logs.log; do - echo -n "." >&2 - sleep 1 - if ((TIMEOUT == 0)); then - echo -e "\nMetro server timed out, exiting" >&2 - set -e # Restore errexit for rest of script. - return 1 - fi - ((TIMEOUT--)) - done - set -e # Restore errexit for rest of script. +showXcrunLogs() { + cat "${XCRUN_INSTALL_LOG_FILE}" >&2; + cat "${XCRUN_LAUNCH_LOG_FILE}" >&2; } # Check if the first argument is provided @@ -39,41 +26,44 @@ if [ -z "${1-}" ]; then exit 1 fi -SIMULATOR=${1} +# fetch available iOS Simulators +xcrun simctl list devices -j > "${XCRUN_SIMULATOR_JSON_FILE}" -# get our desired UUID -UUID=$(xcrun simctl list devices | grep -E "$SIMULATOR \(" | head -n 1 | awk -F '[()]' '{print $2}') +SIMULATOR=${1} -# get simulator status -SIMULATOR_STATE=$(xcrun simctl list devices | grep -E "$SIMULATOR \(" | head -n 1 | awk '{print $NF}') +# get the first available UDID for Simulators that match the name +read -r UDID SIMULATOR_STATE IS_AVAILABLE < <(jq --raw-output --arg simulator "${SIMULATOR}" ' + [ .devices[] | .[] | select(.name == $simulator) ] | + map(select(.isAvailable)) + map(select(.isAvailable | not)) | + first | + "\(.udid) \(.state) \(.isAvailable)" +' "${XCRUN_SIMULATOR_JSON_FILE}") + +if [ "${IS_AVAILABLE}" == false ] || [ "${UDID}" == null ]; then + echo "Error: Simulator ${SIMULATOR} is not available, Please find and install them." + echo "For help please refer" + echo "https://developer.apple.com/documentation/safari-developer-tools/adding-additional-simulators#Add-and-remove-Simulators " >&2 + exit 1 +fi # sometimes a simulator is already running, shut it down to avoid errors -if [ "$SIMULATOR_STATE" != "(Shutdown)" ]; then - xcrun simctl shutdown "$UUID" +if [ "${SIMULATOR_STATE}" != "Shutdown" ]; then + xcrun simctl shutdown "${UDID}" fi # boot up iOS for simulator -xcrun simctl boot "$UUID" +xcrun simctl boot "${UDID}" # start the simulator -open -a Simulator --args -CurrentDeviceUDID "$UUID" +open -a Simulator --args -CurrentDeviceUDID "${UDID}" BUILD_DIR="${GIT_ROOT}/build" #iOS build of debug scheme -xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="$UUID" -derivedDataPath "${BUILD_DIR}" | xcbeautify +xcodebuild -workspace "ios/StatusIm.xcworkspace" -configuration Debug -scheme StatusIm -destination id="${UDID}" -derivedDataPath "${BUILD_DIR}" -verbose | xcbeautify APP_PATH="${BUILD_DIR}/Build/Products/Debug-iphonesimulator/StatusIm.app" -# Install on the simulator -xcrun simctl install "$UUID" "$APP_PATH" - -trap cleanupMetro EXIT ERR INT QUIT -runMetro & -waitForMetro - -# launch the app when metro is ready -xcrun simctl launch "$UUID" im.status.ethereum.debug - -# bring metro job to foreground -fg 'runMetro' +trap showXcrunLogs EXIT ERR INT QUIT +installAndLaunchApp & +exec "${GIT_ROOT}/scripts/run-metro.sh" 2>&1 diff --git a/scripts/wait-for-metro-port.sh b/scripts/wait-for-metro-port.sh new file mode 100755 index 00000000000..67144cfe5a3 --- /dev/null +++ b/scripts/wait-for-metro-port.sh @@ -0,0 +1,14 @@ +#!/usr/bin/env bash +set -euo pipefail + +TIMEOUT=10 # Metro should not take this long to start. + +while [ "${TIMEOUT}" -gt 0 ]; do + if ! lsof -i:8081 &> /dev/null; then + echo "." + sleep 1 + ((TIMEOUT--)) + else + break + fi +done diff --git a/src/legacy/status_im/multiaccounts/logout/core.cljs b/src/legacy/status_im/multiaccounts/logout/core.cljs index 467d91ff85b..5310e9d4dc5 100644 --- a/src/legacy/status_im/multiaccounts/logout/core.cljs +++ b/src/legacy/status_im/multiaccounts/logout/core.cljs @@ -30,7 +30,6 @@ (let [key-uid (get-in db [:profile/profile :key-uid])] (rf/merge cofx {:set-root :progress - :chat.ui/clear-inputs nil :effects.shell/reset-state nil :hide-popover nil ::logout nil diff --git a/src/legacy/status_im/node/core.cljs b/src/legacy/status_im/node/core.cljs index f497c935670..c5ecd37fd61 100644 --- a/src/legacy/status_im/node/core.cljs +++ b/src/legacy/status_im/node/core.cljs @@ -72,7 +72,7 @@ :PeerExchange true :Port 0 :UDPPort 0 - :LightClient true}) + :LightClient false}) (def login-node-config {:WalletConfig (cond-> {:Enabled true} diff --git a/src/native_module/core.cljs b/src/native_module/core.cljs index dc4cda0f44e..43e18df35a7 100644 --- a/src/native_module/core.cljs +++ b/src/native_module/core.cljs @@ -573,3 +573,13 @@ (defn init-status-go-logging [{:keys [enable? mobile-system? log-level callback]}] (.initLogging ^js (log-manager) enable? mobile-system? log-level callback)) + +(defn get-random-mnemonic + [callback] + (.getRandomMnemonic ^js (account-manager) #(callback (types/json->clj %)))) + +(defn create-account-from-mnemonic + [mnemonic callback] + (.createAccountFromMnemonicAndDeriveAccountsForPaths ^js (account-manager) + (types/clj->json mnemonic) + #(callback (types/json->clj %)))) diff --git a/src/quo/components/avatars/channel_avatar/view.cljs b/src/quo/components/avatars/channel_avatar/view.cljs index 7858bacd2ec..d48c477ecbe 100644 --- a/src/quo/components/avatars/channel_avatar/view.cljs +++ b/src/quo/components/avatars/channel_avatar/view.cljs @@ -12,7 +12,7 @@ (defn- initials [{:keys [full-name size customization-color theme]}] (let [amount-initials (if (#{:size-32 :size-64} size) 2 1) - channel-name (string/replace full-name "#" "")] + channel-name (utils.string/safe-replace full-name "#" "")] [text/text (cond-> {:accessibility-label :initials :style {:color (colors/resolve-color customization-color theme)} diff --git a/src/quo/components/avatars/user_avatar/component_spec.cljs b/src/quo/components/avatars/user_avatar/component_spec.cljs index 1fd149b0bdc..5458be45c27 100644 --- a/src/quo/components/avatars/user_avatar/component_spec.cljs +++ b/src/quo/components/avatars/user_avatar/component_spec.cljs @@ -3,16 +3,16 @@ [quo.components.avatars.user-avatar.view :as user-avatar] [test-helpers.component :as h])) -(defonce mock-picture {:uri (js/require "../resources/images/mock2/user_picture_male4.png")}) +(defonce mock-picture 1) (h/describe "user avatar" (h/describe "Profile picture" (h/test "Renders" - (h/render + (h/render-with-theme-provider [user-avatar/user-avatar {:profile-picture mock-picture}]) (h/is-truthy (h/get-by-label-text :profile-picture))) (h/test "Renders even if `:full-name` is passed" - (h/render + (h/render-with-theme-provider [user-avatar/user-avatar {:profile-picture mock-picture}]) (h/is-truthy (h/get-by-label-text :profile-picture))))) diff --git a/src/quo/components/avatars/user_avatar/schema.cljs b/src/quo/components/avatars/user_avatar/schema.cljs new file mode 100644 index 00000000000..bbfdfde7ed2 --- /dev/null +++ b/src/quo/components/avatars/user_avatar/schema.cljs @@ -0,0 +1,24 @@ +(ns quo.components.avatars.user-avatar.schema + (:require + [quo.components.avatars.user-avatar.style :as style])) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:full-name {:optional true} [:maybe string?]] + [:size {:optional true} [:maybe (into [:enum] (keys style/sizes))]] + [:customization-color {:optional true} [:maybe :schema.common/customization-color]] + [:static? {:optional true} [:maybe boolean?]] + [:status-indicator? {:optional true} [:maybe boolean?]] + [:online? {:optional true} [:maybe boolean?]] + [:ring? {:optional true} [:maybe boolean?]] + [:theme :schema.common/theme] + [:profile-picture + {:optional true} + [:maybe + [:or + :schema.common/image-source + [:map [:fn fn?]]]]]]]] + :any]) diff --git a/src/quo/components/avatars/user_avatar/view.cljs b/src/quo/components/avatars/user_avatar/view.cljs index 621ef9845e0..880357655be 100644 --- a/src/quo/components/avatars/user_avatar/view.cljs +++ b/src/quo/components/avatars/user_avatar/view.cljs @@ -1,11 +1,13 @@ (ns quo.components.avatars.user-avatar.view (:require + [quo.components.avatars.user-avatar.schema :as component-schema] [quo.components.avatars.user-avatar.style :as style] [quo.components.common.no-flicker-image :as no-flicker-image] [quo.components.markdown.text :as text] [quo.theme] [react-native.core :as rn] [react-native.fast-image :as fast-image] + [schema.core :as schema] utils.string)) (defn initials-avatar @@ -58,7 +60,7 @@ customization-color :blue} :as props}] (let [full-name (or full-name "Your Name") - ;; image generated with profile-picture-fn is round cropped + ;; image generated with `profile-picture-fn` is round cropped ;; no need to add border-radius for them outer-styles (style/outer size (not (:fn profile-picture))) ;; Once image is loaded, fast image re-renders view with the help of reagent atom, @@ -108,4 +110,6 @@ :else {:uri profile-picture})}])])) -(def user-avatar (quo.theme/with-theme user-avatar-internal)) +(def user-avatar + (quo.theme/with-theme + (schema/instrument #'user-avatar-internal component-schema/?schema))) diff --git a/src/quo/components/drawers/bottom_actions/view.cljs b/src/quo/components/drawers/bottom_actions/view.cljs index 6d1a3377d70..3361c4e24c2 100644 --- a/src/quo/components/drawers/bottom_actions/view.cljs +++ b/src/quo/components/drawers/bottom_actions/view.cljs @@ -53,7 +53,7 @@ :style {:color (colors/theme-colors colors/danger-50 colors/danger-60 theme)}} error-message]]) - (when (= description :top) + (when (and (= description :top) role) [rn/view {:style style/description-top} [text/text diff --git a/src/quo/components/inputs/profile_input/component_spec.cljs b/src/quo/components/inputs/profile_input/component_spec.cljs index 1411a52e882..9bdfe570830 100644 --- a/src/quo/components/inputs/profile_input/component_spec.cljs +++ b/src/quo/components/inputs/profile_input/component_spec.cljs @@ -6,8 +6,9 @@ (h/describe "Profile Input" (h/test "on press event fires" (let [event (h/mock-fn)] - (h/render [profile-input/profile-input - {:placeholder "Your Name" - :on-press event}]) + (h/render-with-theme-provider + [profile-input/profile-input + {:placeholder "Your Name" + :on-press event}]) (h/fire-event :press (h/get-by-label-text :select-profile-picture-button)) (h/was-called-times event 1)))) diff --git a/src/quo/components/list_items/saved_contact_address/component_spec.cljs b/src/quo/components/list_items/saved_contact_address/component_spec.cljs index 4185a3ff8a8..aeef59d2935 100644 --- a/src/quo/components/list_items/saved_contact_address/component_spec.cljs +++ b/src/quo/components/list_items/saved_contact_address/component_spec.cljs @@ -12,34 +12,34 @@ (h/describe "List items: saved contact address" (h/test "default render" - (h/render [saved-contact-address/view]) + (h/render-with-theme-provider [saved-contact-address/view]) (h/is-truthy (h/query-by-label-text :container))) (h/test "renders account detail when passing one account" - (h/render [saved-contact-address/view {:accounts (repeat 1 account)}]) + (h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}]) (h/is-truthy (h/query-by-label-text :account-container))) (h/test "renders account count when passing multiple accounts" - (h/render [saved-contact-address/view {:accounts (repeat 2 account)}]) + (h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 2 account)}]) (h/is-truthy (h/query-by-label-text :accounts-count))) (h/test "on-press-in changes state to :pressed" - (h/render [saved-contact-address/view {:accounts (repeat 1 account)}]) + (h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}]) (h/fire-event :on-press-in (h/get-by-label-text :container)) (h/wait-for #(h/has-style (h/query-by-label-text :container) {:backgroundColor (colors/custom-color :blue 50 5)}))) (h/test "on-press-out changes state to :active if active-state? is true (default value)" - (h/render [saved-contact-address/view {:accounts (repeat 1 account)}]) + (h/render-with-theme-provider [saved-contact-address/view {:accounts (repeat 1 account)}]) (h/fire-event :on-press-in (h/get-by-label-text :container)) (h/fire-event :on-press-out (h/get-by-label-text :container)) (h/wait-for #(h/has-style (h/query-by-label-text :container) {:backgroundColor (colors/custom-color :blue 50 10)}))) (h/test "on-press-out changes state to :default if active-state? is false" - (h/render [saved-contact-address/view - {:accounts (repeat 1 account) - :active-state? false}]) + (h/render-with-theme-provider [saved-contact-address/view + {:accounts (repeat 1 account) + :active-state? false}]) (h/fire-event :on-press-in (h/get-by-label-text :container)) (h/fire-event :on-press-out (h/get-by-label-text :container)) (h/wait-for #(h/has-style (h/query-by-label-text :container) @@ -47,8 +47,9 @@ (h/test "on-press calls on-press" (let [on-press (h/mock-fn)] - (h/render [saved-contact-address/view - {:on-press on-press - :accounts (repeat 1 account)}]) + (h/render-with-theme-provider + [saved-contact-address/view + {:on-press on-press + :accounts (repeat 1 account)}]) (h/fire-event :on-press (h/get-by-label-text :container)) (h/was-called on-press)))) diff --git a/src/quo/components/markdown/list/component_spec.cljs b/src/quo/components/markdown/list/component_spec.cljs index 10838b31585..51295005b4d 100644 --- a/src/quo/components/markdown/list/component_spec.cljs +++ b/src/quo/components/markdown/list/component_spec.cljs @@ -5,19 +5,19 @@ (h/describe "tests for markdown/list component" (h/test "renders component with title" - (h/render [list/view {:title "test title"}]) + (h/render-with-theme-provider [list/view {:title "test title"}]) (h/is-truthy (h/get-by-text "test title"))) (h/test "renders component with description" - (h/render [list/view - {:title "test title" - :description "test description"}]) + (h/render-with-theme-provider [list/view + {:title "test title" + :description "test description"}]) (h/is-truthy (h/get-by-text "test description"))) (h/test "renders component with title and description" - (h/render [list/view - {:title "test title" - :description "test description"}]) + (h/render-with-theme-provider [list/view + {:title "test title" + :description "test description"}]) (h/is-truthy (h/get-by-text "test title")) (h/is-truthy (h/get-by-text "test description"))) @@ -29,11 +29,11 @@ (h/is-truthy (h/get-by-label-text :step-counter))) (h/test "renders decription with a context tag component and description after the tag" - (h/render [list/view - {:step-number 1 - :description "Lorem ipsum " - :tag-name "dolor" - :description-after-tag "text after tag"}]) + (h/render-with-theme-provider [list/view + {:step-number 1 + :description "Lorem ipsum " + :tag-name "dolor" + :description-after-tag "text after tag"}]) (h/is-truthy (h/get-by-text "Lorem ipsum")) (h/is-truthy (h/get-by-label-text :user-avatar)) (h/is-truthy (h/get-by-text "dolor")) diff --git a/src/quo/components/navigation/bottom_nav_tab/view.cljs b/src/quo/components/navigation/bottom_nav_tab/view.cljs index a7c8065c14a..5b071e1a086 100644 --- a/src/quo/components/navigation/bottom_nav_tab/view.cljs +++ b/src/quo/components/navigation/bottom_nav_tab/view.cljs @@ -32,7 +32,7 @@ " [{:keys [icon new-notifications? notification-indicator counter-label on-press pass-through? icon-color-anim accessibility-label test-ID - customization-color on-long-press] + customization-color] :or {customization-color :blue}}] (let [icon-animated-style (reanimated/apply-animations-to-style {:tint-color icon-color-anim} @@ -48,7 +48,6 @@ :border-radius 10})] [rn/touchable-without-feedback {:test-ID test-ID - :on-long-press on-long-press ;;NOTE - this is temporary while supporting old wallet :allow-multiple-presses? true :on-press on-press :on-press-in #(toggle-background-color background-color false pass-through?) diff --git a/src/quo/components/navigation/top_nav/component_spec.cljs b/src/quo/components/navigation/top_nav/component_spec.cljs index e7204213a8c..db9c6cf137e 100644 --- a/src/quo/components/navigation/top_nav/component_spec.cljs +++ b/src/quo/components/navigation/top_nav/component_spec.cljs @@ -5,7 +5,7 @@ (h/describe "Top Nav component" (h/test "Renders default" - (h/render [top-nav/view]) + (h/render-with-theme-provider [top-nav/view]) (h/is-truthy (h/get-by-label-text :open-scanner-button)) (h/is-truthy (h/get-by-label-text :open-activity-center-button)) (h/is-truthy (h/get-by-label-text :show-qr-button)) @@ -17,11 +17,12 @@ activity-center-on-press (h/mock-fn) qr-code-on-press (h/mock-fn)] - (h/render [top-nav/view - {:avatar-on-press avatar-on-press - :scan-on-press scan-on-press - :activity-center-on-press activity-center-on-press - :qr-code-on-press qr-code-on-press}]) + (h/render-with-theme-provider + [top-nav/view + {:avatar-on-press avatar-on-press + :scan-on-press scan-on-press + :activity-center-on-press activity-center-on-press + :qr-code-on-press qr-code-on-press}]) (h/fire-event :press (h/get-by-label-text :open-scanner-button)) (h/was-called scan-on-press) diff --git a/src/quo/components/profile/select_profile/component_spec.cljs b/src/quo/components/profile/select_profile/component_spec.cljs index 5751a709a26..fe2d8bae57d 100644 --- a/src/quo/components/profile/select_profile/component_spec.cljs +++ b/src/quo/components/profile/select_profile/component_spec.cljs @@ -5,12 +5,12 @@ (h/describe "select-profile component" (h/test "render component" - (h/render [select-profile/view]) + (h/render-with-theme-provider [select-profile/view]) (-> (h/expect (h/get-by-label-text :select-profile)) (.toBeTruthy))) (h/test "call on-change handler when clicked" (let [on-change (h/mock-fn)] - (h/render [select-profile/view {:on-change on-change}]) + (h/render-with-theme-provider [select-profile/view {:on-change on-change}]) (h/fire-event :on-press (h/get-by-label-text :select-profile)) (-> (h/expect on-change) (.toHaveBeenCalledTimes 1))))) diff --git a/src/quo/components/settings/settings_item/component_spec.cljs b/src/quo/components/settings/settings_item/component_spec.cljs index af30d889623..3404d29ea0c 100644 --- a/src/quo/components/settings/settings_item/component_spec.cljs +++ b/src/quo/components/settings/settings_item/component_spec.cljs @@ -12,47 +12,47 @@ (h/describe "Settings list tests" (h/test "Default render of Setting list component" - (h/render [settings-item/view props]) + (h/render-with-theme-provider [settings-item/view props]) (h/is-truthy (h/get-by-label-text :settings-item))) (h/test "It renders a title" - (h/render [settings-item/view props]) + (h/render-with-theme-provider [settings-item/view props]) (h/is-truthy (h/get-by-text "Account"))) (h/test "its gets passed an on press event" (let [event (h/mock-fn)] - (h/render [settings-item/view - (merge props {:on-press event})]) + (h/render-with-theme-provider [settings-item/view + (merge props {:on-press event})]) (h/fire-event :press (h/get-by-text "Account")) (h/was-called event))) (h/test "on change event gets fired for toggle" (let [on-change (h/mock-fn)] - (h/render [settings-item/view - (merge props - {:action :selector - :action-props {:on-change on-change}})]) + (h/render-with-theme-provider [settings-item/view + (merge props + {:action :selector + :action-props {:on-change on-change}})]) (h/fire-event :press (h/get-by-label-text :toggle-off)) (h/was-called on-change))) (h/test "It renders a label" - (h/render [settings-item/view (merge props {:label :color})]) + (h/render-with-theme-provider [settings-item/view (merge props {:label :color})]) (h/is-truthy (h/get-by-label-text :label-component))) (h/test "It renders a status tag component" - (h/render [settings-item/view - (merge props - {:tag :context - :tag-props {:context "Test Tag" - :icon :i/placeholder}})]) + (h/render-with-theme-provider [settings-item/view + (merge props + {:tag :context + :tag-props {:context "Test Tag" + :icon :i/placeholder}})]) (h/is-truthy (h/get-by-text "Test Tag"))) (h/test "on press event gets fired for button" (let [event (h/mock-fn)] - (h/render [settings-item/view - (merge props - {:action :button - :action-props {:button-text "test button" - :on-press event}})]) + (h/render-with-theme-provider [settings-item/view + (merge props + {:action :button + :action-props {:button-text "test button" + :on-press event}})]) (h/fire-event :press (h/get-by-text "test button")) (h/was-called event)))) diff --git a/src/quo/components/switchers/group_messaging_card/component_spec.cljs b/src/quo/components/switchers/group_messaging_card/component_spec.cljs index 64d6050abf2..780b7a0f386 100644 --- a/src/quo/components/switchers/group_messaging_card/component_spec.cljs +++ b/src/quo/components/switchers/group_messaging_card/component_spec.cljs @@ -83,35 +83,35 @@ (h/is-truthy (h/get-by-label-text :gif))) (h/test "Status: Read, Type: Audio, Avatar: true" - (h/render [group-messaging-card/view - {:avatar true - :status :read - :type :audio - :title "Title" - :content {:duration "00:32"}}]) + (h/render-with-theme-provider [group-messaging-card/view + {:avatar true + :status :read + :type :audio + :title "Title" + :content {:duration "00:32"}}]) (h/is-truthy (h/get-by-text (utils/subtitle :audio nil))) (h/is-truthy (h/get-by-text "00:32"))) (h/test "Status: Read, Type: Community, Avatar: true" - (h/render [group-messaging-card/view - {:avatar true - :status :read - :type :community - :title "Title" - :content {:community-avatar coinbase-community - :community-name "Coinbase"}}]) + (h/render-with-theme-provider [group-messaging-card/view + {:avatar true + :status :read + :type :community + :title "Title" + :content {:community-avatar coinbase-community + :community-name "Coinbase"}}]) (h/is-truthy (h/get-by-text (utils/subtitle :community nil))) (h/is-truthy (h/get-by-label-text :group-avatar)) (h/is-truthy (h/get-by-text "Coinbase"))) (h/test "Status: Read, Type: Link, Avatar: true" - (h/render [group-messaging-card/view - {:avatar true - :status :read - :type :link - :title "Title" - :content {:icon :placeholder - :text "Rolling St..."}}]) + (h/render-with-theme-provider [group-messaging-card/view + {:avatar true + :status :read + :type :link + :title "Title" + :content {:icon :placeholder + :text "Rolling St..."}}]) (h/is-truthy (h/get-by-text (utils/subtitle :link nil))) (h/is-truthy (h/get-by-label-text :group-avatar)) (h/is-truthy (h/get-by-text "Rolling St...")))) diff --git a/src/quo/components/tags/context_tag/schema.cljs b/src/quo/components/tags/context_tag/schema.cljs new file mode 100644 index 00000000000..419cc16903c --- /dev/null +++ b/src/quo/components/tags/context_tag/schema.cljs @@ -0,0 +1,103 @@ +(ns quo.components.tags.context-tag.schema + (:require [malli.core :as malli])) + +(def ^:private ?context-base + [:map + [:type {:optional true} + [:maybe + [:enum :default :multiuser :group :channel :community :token :network :multinetwork :account + :collectible :address :icon :audio]]] + [:customization-color {:optional true} [:maybe :schema.common/customization-color]] + [:theme :schema.common/theme] + [:blur? {:optional true} [:maybe :boolean]] + [:state {:optional true} [:maybe [:enum :selected :default]]]]) + +(def ^:private ?size + [:map + [:size {:optional true} [:maybe [:enum 24 32]]]]) + +(def ^:private ?default + [:map + [:profile-picture {:optional true} [:maybe :schema.common/image-source]] + [:full-name {:optional true} [:maybe :string]]]) + +(def ^:private ?multiuser + [:map + [:users {:optional true} + [:maybe + [:sequential + [:map [:profile-picture {:optional true} [:maybe :schema.common/image-source]] + [:full-name {:optional true} [:maybe :string]] + [:customization-color {:optional true} [:maybe :schema.common/customization-color]]]]]]]) + +(def ^:private ?group + [:map + [:group-name {:optional true} [:maybe :string]]]) + +(def ^:private ?channel + [:map + [:community-name {:optional true} [:maybe :string]] + [:channel-name {:optional true} [:maybe :string]]]) + +(def ^:private ?community + [:map + [:community-name {:optional true} [:maybe :string]]]) + +(def ^:private ?token + [:map + [:amount {:optional true} [:maybe [:or :string :int]]] + [:token {:optional true} [:maybe :string]]]) + +(def ^:private ?network + [:map + [:network-logo {:optional true} [:maybe :schema.common/image-source]] + [:network-name {:optional true} [:maybe :string]]]) + +(def ^:private ?multinetwork + [:map + [:networks {:optional true} [:maybe [:sequential ?network]]]]) + +(def ^:private ?account + [:map + [:account-name {:optional true} [:maybe :string]] + [:emoji {:optional true} [:maybe :string]]]) + +(def ^:private ?collectible + [:map + [:collectible {:optional true} [:maybe :schema.common/image-source]] + [:collectible-name {:optional true} [:maybe :string]] + [:collectible-number {:optional true} [:maybe [:or :string :int]]]]) + +(def ^:private ?address + [:map + [:address {:optional true} [:maybe :string]]]) + +(def ^:private ?icon + [:map + [:icon {:optional true} [:maybe :keyword]] + [:context {:optional true} [:maybe :string]]]) + +(def ^:private ?audio + [:map + [:duration {:optional true} [:maybe :string]]]) + +(def ?schema + [:=> + [:catn + [:props + [:multi {:dispatch :type} + [::malli/default [:merge ?default ?size ?context-base]] + [:default [:merge ?default ?size ?context-base]] + [:multiuser [:merge ?multiuser ?context-base]] + [:group [:merge ?group ?size ?context-base]] + [:channel [:merge ?channel ?size ?context-base]] + [:community [:merge ?community ?size ?context-base]] + [:token [:merge ?token ?size ?context-base]] + [:network [:merge ?network ?context-base]] + [:multinetwork [:merge ?multinetwork ?context-base]] + [:account [:merge ?account ?size ?context-base]] + [:collectible [:merge ?collectible ?size ?context-base]] + [:address [:merge ?address ?size ?context-base]] + [:icon [:merge ?icon ?size ?context-base]] + [:audio [:merge ?audio ?context-base]]]]] + :any]) diff --git a/src/quo/components/tags/context_tag/view.cljs b/src/quo/components/tags/context_tag/view.cljs index fa7caa7b45a..56aee95c556 100644 --- a/src/quo/components/tags/context_tag/view.cljs +++ b/src/quo/components/tags/context_tag/view.cljs @@ -6,11 +6,13 @@ [quo.components.icon :as icons] [quo.components.list-items.preview-list.view :as preview-list] [quo.components.markdown.text :as text] + [quo.components.tags.context-tag.schema :as component-schema] [quo.components.tags.context-tag.style :as style] [quo.components.utilities.token.view :as token] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] - [react-native.core :as rn])) + [react-native.core :as rn] + [schema.core :as schema])) (defn- tag-skeleton [{:keys [theme size text] :or {size 24}} logo-component] @@ -157,67 +159,5 @@ nil)]) (def view - "Properties: - type, state, blur? & customization-color - - Depending on the `type` selected, different properties are accepted: - - `:default` or `nil`: - - size - - profile-picture - - full-name - - - `:multiuser`: - - users (vector of {:profile-picture pic, :full-name \"a name\"}) - - - `:group` - - size - - group-name - - - `:community` - - size - - community-logo (valid rn/image :source value) - - community-name - - - `:channel` - - size - - community-logo (valid rn/image :source value) - - community-name - - channel-name - - - `:token` - - size - - amount - - token - - - `:network` - - size - - network-logo (valid rn/image :source value) - - network-name - - - `:multinetworks` - - networks (vector of {:network-logo pic, :network-name \"a name\"}) - - - `:account` - - size - - account-name - - emoji (string containing an emoji) - - - `:collectible` - - size - - collectible (valid rn/image :source value) - - collectible-name - - collectible-number - - - `:address` - - size - - address (string) - - - `:icon` - - size - - icon - - context (string) - - - `:audio` - - duration (string) - " - (quo.theme/with-theme view-internal)) + (quo.theme/with-theme + (schema/instrument #'view-internal component-schema/?schema))) diff --git a/src/quo/components/tags/summary_tag/component_spec.cljs b/src/quo/components/tags/summary_tag/component_spec.cljs index e3217dda640..13795e34a0c 100644 --- a/src/quo/components/tags/summary_tag/component_spec.cljs +++ b/src/quo/components/tags/summary_tag/component_spec.cljs @@ -38,11 +38,12 @@ (h/is-truthy (h/get-by-text "Rare Artifact"))) (h/test "User view render" - (h/render [summary-tag/view - {:type :user - :label "Bob Smith" - :image-source "path/to/profile-pic.png" - :customization-color "#0000ff"}]) + (h/render-with-theme-provider + [summary-tag/view + {:type :user + :label "Bob Smith" + :image-source "path/to/profile-pic.png" + :customization-color "#0000ff"}]) (h/is-truthy (h/get-by-text "Bob Smith"))) (h/test "Token view render" diff --git a/src/quo/components/tags/tag.cljs b/src/quo/components/tags/tag.cljs index cf5fcfa4733..4bca27bd28b 100644 --- a/src/quo/components/tags/tag.cljs +++ b/src/quo/components/tags/tag.cljs @@ -27,6 +27,19 @@ :blurred-border-color colors/white-opa-10 :text-color {:style {:color colors/white}}}}}) +(defn- emoji-comp + [size resource] + (let [dimension (case size + 32 20 + 24 12 + nil)] + (if (string? resource) + [rn/text {:style {:margin-right 4 :font-size dimension}} + resource] + [rn/image + {:source resource + :style {:margin-right 4 :width dimension :height dimension}}]))) + (defn tag-resources [size type resource icon-color label text-color labelled?] [rn/view @@ -47,13 +60,7 @@ 24 12) :color icon-color}]) (when (= type :emoji) - [text/text - {:style {:margin-right 4} - :size (case size - 32 :paragraph-1 - 24 :paragraph-2 - nil)} - resource]) + [emoji-comp size resource]) (when labelled? [text/text (merge {:size (case size @@ -73,7 +80,7 @@ :size 32/24 :on-press fn :blurred? true/false - :resource icon/image + :resource icon/image/text(emojis) :labelled? true/false :disabled? true/false} @@ -107,4 +114,3 @@ [tag-resources size type resource icon-color label text-color labelled?]]])) (def tag (quo.theme/with-theme tag-internal)) - diff --git a/src/quo/components/text_combinations/page_top/component_spec.cljs b/src/quo/components/text_combinations/page_top/component_spec.cljs index 54cf422fa26..da6d7c3152e 100644 --- a/src/quo/components/text_combinations/page_top/component_spec.cljs +++ b/src/quo/components/text_combinations/page_top/component_spec.cljs @@ -37,26 +37,26 @@ (h/is-truthy (h/get-by-text "This is a textual description"))) (h/test "Context tag" - (h/render [page-top/view - {:title "Title" - :description :context-tag - :context-tag context-tag-data}]) + (h/render-with-theme-provider [page-top/view + {:title "Title" + :description :context-tag + :context-tag context-tag-data}]) (h/is-truthy (h/get-by-text "Title")) (h/is-truthy (h/get-by-label-text :context-tag))) (h/test "Summary" - (h/render [page-top/view - {:title "Title" - :description :summary - :summary {:row-1 {:text-1 "Send" - :text-2 "from" - :context-tag-1 context-tag-data - :context-tag-2 context-tag-data} - :row-2 {:text-1 "to" - :text-2 "via" - :context-tag-1 context-tag-data - :context-tag-2 context-tag-data}}}]) + (h/render-with-theme-provider [page-top/view + {:title "Title" + :description :summary + :summary {:row-1 {:text-1 "Send" + :text-2 "from" + :context-tag-1 context-tag-data + :context-tag-2 context-tag-data} + :row-2 {:text-1 "to" + :text-2 "via" + :context-tag-1 context-tag-data + :context-tag-2 context-tag-data}}}]) (h/is-truthy (h/get-by-text "Title")) (h/is-truthy (h/get-by-text "Send")) diff --git a/src/quo/components/text_combinations/page_top/style.cljs b/src/quo/components/text_combinations/page_top/style.cljs index 1c2134cb19f..77c288c4784 100644 --- a/src/quo/components/text_combinations/page_top/style.cljs +++ b/src/quo/components/text_combinations/page_top/style.cljs @@ -12,7 +12,8 @@ :height 32}) (def header-title - {:flex-direction :row + {:flex 1 + :flex-direction :row :column-gap 8}) (def header-counter diff --git a/src/quo/components/text_combinations/page_top/view.cljs b/src/quo/components/text_combinations/page_top/view.cljs index 43195b6ecc6..c4d0fdaddb0 100644 --- a/src/quo/components/text_combinations/page_top/view.cljs +++ b/src/quo/components/text_combinations/page_top/view.cljs @@ -8,6 +8,7 @@ [quo.components.markdown.text :as text] [quo.components.tags.context-tag.view :as context-tag] [quo.components.text-combinations.page-top.style :as style] + [quo.components.text-combinations.standard-title.view :as standard-title] [quo.theme] [react-native.core :as rn] [react-native.fast-image :as fast-image] @@ -32,18 +33,20 @@ (format-counter counter-bottom))]]) (defn- header - [{:keys [title input counter-top counter-bottom] + [{:keys [title title-accessibility-label input counter-top counter-bottom + title-right title-right-props] avatar-props :avatar}] - [rn/view {:style style/header} - [rn/view {:style style/header-title} - (when avatar-props - [channel-avatar/view (assoc avatar-props :size :size-32)]) - [text/text - {:weight :semi-bold - :size :heading-1} - title]] - (when (= input :recovery-phrase) - [header-counter counter-top counter-bottom])]) + (let [title-props (assoc title-right-props + :title title + :right title-right + :accessibility-label title-accessibility-label)] + [rn/view {:style style/header} + [rn/view {:style style/header-title} + (when avatar-props + [channel-avatar/view (assoc avatar-props :size :size-32)]) + [standard-title/view title-props]] + (when (= input :recovery-phrase) + [header-counter counter-top counter-bottom])])) (defn- summary-description [{:keys [row-1 row-2] :as _summary-props} blur?] @@ -112,10 +115,10 @@ emojis)) (defn- view-internal - [{:keys [theme description input blur? input-props] + [{:keys [theme description input blur? input-props container-style] emojis :emoji-dash :as props}] - [rn/view + [rn/view {:style container-style} [rn/view {:style style/top-container} [header props] (when description diff --git a/src/quo/components/text_combinations/standard_title/style.cljs b/src/quo/components/text_combinations/standard_title/style.cljs index 18672e5af78..6b01a2b668f 100644 --- a/src/quo/components/text_combinations/standard_title/style.cljs +++ b/src/quo/components/text_combinations/standard_title/style.cljs @@ -2,7 +2,8 @@ (:require [quo.foundations.colors :as colors])) (def container - {:flex-direction :row + {:flex 1 + :flex-direction :row :justify-content :space-between}) (def right-container {:margin-left 20}) diff --git a/src/quo/components/text_combinations/standard_title/view.cljs b/src/quo/components/text_combinations/standard_title/view.cljs index 9633f9fc971..65312a81201 100644 --- a/src/quo/components/text_combinations/standard_title/view.cljs +++ b/src/quo/components/text_combinations/standard_title/view.cljs @@ -53,9 +53,12 @@ :icon-color (style/right-tag-icon-color blur? theme)}])) (defn- view-internal - [{:keys [title right] :as props}] + [{:keys [title right accessibility-label] :as props}] [rn/view {:style style/container} - [text/text {:size :heading-1 :weight :semi-bold} + [text/text + {:size :heading-1 + :weight :semi-bold + :accessibility-label accessibility-label} title] (when right [rn/view {:style style/right-container} diff --git a/src/quo/components/text_combinations/view.cljs b/src/quo/components/text_combinations/view.cljs index 0b3061efb82..6fa6dbc846d 100644 --- a/src/quo/components/text_combinations/view.cljs +++ b/src/quo/components/text_combinations/view.cljs @@ -21,6 +21,7 @@ (defn view-internal [{:keys [container-style title + title-number-of-lines avatar title-accessibility-label description @@ -28,7 +29,8 @@ button-icon button-on-press customization-color - emoji-hash]}] + emoji-hash] + :or {title-number-of-lines 1}}] [rn/view {:style container-style} [rn/view {:style {:flex-direction :row @@ -41,7 +43,7 @@ {:accessibility-label title-accessibility-label :weight :semi-bold :ellipsize-mode :tail - :number-of-lines 1 + :number-of-lines title-number-of-lines :size :heading-1} title]] (when button-icon diff --git a/src/quo/components/utilities/token/view.cljs b/src/quo/components/utilities/token/view.cljs index d4604882254..141294a621a 100644 --- a/src/quo/components/utilities/token/view.cljs +++ b/src/quo/components/utilities/token/view.cljs @@ -15,7 +15,7 @@ [:token {:optional true} [:maybe [:or keyword? string?]]] [:style {:optional true} map?] ;; Ignores `token` and uses this as parameter to `rn/image`'s source. - [:image-source {:optional true} [:maybe [:or :schema.common/image-source :string]]]]] + [:image-source {:optional true} [:maybe :schema.common/image-source]]]] :any]) (defn- size->number diff --git a/src/quo/components/wallet/account_card/properties.cljs b/src/quo/components/wallet/account_card/properties.cljs index 31f5d7f522d..d51711e5b51 100644 --- a/src/quo/components/wallet/account_card/properties.cljs +++ b/src/quo/components/wallet/account_card/properties.cljs @@ -3,17 +3,11 @@ (defn gradient-start-color [theme customization-color] - (colors/theme-colors - (colors/resolve-color customization-color theme 0) - colors/neutral-95 - theme)) + (colors/resolve-color customization-color theme 0)) (defn gradient-end-color [theme customization-color] - (colors/theme-colors - (colors/resolve-color customization-color theme 6) - colors/neutral-95 - theme)) + (colors/resolve-color customization-color theme 6)) (defn alert-icon-color [theme] diff --git a/src/quo/components/wallet/account_origin/schema.cljs b/src/quo/components/wallet/account_origin/schema.cljs index 9fd3bfa1716..da3d9765a2b 100644 --- a/src/quo/components/wallet/account_origin/schema.cljs +++ b/src/quo/components/wallet/account_origin/schema.cljs @@ -9,7 +9,7 @@ (def ^:private ?default-keypair [:map [:user-name {:optional true} [:maybe :string]] - [:profile-picture {:optional true} [:maybe [:or :schema.common/image-source :string]]] + [:profile-picture {:optional true} [:maybe :schema.common/image-source]] [:derivation-path {:optional true} [:maybe :string]] [:on-press {:optional true} [:maybe fn?]] [:customization-color {:optional true} [:maybe :schema.common/customization-color]]]) diff --git a/src/quo/components/wallet/account_permissions/schema.cljs b/src/quo/components/wallet/account_permissions/schema.cljs index a0dd1d95b86..8893b6b52a2 100644 --- a/src/quo/components/wallet/account_permissions/schema.cljs +++ b/src/quo/components/wallet/account_permissions/schema.cljs @@ -1,5 +1,5 @@ (ns quo.components.wallet.account-permissions.schema - (:require [quo.components.wallet.required-tokens.view :as required-tokens])) + (:require [quo.components.wallet.required-tokens.schema :as required-tokens-schema])) (def ?schema [:=> @@ -12,7 +12,7 @@ [:address [:maybe :string]] [:emoji [:maybe :string]] [:customization-color {:optional true} [:maybe :schema.common/customization-color]]]] - [:token-details {:optional true} [:maybe [:sequential required-tokens/?schema]]] + [:token-details {:optional true} [:maybe [:sequential required-tokens-schema/?schema]]] [:keycard? {:optional true} [:maybe :boolean]] [:checked? {:optional true} [:maybe :boolean]] [:disabled? {:optional true} [:maybe :boolean]] diff --git a/src/quo/components/wallet/network_amount/schema.cljs b/src/quo/components/wallet/network_amount/schema.cljs new file mode 100644 index 00000000000..a7baa54e5f7 --- /dev/null +++ b/src/quo/components/wallet/network_amount/schema.cljs @@ -0,0 +1,11 @@ +(ns quo.components.wallet.network-amount.schema) + +(def ?schema + [:=> + [:catn + [:props + [:map {:closed true} + [:amount {:optional true} [:maybe :string]] + [:token {:optional true} [:or :keyword :string]] + [:theme :schema.common/theme]]]] + :any]) diff --git a/src/quo/components/wallet/network_amount/view.cljs b/src/quo/components/wallet/network_amount/view.cljs index bd6cccc802b..2e92a8c6de2 100644 --- a/src/quo/components/wallet/network_amount/view.cljs +++ b/src/quo/components/wallet/network_amount/view.cljs @@ -3,21 +3,12 @@ [clojure.string :as string] [quo.components.markdown.text :as text] [quo.components.utilities.token.view :as token] + [quo.components.wallet.network-amount.schema :as network-amount-schema] [quo.components.wallet.network-amount.style :as style] [quo.theme :as quo.theme] [react-native.core :as rn] [schema.core :as schema])) -(def ?schema - [:=> - [:catn - [:props - [:map {:closed true} - [:amount {:optional true} [:maybe :string]] - [:token {:optional true} [:or :keyword :string]] - [:theme :schema.common/theme]]]] - :any]) - (defn- view-internal [{:keys [amount token theme]}] [rn/view {:style style/container} @@ -30,4 +21,4 @@ [rn/view {:style (style/divider theme)}]]) -(def view (quo.theme/with-theme (schema/instrument #'view-internal ?schema))) +(def view (quo.theme/with-theme (schema/instrument #'view-internal network-amount-schema/?schema))) diff --git a/src/quo/components/wallet/network_bridge/schema.cljs b/src/quo/components/wallet/network_bridge/schema.cljs new file mode 100644 index 00000000000..c070baabb2d --- /dev/null +++ b/src/quo/components/wallet/network_bridge/schema.cljs @@ -0,0 +1,17 @@ +(ns quo.components.wallet.network-bridge.schema) + +(def ^:private ?network-bridge-status + [:enum :add :loading :locked :disabled :default]) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:theme :schema.common/theme] + [:network {:optional true} [:maybe :keyword]] + [:status {:optional true} [:maybe ?network-bridge-status]] + [:amount {:optional true} [:maybe :string]] + [:container-style {:optional true} [:maybe :map]] + [:on-press {:optional true} [:maybe fn?]]]]] + :any]) diff --git a/src/quo/components/wallet/network_bridge/view.cljs b/src/quo/components/wallet/network_bridge/view.cljs index e8c934515a5..c033ee953a7 100644 --- a/src/quo/components/wallet/network_bridge/view.cljs +++ b/src/quo/components/wallet/network_bridge/view.cljs @@ -3,6 +3,7 @@ [clojure.string :as string] [quo.components.icon :as icon] [quo.components.markdown.text :as text] + [quo.components.wallet.network-bridge.schema :as network-bridge-schema] [quo.components.wallet.network-bridge.style :as style] [quo.foundations.colors :as colors] [quo.foundations.resources :as resources] @@ -25,22 +26,6 @@ (= network :ethereum) "Mainnet" :else (string/capitalize (name network)))) -(def ^:private ?network-bridge-status - [:enum :add :loading :locked :disabled :default]) - -(def ?schema - [:=> - [:catn - [:props - [:map - [:theme :schema.common/theme] - [:network {:optional true} [:maybe :keyword]] - [:status {:optional true} [:maybe ?network-bridge-status]] - [:amount {:optional true} [:maybe :string]] - [:container-style {:optional true} [:maybe :map]] - [:on-press {:optional true} [:maybe fn?]]]]] - :any]) - (defn view-internal [{:keys [theme network status amount container-style on-press] :as args}] (if (= status :add) @@ -81,4 +66,4 @@ (def view (quo.theme/with-theme - (schema/instrument #'view-internal ?schema))) + (schema/instrument #'view-internal network-bridge-schema/?schema))) diff --git a/src/quo/components/wallet/network_link/schema.cljs b/src/quo/components/wallet/network_link/schema.cljs new file mode 100644 index 00000000000..c0b89e23519 --- /dev/null +++ b/src/quo/components/wallet/network_link/schema.cljs @@ -0,0 +1,14 @@ +(ns quo.components.wallet.network-link.schema) + +(def ^:private ?networks [:enum :optimism :arbitrum :ethereum]) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:shape {:optional true} [:maybe [:enum :linear :1x :2x]]] + [:source {:optional true} [:maybe ?networks]] + [:destination {:optional true} [:maybe ?networks]] + [:theme :schema.common/theme]]]] + :any]) diff --git a/src/quo/components/wallet/network_link/view.cljs b/src/quo/components/wallet/network_link/view.cljs index b25d0e5e3e5..9fe4949267d 100644 --- a/src/quo/components/wallet/network_link/view.cljs +++ b/src/quo/components/wallet/network_link/view.cljs @@ -1,9 +1,11 @@ (ns quo.components.wallet.network-link.view (:require + [quo.components.wallet.network-link.schema :as component-schema] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] [react-native.core :as rn] - [react-native.svg :as svg])) + [react-native.svg :as svg] + [schema.core :as schema])) (defn link-linear [{:keys [source theme]}] @@ -84,4 +86,6 @@ :1x [link-1x props] :2x [link-2x props])]) -(def view (quo.theme/with-theme view-internal)) +(def view + (quo.theme/with-theme + (schema/instrument #'view-internal component-schema/?schema))) diff --git a/src/quo/components/wallet/network_routing/schema.cljs b/src/quo/components/wallet/network_routing/schema.cljs new file mode 100644 index 00000000000..fec6a7a3d9d --- /dev/null +++ b/src/quo/components/wallet/network_routing/schema.cljs @@ -0,0 +1,17 @@ +(ns quo.components.wallet.network-routing.schema) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:networks {:optional true} + [:maybe + [:sequential + [:map + [:amount :int] + [:max-amount :int] + [:network-name [:or :string :keyword]]]]]] + [:container-style {:optional true} [:maybe :map]] + [:theme :schema.common/theme]]]] + :any]) diff --git a/src/quo/components/wallet/network_routing/view.cljs b/src/quo/components/wallet/network_routing/view.cljs index 001e7de64f3..a9d1d085289 100644 --- a/src/quo/components/wallet/network_routing/view.cljs +++ b/src/quo/components/wallet/network_routing/view.cljs @@ -2,6 +2,7 @@ (:require [oops.core :as oops] [quo.components.wallet.network-routing.animation :as animation] + [quo.components.wallet.network-routing.schema :as network-routing-schema] [quo.components.wallet.network-routing.style :as style] [quo.theme :as quo.theme] [react-native.core :as rn] @@ -173,22 +174,6 @@ [rn/view {:style (style/max-limit-bar-background network-name)}] [dashed-line network-name]])])))) -(def ?schema - [:=> - [:catn - [:props - [:map - [:networks {:optional true} - [:maybe - [:sequential - [:map - [:amount :int] - [:max-amount :int] - [:network-name [:or :string :keyword]]]]]] - [:container-style {:optional true} [:maybe :map]] - [:theme :schema.common/theme]]]] - :any]) - (defn view-internal [{:keys [networks container-style theme] :as params}] (reagent/with-let [total-width (reagent/atom nil)] @@ -205,4 +190,4 @@ (def view (quo.theme/with-theme - (schema/instrument #'view-internal ?schema))) + (schema/instrument #'view-internal network-routing-schema/?schema))) diff --git a/src/quo/components/wallet/progress_bar/schema.cljs b/src/quo/components/wallet/progress_bar/schema.cljs new file mode 100644 index 00000000000..6ef509a6acf --- /dev/null +++ b/src/quo/components/wallet/progress_bar/schema.cljs @@ -0,0 +1,12 @@ +(ns quo.components.wallet.progress-bar.schema) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:customization-color {:optional true} [:maybe :schema.common/customization-color]] + [:theme :schema.common/theme] + [:progressed-value {:optional true} [:maybe [:or :string :int]]] + [:full-width? {:optional true} [:maybe :boolean]]]]] + :any]) diff --git a/src/quo/components/wallet/progress_bar/view.cljs b/src/quo/components/wallet/progress_bar/view.cljs index 9c5f1ed734d..f7c7e9e8f79 100644 --- a/src/quo/components/wallet/progress_bar/view.cljs +++ b/src/quo/components/wallet/progress_bar/view.cljs @@ -1,21 +1,11 @@ (ns quo.components.wallet.progress-bar.view (:require + [quo.components.wallet.progress-bar.schema :as progress-bar-schema] [quo.components.wallet.progress-bar.style :as style] [quo.theme :as quo.theme] [react-native.core :as rn] [schema.core :as schema])) -(def ?schema - [:=> - [:catn - [:props - [:map - [:customization-color {:optional true} [:maybe :schema.common/customization-color]] - [:theme :schema.common/theme] - [:progressed-value {:optional true} [:maybe [:or :string :int]]] - [:full-width? {:optional true} [:maybe :boolean]]]]] - :any]) - (defn- view-internal [{:keys [full-width?] :as props}] [rn/view @@ -26,4 +16,4 @@ (def view (quo.theme/with-theme - (schema/instrument #'view-internal ?schema))) + (schema/instrument #'view-internal progress-bar-schema/?schema))) diff --git a/src/quo/components/wallet/required_tokens/schema.cljs b/src/quo/components/wallet/required_tokens/schema.cljs new file mode 100644 index 00000000000..8bf19f6864e --- /dev/null +++ b/src/quo/components/wallet/required_tokens/schema.cljs @@ -0,0 +1,17 @@ +(ns quo.components.wallet.required-tokens.schema) + +(def ?schema + [:=> + [:catn + [:props + [:map {:closed true} + [:type [:enum :token :collectible]] + [:amount {:optional true} [:maybe [:or :string :int]]] + [:token {:optional true} [:maybe :string]] + [:token-img-src {:optional true} [:maybe :schema.common/image-source]] + [:collectible-img-src {:optional true} [:maybe :schema.common/image-source]] + [:collectible-name {:optional true} [:maybe :string]] + [:divider? {:optional true} [:maybe :boolean]] + [:theme :schema.common/theme] + [:container-style {:optional true} [:maybe :map]]]]] + :any]) diff --git a/src/quo/components/wallet/required_tokens/view.cljs b/src/quo/components/wallet/required_tokens/view.cljs index d3a7754e281..e8bfb2c181c 100644 --- a/src/quo/components/wallet/required_tokens/view.cljs +++ b/src/quo/components/wallet/required_tokens/view.cljs @@ -1,27 +1,12 @@ (ns quo.components.wallet.required-tokens.view (:require [quo.components.markdown.text :as text] [quo.components.utilities.token.view :as token] + [quo.components.wallet.required-tokens.schema :as required-tokens-schema] [quo.components.wallet.required-tokens.style :as style] quo.theme [react-native.core :as rn] [schema.core :as schema])) -(def ?schema - [:=> - [:catn - [:props - [:map {:closed true} - [:type [:enum :token :collectible]] - [:amount {:optional true} [:maybe [:or :string :int]]] - [:token {:optional true} [:maybe :string]] - [:token-img-src {:optional true} [:maybe :schema.common/image-source]] - [:collectible-img-src {:optional true} [:maybe :schema.common/image-source]] - [:collectible-name {:optional true} [:maybe :string]] - [:divider? {:optional true} [:maybe :boolean]] - [:theme :schema.common/theme] - [:container-style {:optional true} [:maybe :map]]]]] - :any]) - (defn- view-internal [{:keys [type amount token token-img-src collectible-img-src collectible-name divider? theme container-style]}] @@ -53,4 +38,4 @@ (def view (quo.theme/with-theme - (schema/instrument #'view-internal ?schema))) + (schema/instrument #'view-internal required-tokens-schema/?schema))) diff --git a/src/quo/components/wallet/summary_info/schema.cljs b/src/quo/components/wallet/summary_info/schema.cljs new file mode 100644 index 00000000000..3d604830b52 --- /dev/null +++ b/src/quo/components/wallet/summary_info/schema.cljs @@ -0,0 +1,13 @@ +(ns quo.components.wallet.summary-info.schema) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:theme :schema.common/theme] + [:type [:enum :status-account :saved-account :account :user]] + [:account-props {:optional true} [:maybe :map]] + [:networks? {:optional true} [:maybe :boolean]] + [:values {:optional true} [:maybe :map]]]]] + :any]) diff --git a/src/quo/components/wallet/summary_info/view.cljs b/src/quo/components/wallet/summary_info/view.cljs index 697b99718db..375321770db 100644 --- a/src/quo/components/wallet/summary_info/view.cljs +++ b/src/quo/components/wallet/summary_info/view.cljs @@ -4,6 +4,7 @@ [quo.components.avatars.user-avatar.view :as user-avatar] [quo.components.avatars.wallet-user-avatar.view :as wallet-user-avatar] [quo.components.markdown.text :as text] + [quo.components.wallet.summary-info.schema :as summary-info-schema] [quo.components.wallet.summary-info.style :as style] [quo.foundations.colors :as colors] [quo.foundations.resources :as resources] @@ -52,18 +53,6 @@ :amount (str (:amount arbitrum) " " (or (:token-symbol arbitrum) "ARB")) :theme theme}])])) -(def ?schema - [:=> - [:catn - [:props - [:map - [:theme :schema.common/theme] - [:type [:enum :status-account :saved-account :account :user]] - [:account-props {:optional true} [:maybe :map]] - [:networks? {:optional true} [:maybe :boolean]] - [:values {:optional true} [:maybe :map]]]]] - :any]) - (defn- view-internal [{:keys [theme type account-props networks? values]}] [rn/view @@ -106,4 +95,4 @@ (def view (quo.theme/with-theme - (schema/instrument #'view-internal ?schema))) + (schema/instrument #'view-internal summary-info-schema/?schema))) diff --git a/src/quo/components/wallet/token_input/component_spec.cljs b/src/quo/components/wallet/token_input/component_spec.cljs index 6e76ce46c2d..8f702fe71a4 100644 --- a/src/quo/components/wallet/token_input/component_spec.cljs +++ b/src/quo/components/wallet/token_input/component_spec.cljs @@ -5,15 +5,15 @@ (h/describe "Wallet: Token Input" (h/test "Token label renders" - (h/render [token-input/view - {:token :snt - :currency :eur - :conversion 1}]) + (h/render-with-theme-provider [token-input/view + {:token :snt + :currency :eur + :conversion 1}]) (h/is-truthy (h/get-by-text "SNT"))) (h/test "Amount renders" - (h/render [token-input/view - {:token :snt - :currency :eur - :conversion 1}]) + (h/render-with-theme-provider [token-input/view + {:token :snt + :currency :eur + :conversion 1}]) (h/is-truthy (h/get-by-text "€0.00")))) diff --git a/src/quo/components/wallet/token_input/schema.cljs b/src/quo/components/wallet/token_input/schema.cljs new file mode 100644 index 00000000000..e33762864a2 --- /dev/null +++ b/src/quo/components/wallet/token_input/schema.cljs @@ -0,0 +1,19 @@ +(ns quo.components.wallet.token-input.schema) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:token {:optional true} [:maybe :keyword]] + [:currency {:optional true} [:maybe :keyword]] + [:error? {:optional true} [:maybe :boolean]] + [:title {:optional true} [:maybe :string]] + [:conversion {:optional true} [:maybe :double]] + [:show-keyboard? {:optional true} [:maybe :boolean]] + [:networks {:optional true} + [:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]] + [:customization-color {:optional true} [:maybe :schema.common/customization-color]] + [:value {:optional true} [:maybe :string]] + [:theme :schema.common/theme]]]] + :any]) diff --git a/src/quo/components/wallet/token_input/view.cljs b/src/quo/components/wallet/token_input/view.cljs index 5a6bbedd66b..c330ee537c8 100644 --- a/src/quo/components/wallet/token_input/view.cljs +++ b/src/quo/components/wallet/token_input/view.cljs @@ -7,11 +7,13 @@ [quo.components.markdown.text :as text] [quo.components.tags.network-tags.view :as network-tag] [quo.components.utilities.token.view :as token] + [quo.components.wallet.token-input.schema :as component-schema] [quo.components.wallet.token-input.style :as style] [quo.foundations.common :as common] [quo.theme :as quo.theme] [react-native.core :as rn] - [reagent.core :as reagent])) + [reagent.core :as reagent] + [schema.core :as schema])) (defn fiat-format [currency num-value conversion] @@ -149,4 +151,6 @@ :crypto? @crypto? :amount (or value @value-atom))]])))) -(def view (quo.theme/with-theme view-internal)) +(def view + (quo.theme/with-theme + (schema/instrument #'view-internal component-schema/?schema))) diff --git a/src/quo/components/wallet/transaction_progress/schema.cljs b/src/quo/components/wallet/transaction_progress/schema.cljs new file mode 100644 index 00000000000..2c2cb4840b8 --- /dev/null +++ b/src/quo/components/wallet/transaction_progress/schema.cljs @@ -0,0 +1,25 @@ +(ns quo.components.wallet.transaction-progress.schema) + +(def ^:private ?network + [:map + [:network {:optional true} [:maybe [:enum :mainnet :optimism :arbitrum]]] + [:state {:optional true} [:maybe [:enum :pending :sending :confirmed :finalising :finalized :error]]] + [:counter {:optional true} [:maybe :int]] + [:total-box {:optional true} [:maybe :int]] + [:epoch-number {:optional true} [:maybe :string]] + [:progress {:optional true} [:maybe :int]]]) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:theme :schema.common/theme] + [:customization-color {:optional true} [:maybe :schema.common/customization-color]] + [:title {:optional true} [:maybe :string]] + [:tag-name {:optional true} [:maybe :string]] + [:tag-number {:optional true} [:maybe [:or :string :int]]] + [:tag-photo {:optional true} [:maybe :schema.common/image-source]] + [:on-press {:optional true} [:maybe fn?]] + [:networks {:optional true} [:maybe [:sequential ?network]]]]]] + :any]) diff --git a/src/quo/components/wallet/transaction_progress/view.cljs b/src/quo/components/wallet/transaction_progress/view.cljs index 147495384d4..7ddda95d6e9 100644 --- a/src/quo/components/wallet/transaction_progress/view.cljs +++ b/src/quo/components/wallet/transaction_progress/view.cljs @@ -4,10 +4,12 @@ [quo.components.markdown.text :as text] [quo.components.tags.context-tag.view :as context-tag] [quo.components.wallet.confirmation-progress.view :as confirmation-progress] + [quo.components.wallet.transaction-progress.schema :as component-schema] [quo.components.wallet.transaction-progress.style :as style] [quo.foundations.colors :as colors] [quo.theme :as quo.theme] [react-native.core :as rn] + [schema.core :as schema] [utils.i18n :as i18n])) (def ^:private max-mainnet-verifications 4) @@ -184,4 +186,6 @@ ^{:key (:network network)} [view-network (assoc-props (:network network))]))]]) -(def view (quo.theme/with-theme view-internal)) +(def view + (quo.theme/with-theme + (schema/instrument #'view-internal component-schema/?schema))) diff --git a/src/quo/components/wallet/transaction_summary/component_spec.cljs b/src/quo/components/wallet/transaction_summary/component_spec.cljs index 30a6585e7f6..25507435720 100644 --- a/src/quo/components/wallet/transaction_summary/component_spec.cljs +++ b/src/quo/components/wallet/transaction_summary/component_spec.cljs @@ -5,24 +5,20 @@ (h/describe "Transaction summary" (h/test "default render" - (h/render [transaction-summary/view {}]) - (h/is-truthy (h/query-by-label-text :transaction-summary))) - - (h/test "incorrect setting doesn't crash render" - (h/render [transaction-summary/view {:transaction :unknown}]) + (h/render-with-theme-provider [transaction-summary/view {}]) (h/is-truthy (h/query-by-label-text :transaction-summary))) (h/test "icon displayed" - (h/render [transaction-summary/view {:transaction :send}]) + (h/render-with-theme-provider [transaction-summary/view {:transaction :send}]) (h/is-truthy (h/query-by-label-text :header-icon))) (h/test "Context tag rendered" - (h/render [transaction-summary/view - {:transaction :send - :first-tag {:size 24 - :type :token - :token "SNT" - :amount 1500}}]) + (h/render-with-theme-provider [transaction-summary/view + {:transaction :send + :first-tag {:size 24 + :type :token + :token "SNT" + :amount 1500}}]) (h/is-truthy (h/query-by-label-text :context-tag)))) diff --git a/src/quo/components/wallet/transaction_summary/schema.cljs b/src/quo/components/wallet/transaction_summary/schema.cljs new file mode 100644 index 00000000000..908abb6477a --- /dev/null +++ b/src/quo/components/wallet/transaction_summary/schema.cljs @@ -0,0 +1,23 @@ +(ns quo.components.wallet.transaction-summary.schema + (:require [quo.components.tags.context-tag.schema :as context-tag-schema])) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:theme :schema.common/theme] + [:transaction {:optional true} [:maybe [:enum :send :swap :bridge]]] + [:first-tag {:optional true} [:maybe context-tag-schema/?schema]] + [:second-tag {:optional true} [:maybe context-tag-schema/?schema]] + [:third-tag {:optional true} [:maybe context-tag-schema/?schema]] + [:fourth-tag {:optional true} [:maybe context-tag-schema/?schema]] + [:fifth-tag {:optional true} [:maybe context-tag-schema/?schema]] + [:second-tag-prefix {:optional true} [:maybe :keyword]] + [:third-tag-prefix {:optional true} [:maybe :keyword]] + [:fourth-tag-prefix {:optional true} [:maybe :keyword]] + [:max-fees {:optional true} [:maybe :string]] + [:nonce {:optional true} [:maybe :int]] + [:input-data {:optional true} [:maybe :string]] + [:on-press {:optional true} [:maybe fn?]]]]] + :any]) diff --git a/src/quo/components/wallet/transaction_summary/view.cljs b/src/quo/components/wallet/transaction_summary/view.cljs index 6f4387dbf86..eb253e692ad 100644 --- a/src/quo/components/wallet/transaction_summary/view.cljs +++ b/src/quo/components/wallet/transaction_summary/view.cljs @@ -3,9 +3,11 @@ [quo.components.icon :as icon] [quo.components.markdown.text :as text] [quo.components.tags.context-tag.view :as context-tag] + [quo.components.wallet.transaction-summary.schema :as component-schema] [quo.components.wallet.transaction-summary.style :as style] [quo.theme :as quo.theme] [react-native.core :as rn] + [schema.core :as schema] [utils.i18n :as i18n])) (def transaction-translation @@ -101,24 +103,5 @@ :theme theme}]]]) (def view - "Properties: - - :transaction - type of transaction`. Possible values: - - :send - - :swap - - :bridge - - - :first-tag - props for context tag component that will be first on the first line - - :second-tag - props for context tag component that will be second on the first line - - :third-tag - props for context tag component that will be first on the second line - - :fourth-tag - props for context tag component that will be second on the second line - - :fifth-tag - props for context tag component that will be second on the second line - - - :second-tag-prefix - translation keyword to be used with label before second context tag - - :third-tag-prefix - translation keyword to be used with label before third context tag - - :fourth-tag-prefix - translation keyword to be used with label before fourth context tag - - - :max-fees - string - - :nonce - digit - - :input data - string - " - (quo.theme/with-theme view-internal)) + (quo.theme/with-theme + (schema/instrument #'view-internal component-schema/?schema))) diff --git a/src/quo/components/wallet/wallet_activity/component_spec.cljs b/src/quo/components/wallet/wallet_activity/component_spec.cljs index e5df26a8c9c..eaf64c28c2c 100644 --- a/src/quo/components/wallet/wallet_activity/component_spec.cljs +++ b/src/quo/components/wallet/wallet_activity/component_spec.cljs @@ -5,12 +5,12 @@ (h/describe "Wallet activity" (h/test "default render" - (h/render [wallet-activity/view {}]) + (h/render-with-theme-provider [wallet-activity/view {}]) (h/is-truthy (h/query-by-label-text :wallet-activity))) (h/test "Should call :on-press" (let [on-press (h/mock-fn)] - (h/render [wallet-activity/view {:on-press on-press}]) + (h/render-with-theme-provider [wallet-activity/view {:on-press on-press}]) (h/is-truthy (h/query-by-label-text :wallet-activity)) (h/fire-event :press (h/query-by-label-text :wallet-activity)) (h/was-called on-press)))) diff --git a/src/quo/components/wallet/wallet_activity/schema.cljs b/src/quo/components/wallet/wallet_activity/schema.cljs new file mode 100644 index 00000000000..a1386352751 --- /dev/null +++ b/src/quo/components/wallet/wallet_activity/schema.cljs @@ -0,0 +1,24 @@ +(ns quo.components.wallet.wallet-activity.schema + (:require [quo.components.tags.context-tag.schema :as context-tag-schema])) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:transaction {:optional true} [:maybe [:enum :receive :send :swap :bridge :buy :destroy :mint]]] + [:status {:optional true} [:maybe [:enum :pending :confirmed :finalised :failed]]] + [:counter {:optional true} [:maybe :int]] + [:timestamp {:optional true} [:maybe :string]] + [:blur? {:optional true} [:maybe :boolean]] + [:on-press {:optional true} [:maybe fn?]] + [:state {:optional true} [:maybe [:= :disabled]]] + [:theme :schema.common/theme] + [:second-tag-prefix {:optional true} [:maybe :keyword]] + [:third-tag-prefix {:optional true} [:maybe :keyword]] + [:fourth-tag-prefix {:optional true} [:maybe :keyword]] + [:first-tag {:optional true} [:maybe context-tag-schema/?schema]] + [:second-tag {:optional true} [:maybe context-tag-schema/?schema]] + [:third-tag {:optional true} [:maybe context-tag-schema/?schema]] + [:fourth-tag {:optional true} [:maybe context-tag-schema/?schema]]]]] + :any]) diff --git a/src/quo/components/wallet/wallet_activity/view.cljs b/src/quo/components/wallet/wallet_activity/view.cljs index a63fbc49c67..fd08a9efc5d 100644 --- a/src/quo/components/wallet/wallet_activity/view.cljs +++ b/src/quo/components/wallet/wallet_activity/view.cljs @@ -3,11 +3,13 @@ [quo.components.icon :as icon] [quo.components.markdown.text :as text] [quo.components.tags.context-tag.view :as context-tag] + [quo.components.wallet.wallet-activity.schema :as component-schema] [quo.components.wallet.wallet-activity.style :as style] [quo.theme :as quo.theme] [react-native.core :as rn] [react-native.hole-view :as hole-view] [reagent.core :as reagent] + [schema.core :as schema] [utils.i18n :as i18n])) (def transaction-translation @@ -132,35 +134,5 @@ (when fourth-tag [prop-tag fourth-tag blur?])]]]]))) (def view - "Properties: - - :transaction - type of transaction`. Possible values: - - :receive - - :send - - :swap - - :bridge - - :buy - - :destroy - - :mint - - - :status - transaction status. Possible values: - - :pending - - :confirmed - - :finalised - - :failed - - - :counter - amount of transactions shown by instance of the component - - - :timestamp - when transaction occured (string) - - :blur? - - - :first-tag - props for context tag component that will be first on the first line - - :second-tag - props for context tag component that will be second on the first line - - :third-tag - props for context tag component that will be first on the second line - - :fourth-tag - props for context tag component that will be second on the second line - - - :second-tag-prefix - translation keyword to be used with label before second context tag - - :third-tag-prefix - translation keyword to be used with label before third context tag - - :fourth-tag-prefix - translation keyword to be used with label before fourth context tag - - " - (quo.theme/with-theme view-internal)) + (quo.theme/with-theme + (schema/instrument #'view-internal component-schema/?schema))) diff --git a/src/quo/components/wallet/wallet_overview/component_spec.cljs b/src/quo/components/wallet/wallet_overview/component_spec.cljs index 60f26b9b73b..ff691cee525 100644 --- a/src/quo/components/wallet/wallet_overview/component_spec.cljs +++ b/src/quo/components/wallet/wallet_overview/component_spec.cljs @@ -6,9 +6,9 @@ (h/describe "Wallet overview test" (h/test "renders correct balance" - (h/render [wallet-overview/view - {:state :default - :time-frame :one-week - :metrics :positive - :balance "€0.01"}]) + (h/render-with-theme-provider [wallet-overview/view + {:state :default + :time-frame :one-week + :metrics :positive + :balance "€0.01"}]) (h/is-truthy (h/get-by-text "€0.01")))) diff --git a/src/quo/components/wallet/wallet_overview/schema.cljs b/src/quo/components/wallet/wallet_overview/schema.cljs new file mode 100644 index 00000000000..d65836c7bc5 --- /dev/null +++ b/src/quo/components/wallet/wallet_overview/schema.cljs @@ -0,0 +1,23 @@ +(ns quo.components.wallet.wallet-overview.schema) + +(def ?schema + [:=> + [:catn + [:props + [:map + [:state {:optional true} [:maybe [:enum :default :loading]]] + [:time-frame {:optional true} + [:maybe [:enum :none :selected :one-week :one-month :three-months :one-year :all-time :custom]]] + [:metrics {:optional true} [:maybe [:enum :none :negative :positive]]] + [:balance {:optional true} [:maybe :string]] + [:date {:optional true} [:maybe :string]] + [:begin-date {:optional true} [:maybe :string]] + [:end-date {:optional true} [:maybe :string]] + [:currency-change {:optional true} [:maybe :string]] + [:percentage-change {:optional true} [:maybe :string]] + [:theme :schema.common/theme] + [:dropdown-on-press {:optional true} [:maybe fn?]] + [:networks {:optional true} + [:maybe [:sequential [:map [:source [:maybe :schema.common/image-source]]]]]] + [:dropdown-state {:optional true} [:maybe [:enum :default :disabled]]]]]] + :any]) diff --git a/src/quo/components/wallet/wallet_overview/view.cljs b/src/quo/components/wallet/wallet_overview/view.cljs index ce62fcc98c2..f3045225ba2 100644 --- a/src/quo/components/wallet/wallet_overview/view.cljs +++ b/src/quo/components/wallet/wallet_overview/view.cljs @@ -3,9 +3,11 @@ [quo.components.dropdowns.network-dropdown.view :as network-dropdown] [quo.components.icon :as icon] [quo.components.markdown.text :as text] + [quo.components.wallet.wallet-overview.schema :as component-schema] [quo.components.wallet.wallet-overview.style :as style] [quo.theme :as quo.theme] [react-native.core :as rn] + [schema.core :as schema] [utils.i18n :as i18n])) (def ^:private time-frames @@ -117,4 +119,5 @@ [view-info-bottom props]]) (def view - (quo.theme/with-theme view-internal)) + (quo.theme/with-theme + (schema/instrument #'view-internal component-schema/?schema))) diff --git a/src/quo/core.cljs b/src/quo/core.cljs index ede15507d27..de7a05d4527 100644 --- a/src/quo/core.cljs +++ b/src/quo/core.cljs @@ -405,7 +405,9 @@ (def channel-name quo.components.text-combinations.channel-name.view/view) (def page-top quo.components.text-combinations.page-top.view/view) (def standard-title quo.components.text-combinations.standard-title.view/view) -(def text-combinations quo.components.text-combinations.view/view) +(def ^{:deprecated "quo.components.text-combinations.page-top.view should be used instead"} + text-combinations + quo.components.text-combinations.view/view) (def username quo.components.text-combinations.username.view/view) ;;;; Utilities - Outside of design system diff --git a/src/schema/common.cljs b/src/schema/common.cljs index 33535311626..bc9708735e1 100644 --- a/src/schema/common.cljs +++ b/src/schema/common.cljs @@ -13,7 +13,8 @@ (def ^:private ?image-source [:or - [:int] + :int + :string [:map [:uri [:maybe [:string]]]]]) diff --git a/src/status_im/common/bottom_sheet_screen/view.cljs b/src/status_im/common/bottom_sheet_screen/view.cljs index d02f1002edf..e9783b456e6 100644 --- a/src/status_im/common/bottom_sheet_screen/view.cljs +++ b/src/status_im/common/bottom_sheet_screen/view.cljs @@ -4,7 +4,6 @@ [quo.theme :as theme] [react-native.core :as rn] [react-native.gesture :as gesture] - [react-native.hooks :as hooks] [react-native.platform :as platform] [react-native.reanimated :as reanimated] [react-native.safe-area :as safe-area] @@ -58,7 +57,8 @@ (set-animating-true) (reanimated/animate translate-y height 300) (reanimated/animate opacity 0 300) - (rf/dispatch [:navigate-back])) + (rf/dispatch [:navigate-back]) + true) reset-open-sheet (fn [] (reanimated/animate translate-y 0 300) (reanimated/animate opacity 1 300) @@ -66,10 +66,11 @@ (reset! scroll-enabled? true))] (rn/use-effect (fn [] + (rn/hw-back-add-listener close) (reanimated/animate translate-y 0 300) (reanimated/animate opacity 1 300) - (set-animating-false 300))) - (hooks/use-back-handler close) + (set-animating-false 300) + #(rn/hw-back-remove-listener close))) [rn/view {:style (style/container insets)} (when-not skip-background? [reanimated/view {:style (style/background opacity)}]) @@ -87,7 +88,7 @@ [content {:insets insets :close close - :scroll-enabled? @scroll-enabled? + :scroll-enabled? scroll-enabled? :current-scroll curr-scroll :on-scroll #(on-scroll % curr-scroll) :sheet-animating? animating?}]]]])))) diff --git a/src/status_im/common/emoji_picker/view.cljs b/src/status_im/common/emoji_picker/view.cljs index aab8ac028be..e09e8754fe7 100644 --- a/src/status_im/common/emoji_picker/view.cljs +++ b/src/status_im/common/emoji_picker/view.cljs @@ -98,7 +98,7 @@ on-select set-scroll-ref close sheet-animating?]}] [gesture/flat-list {:ref set-scroll-ref - :scroll-enabled scroll-enabled? + :scroll-enabled @scroll-enabled? :data (or filtered-data emoji-picker.data/flatten-data) :initial-num-to-render 14 :max-to-render-per-batch 10 diff --git a/src/status_im/common/qr_codes/view.cljs b/src/status_im/common/qr_codes/view.cljs index a3da20fa1ae..c43686db23f 100644 --- a/src/status_im/common/qr_codes/view.cljs +++ b/src/status_im/common/qr_codes/view.cljs @@ -33,9 +33,12 @@ (let [qr-media-server-uri (image-server/get-qr-image-uri-for-any-url {:url url :port (rf/sub [:mediaserver/port]) - :qr-size (or 400 (int size)) + :qr-size (or (int size) 400) :error-level :highest})] - [quo/qr-code (assoc props :qr-image-uri qr-media-server-uri)])) + [quo/qr-code + (assoc props + :qr-image-uri + qr-media-server-uri)])) (defn get-network-short-name-url [network] diff --git a/src/status_im/common/standard_authentication/password_input/view.cljs b/src/status_im/common/standard_authentication/password_input/view.cljs index 50eb424b448..bba900585cf 100644 --- a/src/status_im/common/standard_authentication/password_input/view.cljs +++ b/src/status_im/common/standard_authentication/password_input/view.cljs @@ -7,6 +7,7 @@ [react-native.core :as rn] [status-im.common.standard-authentication.forgot-password-doc.view :as forgot-password-doc] [status-im.common.standard-authentication.password-input.style :as style] + [utils.debounce :as debounce] [utils.i18n :as i18n] [utils.re-frame :as rf] [utils.security.core :as security])) @@ -22,9 +23,10 @@ (defn- on-change-password [entered-password] - (rf/dispatch [:set-in [:profile/login :password] - (security/mask-data entered-password)]) - (rf/dispatch [:set-in [:profile/login :error] ""])) + (debounce/debounce-and-dispatch [:profile/on-password-input-changed + {:password (security/mask-data entered-password) + :error ""}] + 100)) (defn- view-internal [{:keys [default-password theme shell? on-press-biometrics blur?]}] diff --git a/src/status_im/contexts/chat/home/new_chat/view.cljs b/src/status_im/contexts/chat/home/new_chat/view.cljs index 2aa656c49ef..1ac18f50ab6 100644 --- a/src/status_im/contexts/chat/home/new_chat/view.cljs +++ b/src/status_im/contexts/chat/home/new_chat/view.cljs @@ -105,7 +105,7 @@ :render-section-header-fn contact-list/contacts-section-header :content-container-style {:padding-bottom 70} :render-fn contact-item-render - :scroll-enabled scroll-enabled? + :scroll-enabled @scroll-enabled? :on-scroll on-scroll}]) (when contacts-selected? [quo/button diff --git a/src/status_im/contexts/chat/messenger/composer/actions/view.cljs b/src/status_im/contexts/chat/messenger/composer/actions/view.cljs index 2b824833428..5a3e97cecf5 100644 --- a/src/status_im/contexts/chat/messenger/composer/actions/view.cljs +++ b/src/status_im/contexts/chat/messenger/composer/actions/view.cljs @@ -182,8 +182,7 @@ (defn open-photo-selector [{:keys [input-ref]} - {:keys [height]} - insets] + {:keys [height]}] (permissions/request-permissions {:permissions [(if platform/is-below-android-13? :read-external-storage :read-media-images) :write-external-storage] @@ -192,18 +191,18 @@ (.blur ^js @input-ref)) (rf/dispatch [:chat.ui/set-input-content-height (reanimated/get-shared-value height)]) - (rf/dispatch [:open-modal :photo-selector {:insets insets}])) + (rf/dispatch [:photo-selector/navigate-to-photo-selector])) :on-denied (fn [] (alert.effects/show-popup (i18n/label :t/error) (i18n/label :t/external-storage-denied)))})) (defn image-button - [props animations insets edit] + [props animations edit] [quo/composer-button {:on-press (if edit #(js/alert "This feature is temporarily unavailable in edit mode.") - #(open-photo-selector props animations insets)) + #(open-photo-selector props animations)) :accessibility-label :open-images-button :container-style {:margin-right 12} :icon :i/image}]) @@ -228,7 +227,7 @@ :icon :i/format}]) (defn view - [props state animations window-height insets {:keys [edit images]}] + [props state animations window-height {:keys [edit images]}] (let [send-btn-opacity (reanimated/use-shared-value 0) audio-btn-opacity (reanimated/interpolate send-btn-opacity [0 1] [1 0])] [rn/view {:style style/actions-container} @@ -236,7 +235,7 @@ {:style {:flex-direction :row :display (if @(:recording? state) :none :flex)}} [camera-button edit] - [image-button props animations insets edit] + [image-button props animations edit] [reaction-button] [format-button]] [:f> send-button props state animations window-height images edit send-btn-opacity] diff --git a/src/status_im/contexts/chat/messenger/composer/view.cljs b/src/status_im/contexts/chat/messenger/composer/view.cljs index aab0663da1a..237ecab9738 100644 --- a/src/status_im/contexts/chat/messenger/composer/view.cljs +++ b/src/status_im/contexts/chat/messenger/composer/view.cljs @@ -142,7 +142,7 @@ [gradients/view props state animations show-bottom-gradient?] [link-preview/view] [images/images-list]] - [:f> actions/view props state animations window-height insets subscriptions]]]]])) + [:f> actions/view props state animations window-height subscriptions]]]]])) (defn f-composer [props] diff --git a/src/status_im/contexts/chat/messenger/photo_selector/album_selector/view.cljs b/src/status_im/contexts/chat/messenger/photo_selector/album_selector/view.cljs index b67bd316d36..e58db9e70ae 100644 --- a/src/status_im/contexts/chat/messenger/photo_selector/album_selector/view.cljs +++ b/src/status_im/contexts/chat/messenger/photo_selector/album_selector/view.cljs @@ -87,7 +87,7 @@ :content-container-style {:padding-top 64 :padding-bottom 40} :key-fn key-fn - :scroll-enabled scroll-enabled? + :scroll-enabled @scroll-enabled? :on-scroll on-scroll :style {:height window-height}}]])) diff --git a/src/status_im/contexts/chat/messenger/photo_selector/events.cljs b/src/status_im/contexts/chat/messenger/photo_selector/events.cljs index 27f287f3293..2b8357fe4af 100644 --- a/src/status_im/contexts/chat/messenger/photo_selector/events.cljs +++ b/src/status_im/contexts/chat/messenger/photo_selector/events.cljs @@ -1,5 +1,6 @@ (ns status-im.contexts.chat.messenger.photo-selector.events (:require + [re-frame.core :as re-frame] [status-im.constants :as constants] status-im.contexts.chat.messenger.photo-selector.effects [utils.i18n :as i18n] @@ -74,3 +75,9 @@ (when (and (< (count images) constants/max-album-photos) (not (some #(= (:uri image) (:uri %)) images))) {:effects.camera-roll/image-selected [image current-chat-id]}))) + +(re-frame/reg-event-fx :photo-selector/navigate-to-photo-selector + (fn [] + {:fx [[:dispatch [:open-modal :photo-selector]] + [:dispatch [:photo-selector/get-photos-for-selected-album]] + [:dispatch [:photo-selector/camera-roll-get-albums]]]})) diff --git a/src/status_im/contexts/chat/messenger/photo_selector/view.cljs b/src/status_im/contexts/chat/messenger/photo_selector/view.cljs index f25dc294983..25b655c8965 100644 --- a/src/status_im/contexts/chat/messenger/photo_selector/view.cljs +++ b/src/status_im/contexts/chat/messenger/photo_selector/view.cljs @@ -70,13 +70,14 @@ (let [customization-color (rf/sub [:profile/customization-color]) item-selected? (some #(= (:uri item) (:uri %)) @selected)] [rn/touchable-opacity - {:on-press (fn [] - (if item-selected? - (swap! selected remove-selected item) - (if (>= (count @selected) constants/max-album-photos) - (show-photo-limit-toast) - (swap! selected conj item)))) - :accessibility-label (str "image-" index)} + {:on-press (fn [] + (if item-selected? + (swap! selected remove-selected item) + (if (>= (count @selected) constants/max-album-photos) + (show-photo-limit-toast) + (swap! selected conj item)))) + :allow-multiple-presses? true + :accessibility-label (str "image-" index)} [rn/image {:source {:uri (:uri item)} :style (style/image window-width index)}] @@ -91,8 +92,6 @@ (defn photo-selector [{:keys [scroll-enabled? on-scroll current-scroll close] :as sheet}] - (rf/dispatch [:photo-selector/get-photos-for-selected-album]) - (rf/dispatch [:photo-selector/camera-roll-get-albums]) (let [album? (reagent/atom false) customization-color (rf/sub [:profile/customization-color]) sending-image (into [] (vals (rf/sub [:chats/sending-image]))) @@ -134,7 +133,7 @@ :padding-bottom (+ (safe-area/get-bottom) 100) :padding-top 64} :on-scroll on-scroll - :scroll-enabled scroll-enabled? + :scroll-enabled @scroll-enabled? :on-end-reached (fn [] (when (and (not loading?) has-next-page?) (rf/dispatch [:photo-selector/camera-roll-loading-more true]) diff --git a/src/status_im/contexts/communities/actions/accounts_selection/style.cljs b/src/status_im/contexts/communities/actions/accounts_selection/style.cljs index 19fffacaff2..7968f2815b7 100644 --- a/src/status_im/contexts/communities/actions/accounts_selection/style.cljs +++ b/src/status_im/contexts/communities/actions/accounts_selection/style.cljs @@ -7,10 +7,6 @@ (def container {:flex 1}) -(def page-top - {:padding-vertical 12 - :padding-horizontal screen-horizontal-padding}) - (def section-title {:padding-top 12 :padding-bottom 4 @@ -18,11 +14,6 @@ (defn bottom-actions [] - {:position :absolute - :background-color (colors/theme-colors colors/white colors/neutral-95) - :bottom 0 - :left 0 - :right 0 + {:padding-top 12 :padding-horizontal screen-horizontal-padding - :padding-vertical 12 - :flex 1}) + :background-color (colors/theme-colors colors/white colors/neutral-95)}) diff --git a/src/status_im/contexts/communities/actions/accounts_selection/view.cljs b/src/status_im/contexts/communities/actions/accounts_selection/view.cljs index 8c8100d2a0f..853e11c347f 100644 --- a/src/status_im/contexts/communities/actions/accounts_selection/view.cljs +++ b/src/status_im/contexts/communities/actions/accounts_selection/view.cljs @@ -28,7 +28,7 @@ highest-role-text (i18n/label (communities.utils/role->translation-key highest-permission-role :t/member))] - [rn/view {:style style/container} + [rn/safe-area-view {:style style/container} [quo/page-nav {:text-align :left :icon-name :i/close diff --git a/src/status_im/contexts/communities/actions/addresses_for_permissions/style.cljs b/src/status_im/contexts/communities/actions/addresses_for_permissions/style.cljs index f3e508e0fd2..1f0b2ab1266 100644 --- a/src/status_im/contexts/communities/actions/addresses_for_permissions/style.cljs +++ b/src/status_im/contexts/communities/actions/addresses_for_permissions/style.cljs @@ -1,16 +1,3 @@ (ns status-im.contexts.communities.actions.addresses-for-permissions.style) (def container {:flex 1}) - -(def buttons - {:flex-direction :row - :gap 12 - :padding-horizontal 20 - :padding-vertical 12}) - -(def highest-role - {:flex-direction :row - :gap 4 - :justify-content :center - :align-items :center - :margin-bottom 8}) diff --git a/src/status_im/contexts/communities/actions/addresses_for_permissions/view.cljs b/src/status_im/contexts/communities/actions/addresses_for_permissions/view.cljs index c4450884004..d793a221a98 100644 --- a/src/status_im/contexts/communities/actions/addresses_for_permissions/view.cljs +++ b/src/status_im/contexts/communities/actions/addresses_for_permissions/view.cljs @@ -1,17 +1,24 @@ (ns status-im.contexts.communities.actions.addresses-for-permissions.view (:require [quo.core :as quo] - [quo.foundations.colors :as colors] [react-native.core :as rn] [react-native.gesture :as gesture] [status-im.common.not-implemented :as not-implemented] [status-im.common.resources :as resources] [status-im.constants :as constants] [status-im.contexts.communities.actions.addresses-for-permissions.style :as style] - [status-im.contexts.communities.utils :as communities.utils] [utils.i18n :as i18n] [utils.money :as money] [utils.re-frame :as rf])) +(defn- role-keyword + [role] + (condp = role + constants/community-token-permission-become-token-owner :token-owner + constants/community-token-permission-become-token-master :token-master + constants/community-token-permission-become-admin :admin + constants/community-token-permission-become-member :member + nil)) + (defn- balances->components-props [balances] (for [{:keys [amount decimals type name] :as balance} balances] @@ -54,14 +61,12 @@ (rf/dispatch [:communities/get-permissioned-balances id]) (fn [] (let [{:keys [name color images]} (rf/sub [:communities/community id]) - {:keys [highest-permission-role]} (rf/sub [:community/token-gated-overview id]) + {:keys [checking? + highest-permission-role]} (rf/sub [:community/token-gated-overview id]) accounts (rf/sub [:wallet/accounts-without-watched-accounts]) selected-addresses (rf/sub [:communities/selected-permission-addresses id]) share-all-addresses? (rf/sub [:communities/share-all-addresses? id]) - unsaved-address-changes? (rf/sub [:communities/unsaved-address-changes? id]) - highest-role-text (when highest-permission-role - (i18n/label (communities.utils/role->translation-key - highest-permission-role)))] + unsaved-address-changes? (rf/sub [:communities/unsaved-address-changes? id])] [rn/safe-area-view {:style style/container} [quo/drawer-top {:type :context-tag @@ -92,47 +97,38 @@ :share-all-addresses? share-all-addresses? :community-color color} :content-container-style {:padding-horizontal 20} - :scroll-enabled scroll-enabled? + :scroll-enabled @scroll-enabled? :on-scroll on-scroll :key-fn :address :data accounts}] - (if (and highest-permission-role (seq selected-addresses)) - [rn/view - {:style style/highest-role} - [quo/text - {:size :paragraph-2 - :style {:color colors/neutral-50}} - (i18n/label :t/eligible-to-join-as)] - [quo/context-tag - {:type :icon - :icon :i/members - :size 24 - :context highest-role-text}]] - [quo/info-message - {:type :error - :size :default - :icon :i/info - :style {:justify-content :center}} - (if (empty? selected-addresses) - (i18n/label :t/no-addresses-selected) - (i18n/label :t/addresses-dont-contain-tokens-needed))]) + [quo/bottom-actions + {:actions :two-actions + :button-one-label (i18n/label :t/confirm-changes) + :button-one-props {:customization-color color + :disabled? (or checking? + (empty? selected-addresses) + (not highest-permission-role) + (not unsaved-address-changes?)) + :on-press (fn [] + (rf/dispatch + [:communities/update-previous-permission-addresses + id]) + (rf/dispatch [:navigate-back]))} + :button-two-label (i18n/label :t/cancel) + :button-two-props {:type :grey + :on-press (fn [] + (rf/dispatch + [:communities/reset-selected-permission-addresses id]) + (rf/dispatch [:navigate-back]))} + :description (if (or (empty? selected-addresses) + (not highest-permission-role)) + :top-error + :top) + :role (when-not checking? (role-keyword highest-permission-role)) + :error-message (cond + (empty? selected-addresses) (i18n/label :t/no-addresses-selected) + (not highest-permission-role) (i18n/label + :t/addresses-dont-contain-tokens-needed) + :else nil)}]])))) - [rn/view {:style style/buttons} - [quo/button - {:type :grey - :container-style {:flex 1} - :on-press (fn [] - (rf/dispatch [:communities/reset-selected-permission-addresses id]) - (rf/dispatch [:navigate-back]))} - (i18n/label :t/cancel)] - [quo/button - {:container-style {:flex 1} - :customization-color color - :disabled? (or (empty? selected-addresses) - (not highest-permission-role) - (not unsaved-address-changes?)) - :on-press (fn [] - (rf/dispatch [:communities/update-previous-permission-addresses id]) - (rf/dispatch [:navigate-back]))} - (i18n/label :t/confirm-changes)]]])))) diff --git a/src/status_im/contexts/communities/actions/chat/view.cljs b/src/status_im/contexts/communities/actions/chat/view.cljs index 2a171d1a077..e65c4218ffe 100644 --- a/src/status_im/contexts/communities/actions/chat/view.cljs +++ b/src/status_im/contexts/communities/actions/chat/view.cljs @@ -94,10 +94,10 @@ :label (i18n/label :t/invite-people-from-contacts)}) (defn- action-qr-code - [] + [chat-id] {:icon :i/qr-code :accessibility-label :chat-show-qr-code - :on-press not-implemented/alert + :on-press #(rf/dispatch [:communities/share-community-channel-url-qr-code chat-id]) :label (i18n/label :t/show-qr)}) (defn- action-share @@ -115,7 +115,7 @@ [quo/action-drawer [[(action-invite-people) (action-token-requirements) - (action-qr-code) + (action-qr-code chat-id) (action-share chat-id)]]] (and (not inside-chat?) (not locked?)) @@ -126,7 +126,7 @@ (action-notification-settings) (action-pinned-messages) (action-invite-people) - (action-qr-code) + (action-qr-code chat-id) (action-share chat-id)]]] (and inside-chat? (not locked?)) @@ -139,7 +139,7 @@ (when config/fetch-messages-enabled? (chat-actions/fetch-messages chat-id)) (action-invite-people) - (action-qr-code) + (action-qr-code chat-id) (action-share chat-id)]]] :else nil))) diff --git a/src/status_im/contexts/communities/actions/community_rules/style.cljs b/src/status_im/contexts/communities/actions/community_rules/style.cljs index 6a2b39621d6..1deb6960e76 100644 --- a/src/status_im/contexts/communities/actions/community_rules/style.cljs +++ b/src/status_im/contexts/communities/actions/community_rules/style.cljs @@ -3,5 +3,6 @@ (def community-rule {:flex 1 :align-items :flex-start - :padding-vertical 8 + :padding-top 8 + :margin-bottom 12 :padding-horizontal 20}) diff --git a/src/status_im/contexts/communities/actions/share_community_channel/style.cljs b/src/status_im/contexts/communities/actions/share_community_channel/style.cljs new file mode 100644 index 00000000000..db71ed6f0df --- /dev/null +++ b/src/status_im/contexts/communities/actions/share_community_channel/style.cljs @@ -0,0 +1,35 @@ +(ns status-im.contexts.communities.actions.share-community-channel.style + (:require [quo.foundations.colors :as colors])) + +(def header-container + {:padding-horizontal 20 + :padding-vertical 12}) + +(def scan-notice + {:color colors/white-70-blur + :margin-top 16 + :margin-left :auto + :margin-right :auto}) + +(def qr-code-wrapper + {:padding-horizontal 20 + :margin-top 8 + :align-items :center}) + +(def gradient-cover-padding 20) +(def qr-code-padding 12) + +(defn qr-code-size + [total-width] + (- total-width (* gradient-cover-padding 2) (* qr-code-padding 2))) + +(defn gradient-cover-size + [total-width] + (- total-width (* gradient-cover-padding 2))) + +(defn gradient-cover-wrapper + [width] + {:width (gradient-cover-size width) + :position :absolute + :border-radius 12 + :z-index -1}) diff --git a/src/status_im/contexts/communities/actions/share_community_channel/view.cljs b/src/status_im/contexts/communities/actions/share_community_channel/view.cljs new file mode 100644 index 00000000000..58ba51592bf --- /dev/null +++ b/src/status_im/contexts/communities/actions/share_community_channel/view.cljs @@ -0,0 +1,47 @@ +(ns status-im.contexts.communities.actions.share-community-channel.view + (:require + [quo.core :as quo] + [react-native.core :as rn] + [react-native.safe-area :as safe-area] + [status-im.common.qr-codes.view :as qr-codes] + [status-im.contexts.communities.actions.share-community-channel.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(defn view + [] + (fn [] + (let [{:keys [url chat-id]} (rf/sub [:get-screen-params]) + {:keys [color emoji chat-name]} (rf/sub [:chats/community-channel-ui-details-by-id chat-id]) + window-width (rf/sub [:dimensions/window-width])] + [quo/overlay {:type :shell} + [rn/view + {:style {:padding-top (safe-area/get-top)} + :key :share-community} + [quo/page-nav + {:icon-name :i/close + :on-press #(rf/dispatch [:navigate-back]) + :background :blur + :accessibility-label :top-bar}] + [quo/text-combinations + {:container-style style/header-container + :title (i18n/label :t/share-channel)}] + [rn/view {:style style/qr-code-wrapper} + [quo/gradient-cover + {:container-style + (style/gradient-cover-wrapper window-width) + :customization-color color}] + [rn/view + {:style {:padding-vertical 12}} + [qr-codes/qr-code + {:size (style/qr-code-size window-width) + :url url + :avatar :channel + :customization-color color + :emoji emoji + :full-name chat-name}]]] + [quo/text + {:size :paragraph-2 + :weight :regular + :style style/scan-notice} + (i18n/label :t/scan-with-status-app)]]]))) diff --git a/src/status_im/contexts/communities/events.cljs b/src/status_im/contexts/communities/events.cljs index 36777deee6b..67ece5168c1 100644 --- a/src/status_im/contexts/communities/events.cljs +++ b/src/status_im/contexts/communities/events.cljs @@ -223,16 +223,19 @@ (defn toggle-share-all-addresses [{:keys [db]} [community-id]] - (let [share-all-addresses? (get-in db [:communities community-id :share-all-addresses?]) - accounts (utils/sorted-non-watch-only-accounts db) - addresses (set (map :address accounts))] + (let [share-all-addresses? (get-in db [:communities community-id :share-all-addresses?]) + next-share-all-addresses? (not share-all-addresses?) + accounts (utils/sorted-non-watch-only-accounts db) + addresses (set (map :address accounts))] {:db (update-in db [:communities community-id] - (fn [community] - (-> community - (assoc :share-all-addresses? (not share-all-addresses?)) - (cond-> (not share-all-addresses?) - (assoc :selected-permission-addresses addresses)))))})) + assoc + :share-all-addresses? next-share-all-addresses? + :selected-permission-addresses addresses) + :fx [(when (and community-id next-share-all-addresses?) + [:dispatch + [:communities/check-permissions-to-join-community community-id + addresses :based-on-client-selection]])]})) (rf/reg-event-fx :communities/toggle-share-all-addresses toggle-share-all-addresses) @@ -249,14 +252,23 @@ (get-in db [:communities community-id :previous-share-all-addresses?])) :fx [[:dispatch [:communities/check-permissions-to-join-community community-id]]]}))) -(rf/reg-event-fx :communities/share-community-channel-url-with-data - (fn [_ [chat-id]] - (let [{:keys [community-id channel-id]} (data-store.chats/decode-chat-id chat-id) - title (i18n/label :t/channel-on-status)] +(rf/reg-event-fx :communities/get-community-channel-share-data + (fn [_ [chat-id on-success]] + (let [{:keys [community-id channel-id]} (data-store.chats/decode-chat-id chat-id)] {:json-rpc/call [{:method "wakuext_shareCommunityChannelURLWithData" :params [{:CommunityID community-id :ChannelID channel-id}] - :on-success (fn [url] + :on-success on-success + :on-error (fn [err] + (log/error "failed to retrieve community channel url with data" + {:error err + :chat-id chat-id + :event :communities/get-community-channel-share-data}))}]}))) + +(rf/reg-event-fx :communities/share-community-channel-url-with-data + (fn [_ [chat-id]] + (let [title (i18n/label :t/channel-on-status) + on-success (fn [url] (share/open (if platform/ios? {:activityItemSources [{:placeholderItem {:type "text" @@ -268,12 +280,15 @@ :subject title :message url :url url - :isNewTask true}))) - :on-error (fn [err] - (log/error "failed to retrieve community channel url with data" - {:error err - :chat-id chat-id - :event "share-community-channel-url-with-data"}))}]}))) + :isNewTask true})))] + {:fx [[:dispatch [:communities/get-community-channel-share-data chat-id on-success]]]}))) + +(rf/reg-event-fx :communities/share-community-channel-url-qr-code + (fn [_ [chat-id]] + (let [on-success #(rf/dispatch [:open-modal :share-community-channel + {:chat-id chat-id + :url %}])] + {:fx [[:dispatch [:communities/get-community-channel-share-data chat-id on-success]]]}))) (rf/reg-event-fx :communities/set-airdrop-address (fn [{:keys [db]} [address community-id]] diff --git a/src/status_im/contexts/communities/events_test.cljs b/src/status_im/contexts/communities/events_test.cljs index 374d8763bb2..25dffdc49bf 100644 --- a/src/status_im/contexts/communities/events_test.cljs +++ b/src/status_im/contexts/communities/events_test.cljs @@ -74,8 +74,8 @@ :position 1}}} :communities {community-id {:share-all-addresses? true :previous-share-all-addresses? true - :previous-permission-addresses #{"0x1"} - :selected-permission-addresses #{"0x1"} + :previous-permission-addresses #{"0x1" "0x2"} + :selected-permission-addresses #{"0x1" "0x2"} :airdrop-address "0x1"}}}} expected-db (update-in initial-db [:db :communities community-id] diff --git a/src/status_im/contexts/communities/overview/view.cljs b/src/status_im/contexts/communities/overview/view.cljs index d3059f8db9f..8dbf13b27f2 100644 --- a/src/status_im/contexts/communities/overview/view.cljs +++ b/src/status_im/contexts/communities/overview/view.cljs @@ -71,7 +71,7 @@ {:key category-id ;; on-layout fires only when the component re-renders, so ;; in case the category hasn't changed, it will not be fired - :on-layout #(on-category-layout name (int (layout-y %)))} + :on-layout #(on-category-layout name category-id (int (layout-y %)))} (when-not (= constants/empty-category-id category-id) [quo/divider-label {:on-press #(collapse-category community-id category-id collapsed?) @@ -238,18 +238,18 @@ (defn- community-header [title logo description] [quo/text-combinations - {:container-style - {:margin-top - (if logo - 12 - (+ scroll-page.style/picture-radius - scroll-page.style/picture-border-width - 12)) - :margin-bottom 12} - :avatar logo - :title title - :description description - :title-accessibility-label :community-title + {:container-style {:margin-top + (if logo + 12 + (+ scroll-page.style/picture-radius + scroll-page.style/picture-border-width + 12)) + :margin-bottom 12} + :avatar logo + :title title + :title-number-of-lines 2 + :description description + :title-accessibility-label :community-title :description-accessibility-label :community-description}]) (defn- community-content @@ -328,10 +328,14 @@ (swap! categories-heights select-keys categories) (reset! first-channel-height height))] (fn [id joined name images] - (let [cover {:uri (get-in images [:banner :uri])} - logo {:uri (get-in images [:thumbnail :uri])} - collapsed? (and initial-joined? joined) - overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))] + (let [cover {:uri (get-in images [:banner :uri])} + logo {:uri (get-in images [:thumbnail :uri])} + collapsed? (and initial-joined? joined) + first-category-height (->> @categories-heights + vals + (apply min) + (+ @first-channel-height)) + overlay-shown? (boolean (:sheets (rf/sub [:bottom-sheet])))] [scroll-page/scroll-page {:cover-image cover :collapsed? collapsed? @@ -347,7 +351,8 @@ :community-name name :community-logo logo} :sticky-header [sticky-category-header - {:enabled (> @scroll-height @first-channel-height) + {:enabled (> @scroll-height + first-category-height) :label (pick-first-category-by-height @scroll-height @first-channel-height diff --git a/src/status_im/contexts/preview/quo/community/community_card_view.cljs b/src/status_im/contexts/preview/quo/community/community_card_view.cljs index b3675bd930d..7b39ebf4fe8 100644 --- a/src/status_im/contexts/preview/quo/community/community_card_view.cljs +++ b/src/status_im/contexts/preview/quo/community/community_card_view.cljs @@ -15,15 +15,15 @@ :community-icon (resources/get-mock-image :status-logo) :customization-color :blue :tokens [{:id 1 :group [{:id 1 :token-icon (resources/get-mock-image :status-logo)}]}] - :tags [{:id 1 - :tag-label (i18n/label :t/music) - :emoji (resources/get-image :music)} - {:id 2 - :tag-label (i18n/label :t/lifestyle) - :emoji (resources/get-image :lifestyle)} - {:id 3 - :tag-label (i18n/label :t/podcasts) - :emoji (resources/get-image :podcasts)}]}) + :tags [{:id 1 + :name (i18n/label :t/music) + :emoji (resources/get-image :music)} + {:id 2 + :name (i18n/label :t/lifestyle) + :emoji "🧩"} + {:id 3 + :name (i18n/label :t/podcasts) + :emoji "🎶"}]}) (def descriptor [{:key :status diff --git a/src/status_im/contexts/preview/quo/wallet/transaction_progress.cljs b/src/status_im/contexts/preview/quo/wallet/transaction_progress.cljs index 396fc237338..3d5dd5014ec 100644 --- a/src/status_im/contexts/preview/quo/wallet/transaction_progress.cljs +++ b/src/status_im/contexts/preview/quo/wallet/transaction_progress.cljs @@ -135,8 +135,6 @@ [] (let [state (reagent/atom {:title "Title" - :counter 40 - :total-box total-box :tag-name "Doodle" :tag-number "120" :epoch-number-mainnet "181,329" diff --git a/src/status_im/contexts/profile/config.cljs b/src/status_im/contexts/profile/config.cljs index 137f97df5e3..2a42f954a00 100644 --- a/src/status_im/contexts/profile/config.cljs +++ b/src/status_im/contexts/profile/config.cljs @@ -43,7 +43,7 @@ :upstreamConfig config/default-network-rpc-url :networkId config/default-network-id :currentNetwork config/default-network - :wakuV2LightClient true + :wakuV2LightClient false :previewPrivacy config/blank-preview?}))) (defn strip-file-prefix diff --git a/src/status_im/contexts/profile/login/events.cljs b/src/status_im/contexts/profile/login/events.cljs index aad293b4070..56d365974a8 100644 --- a/src/status_im/contexts/profile/login/events.cljs +++ b/src/status_im/contexts/profile/login/events.cljs @@ -247,3 +247,8 @@ #(-> % (dissoc :processing) (assoc :error "Invalid password")))})) + +(re-frame/reg-event-fx + :profile/on-password-input-changed + (fn [{:keys [db]} [{:keys [password error]}]] + {:db (update db :profile/login assoc :password password :error error)})) diff --git a/src/status_im/contexts/profile/profiles/view.cljs b/src/status_im/contexts/profile/profiles/view.cljs index e833f879558..b6aa3a39fba 100644 --- a/src/status_im/contexts/profile/profiles/view.cljs +++ b/src/status_im/contexts/profile/profiles/view.cljs @@ -172,13 +172,29 @@ [props] [:f> f-profiles-section props]) +(defn password-input + [] + (let [password (rf/sub [:profile/login-password]) + auth-method (rf/sub [:auth-method])] + [standard-authentication/password-input + {:shell? true + :blur? true + :on-press-biometrics (when (= auth-method constants/auth-method-biometric) + (fn [] + (rf/dispatch [:biometric/authenticate + {:on-success #(rf/dispatch + [:profile.login/biometric-success]) + :on-fail #(rf/dispatch + [:profile.login/biometric-auth-fail + %])}]))) + :default-password password}])) + (defn login-section [{:keys [set-show-profiles]}] - (let [{:keys [processing password]} (rf/sub [:profile/login]) + (let [processing (rf/sub [:profile/login-processing]) {:keys [key-uid name customization-color]} (rf/sub [:profile/login-profile]) sign-in-enabled? (rf/sub [:sign-in-enabled?]) profile-picture (rf/sub [:profile/login-profiles-picture key-uid]) - auth-method (rf/sub [:auth-method]) login-multiaccount #(rf/dispatch [:profile.login/login])] [rn/keyboard-avoiding-view {:style style/login-container @@ -213,18 +229,7 @@ :customization-color (or customization-color :primary) :profile-picture profile-picture :card-style style/login-profile-card}] - [standard-authentication/password-input - {:shell? true - :blur? true - :on-press-biometrics (when (= auth-method constants/auth-method-biometric) - (fn [] - (rf/dispatch [:biometric/authenticate - {:on-success #(rf/dispatch - [:profile.login/biometric-success]) - :on-fail #(rf/dispatch - [:profile.login/biometric-auth-fail - %])}]))) - :default-password password}]] + [password-input]] [quo/button {:size 40 :type :primary diff --git a/src/status_im/contexts/shell/jump_to/view.cljs b/src/status_im/contexts/shell/jump_to/view.cljs index c4ab7fac93d..b64041ad09e 100644 --- a/src/status_im/contexts/shell/jump_to/view.cljs +++ b/src/status_im/contexts/shell/jump_to/view.cljs @@ -15,12 +15,10 @@ (defn navigate-back-handler [] - (if (and (not @navigation.state/curr-modal) - (seq (utils/open-floating-screens))) - (do - (rf/dispatch [:navigate-back]) - true) - false)) + (when (and (not @navigation.state/curr-modal) + (seq (utils/open-floating-screens))) + (rf/dispatch [:navigate-back]) + true)) (defn floating-button [shared-values] diff --git a/src/status_im/contexts/wallet/account/bridge/style.cljs b/src/status_im/contexts/wallet/account/bridge/style.cljs index a436a57baae..10a81375ede 100644 --- a/src/status_im/contexts/wallet/account/bridge/style.cljs +++ b/src/status_im/contexts/wallet/account/bridge/style.cljs @@ -1,9 +1,5 @@ (ns status-im.contexts.wallet.account.bridge.style) -(def header-container - {:padding-horizontal 20 - :padding-vertical 12}) - (def input-container {:padding-horizontal 20 :padding-vertical 8}) diff --git a/src/status_im/contexts/wallet/account/bridge/view.cljs b/src/status_im/contexts/wallet/account/bridge/view.cljs index 59db1c64cc5..8749705dbf0 100644 --- a/src/status_im/contexts/wallet/account/bridge/view.cljs +++ b/src/status_im/contexts/wallet/account/bridge/view.cljs @@ -17,9 +17,7 @@ [account-switcher/view {:on-press #(rf/dispatch [:navigate-back]) :accessibility-label :top-bar}] - [quo/text-combinations - {:container-style style/header-container - :title (i18n/label :t/bridge)}] + [quo/page-top {:title (i18n/label :t/bridge)}] [quo/input {:container-style style/input-container :icon-name :i/search diff --git a/src/status_im/contexts/wallet/account/bridge_to/style.cljs b/src/status_im/contexts/wallet/account/bridge_to/style.cljs index 23a50e7d647..3ae18b2c990 100644 --- a/src/status_im/contexts/wallet/account/bridge_to/style.cljs +++ b/src/status_im/contexts/wallet/account/bridge_to/style.cljs @@ -1,9 +1,5 @@ (ns status-im.contexts.wallet.account.bridge-to.style) -(def header-container - {:padding-horizontal 20 - :padding-vertical 12}) - (def content-container {:padding-horizontal 8}) diff --git a/src/status_im/contexts/wallet/account/bridge_to/view.cljs b/src/status_im/contexts/wallet/account/bridge_to/view.cljs index bd3a5325b8e..af89424e46b 100644 --- a/src/status_im/contexts/wallet/account/bridge_to/view.cljs +++ b/src/status_im/contexts/wallet/account/bridge_to/view.cljs @@ -43,17 +43,15 @@ tokens (:tokens account) mainnet (first network-details) layer-2-networks (rest network-details) - account-token (some #(when (= token-symbol (:symbol %)) %) tokens)] - - + account-token (some #(when (= token-symbol (:symbol %)) %) tokens) + bridge-to-title (i18n/label :t/bridge-to + {:name (string/upper-case (str (:name token)))})] [rn/view [account-switcher/view {:on-press #(rf/dispatch [:navigate-back-within-stack :wallet-bridge-to]) :icon-name :i/arrow-left :accessibility-label :top-bar}] - [quo/text-combinations - {:container-style style/header-container - :title (i18n/label :t/bridge-to {:name (string/upper-case (str (:name token)))})}] + [quo/page-top {:title bridge-to-title}] [rn/view style/content-container [bridge-token-component (assoc mainnet :network-name :t/mainnet) account-token]] diff --git a/src/status_im/contexts/wallet/account/tabs/view.cljs b/src/status_im/contexts/wallet/account/tabs/view.cljs index b9f675fe71a..194a0a9bfd2 100644 --- a/src/status_im/contexts/wallet/account/tabs/view.cljs +++ b/src/status_im/contexts/wallet/account/tabs/view.cljs @@ -19,8 +19,7 @@ :collectibles [collectibles/view {:collectibles collectible-list :on-collectible-press (fn [{:keys [id]}] - (rf/dispatch [:wallet/get-collectible-details id]) - (rf/dispatch [:navigate-to :wallet-collectible]))}] + (rf/dispatch [:wallet/get-collectible-details id]))}] :activity [activity/view] :permissions [empty-tab/view {:title (i18n/label :t/no-permissions) diff --git a/src/status_im/contexts/wallet/add_address_to_watch/style.cljs b/src/status_im/contexts/wallet/add_address_to_watch/style.cljs index b08c4128dae..4b8e3a6f007 100644 --- a/src/status_im/contexts/wallet/add_address_to_watch/style.cljs +++ b/src/status_im/contexts/wallet/add_address_to_watch/style.cljs @@ -1,9 +1,6 @@ (ns status-im.contexts.wallet.add-address-to-watch.style) -(def header-container - {:margin-horizontal 20 - :margin-top 12 - :margin-bottom 20}) +(def header-container {:padding-bottom 8}) (def scan {:margin-top 26}) diff --git a/src/status_im/contexts/wallet/add_address_to_watch/view.cljs b/src/status_im/contexts/wallet/add_address_to_watch/view.cljs index 4c455831f4f..65dd9a8972a 100644 --- a/src/status_im/contexts/wallet/add_address_to_watch/view.cljs +++ b/src/status_im/contexts/wallet/add_address_to_watch/view.cljs @@ -133,10 +133,11 @@ (clear-input)) :container-style {:z-index 2}} (i18n/label :t/continue)]} - [quo/text-combinations - {:container-style style/header-container - :title (i18n/label :t/add-address) - :description (i18n/label :t/enter-eth)}] + [quo/page-top + {:container-style style/header-container + :title (i18n/label :t/add-address) + :description :text + :description-text (i18n/label :t/enter-eth)}] [:f> address-input {:input-value input-value :validate validate diff --git a/src/status_im/contexts/wallet/collectible/view.cljs b/src/status_im/contexts/wallet/collectible/view.cljs index ca6a2934670..44a76f2cfcc 100644 --- a/src/status_im/contexts/wallet/collectible/view.cljs +++ b/src/status_im/contexts/wallet/collectible/view.cljs @@ -99,7 +99,7 @@ :label (i18n/label :t/share-collectible) :right-icon :i/external}]]])) -(defn view-internal +(defn f-view-internal [{:keys [theme] :as _props}] (let [selected-tab (reagent/atom :overview) on-tab-change #(reset! selected-tab %)] @@ -116,6 +116,10 @@ {collection-image :image-url collection-name :name} collection-data {collectible-name :name} collectible-data] + (rn/use-effect + (fn [] + #(rf/dispatch [:wallet/clear-last-collectible-details])) + []) [scroll-page/scroll-page {:navigate-back? true :height 148 @@ -177,4 +181,8 @@ :data tabs-data}] [tabs/view {:selected-tab @selected-tab}]]])))) +(defn- view-internal + [props] + [:f> f-view-internal props]) + (def view (quo.theme/with-theme view-internal)) diff --git a/src/status_im/contexts/wallet/create_account/edit_derivation_path/component_spec.cljs b/src/status_im/contexts/wallet/create_account/edit_derivation_path/component_spec.cljs index 4216ad33836..79b5387bd16 100644 --- a/src/status_im/contexts/wallet/create_account/edit_derivation_path/component_spec.cljs +++ b/src/status_im/contexts/wallet/create_account/edit_derivation_path/component_spec.cljs @@ -3,13 +3,9 @@ [status-im.contexts.wallet.create-account.edit-derivation-path.view :as edit-derivation-path] [test-helpers.component :as h])) -(defn- render - [component] - (h/render-with-theme-provider component :light)) - (h/describe "Edit derivation path page" (h/test "Default render" - (render [edit-derivation-path/view {}]) + (h/render-with-theme-provider [edit-derivation-path/view {}]) (h/is-truthy (h/get-by-translation-text :t/edit-derivation-path)) (h/is-truthy (h/get-by-translation-text :t/path-format)) (h/is-truthy (h/get-by-translation-text :t/derivation-path)) @@ -19,14 +15,14 @@ (h/test "Reveal address pressed" (let [on-reveal (h/mock-fn)] - (render [edit-derivation-path/view {:on-reveal on-reveal}]) + (h/render-with-theme-provider [edit-derivation-path/view {:on-reveal on-reveal}]) (h/fire-event :press (h/get-by-translation-text :t/reveal-address)) (h/was-called on-reveal) (h/wait-for #(h/is-truthy (h/get-by-translation-text :t/address-activity))))) (h/test "Reset button pressed" (let [on-reset (h/mock-fn)] - (render [edit-derivation-path/view {:on-reset on-reset}]) + (h/render-with-theme-provider [edit-derivation-path/view {:on-reset on-reset}]) (h/fire-event :press (h/get-by-translation-text :t/reset)) (h/was-called on-reset) (h/wait-for #(h/is-truthy (h/get-by-translation-text :t/derive-addresses)))))) diff --git a/src/status_im/contexts/wallet/create_account/new_keypair/backup_recovery_phrase/style.cljs b/src/status_im/contexts/wallet/create_account/new_keypair/backup_recovery_phrase/style.cljs index 70cc607bd90..56c00b88216 100644 --- a/src/status_im/contexts/wallet/create_account/new_keypair/backup_recovery_phrase/style.cljs +++ b/src/status_im/contexts/wallet/create_account/new_keypair/backup_recovery_phrase/style.cljs @@ -4,10 +4,6 @@ [quo.theme :as quo.theme] [react-native.platform :as platform])) -(def header-container - {:margin-horizontal 20 - :margin-vertical 12}) - (defn seed-phrase-container [theme] {:margin-horizontal 20 diff --git a/src/status_im/contexts/wallet/create_account/new_keypair/backup_recovery_phrase/view.cljs b/src/status_im/contexts/wallet/create_account/new_keypair/backup_recovery_phrase/view.cljs index ddb329ba32c..5db032f9fcf 100644 --- a/src/status_im/contexts/wallet/create_account/new_keypair/backup_recovery_phrase/view.cljs +++ b/src/status_im/contexts/wallet/create_account/new_keypair/backup_recovery_phrase/view.cljs @@ -1,11 +1,12 @@ (ns status-im.contexts.wallet.create-account.new-keypair.backup-recovery-phrase.view (:require + [clojure.string :as string] + [native-module.core :as native-module] [quo.core :as quo] [quo.theme :as quo.theme] [react-native.blur :as blur] [react-native.core :as rn] [reagent.core :as reagent] - [status-im.contexts.wallet.common.temp :as temp] [status-im.contexts.wallet.create-account.new-keypair.backup-recovery-phrase.style :as style] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -17,7 +18,7 @@ [quo/text {:style {:margin-left 4}} item]]) (defn- words-column - [words first-half?] + [{:keys [words first-half?]}] [rn/flat-list {:style {:padding-vertical 8} :data (if first-half? (subvec words 0 6) (subvec words 6)) @@ -34,31 +35,43 @@ :on-change #(swap! checked? assoc (keyword (str index)) %)}] [quo/text {:style {:margin-left 12}} (i18n/label item)]]) -(defn- view-internal +(defn- f-view [{:keys [theme]}] - (let [step-labels [:t/backup-step-1 :t/backup-step-2 :t/backup-step-3 - :t/backup-step-4] - checked? (reagent/atom - {:0 false - :1 false - :2 false - :3 false}) - revealed? (reagent/atom false) - {:keys [customization-color]} (rf/sub [:profile/profile])] + (let [step-labels [:t/backup-step-1 :t/backup-step-2 :t/backup-step-3 + :t/backup-step-4] + checked? (reagent/atom + {:0 false + :1 false + :2 false + :3 false}) + revealed? (reagent/atom false) + customization-color (rf/sub [:profile/customization-color]) + secret-phrase (reagent/atom []) + random-phrase (reagent/atom [])] (fn [] + (rn/use-effect + (fn [] + (native-module/get-random-mnemonic #(reset! secret-phrase (string/split % #"\s"))) + (native-module/get-random-mnemonic #(reset! random-phrase (string/split % #"\s"))))) [rn/view {:style {:flex 1}} [quo/page-nav {:icon-name :i/close :on-press #(rf/dispatch [:navigate-back]) :accessibility-label :top-bar}] - [quo/text-combinations - {:container-style style/header-container - :title (i18n/label :t/backup-recovery-phrase) - :description (i18n/label :t/backup-recovery-phrase-description)}] + [quo/page-top + {:title (i18n/label :t/backup-recovery-phrase) + :description :text + :description-text (i18n/label :t/backup-recovery-phrase-description)}] [rn/view {:style (style/seed-phrase-container theme)} - [words-column temp/secret-phrase true] - [rn/view {:style (style/separator theme)}] - [words-column temp/secret-phrase false] + (when (pos? (count @secret-phrase)) + [:<> + [words-column + {:words @secret-phrase + :first-half? true}] + [rn/view {:style (style/separator theme)}] + [words-column + {:words @secret-phrase + :first-half? false}]]) (when-not @revealed? [rn/view {:style style/blur-container} [blur/view (style/blur theme)]])] @@ -68,7 +81,8 @@ :padding-top 20}} [quo/text {:weight :semi-bold - :style {:margin-bottom 8}} (i18n/label :t/how-to-backup)] + :style {:margin-bottom 8}} + (i18n/label :t/how-to-backup)] [rn/flat-list {:data step-labels :render-fn step-item @@ -81,8 +95,9 @@ :button-one-label (i18n/label :t/i-have-written) :button-one-props {:disabled? (some false? (vals @checked?)) :customization-color customization-color - :on-press #(rf/dispatch [:navigate-to - :wallet-check-your-backup])}}] + :on-press #(rf/dispatch [:wallet/store-secret-phrase + {:secret-phrase @secret-phrase + :random-phrase @random-phrase}])}}] [quo/text {:size :paragraph-2 :style (style/description-text theme)} @@ -95,4 +110,8 @@ :on-press #(reset! revealed? true)} :container-style style/slide-button}])]))) +(defn view-internal + [params] + [:f> f-view params]) + (def view (quo.theme/with-theme view-internal)) diff --git a/src/status_im/contexts/wallet/create_account/new_keypair/check_your_backup/view.cljs b/src/status_im/contexts/wallet/create_account/new_keypair/check_your_backup/view.cljs index b20ee05cef2..7e89cfde597 100644 --- a/src/status_im/contexts/wallet/create_account/new_keypair/check_your_backup/view.cljs +++ b/src/status_im/contexts/wallet/create_account/new_keypair/check_your_backup/view.cljs @@ -4,7 +4,6 @@ [quo.theme :as quo.theme] [react-native.core :as rn] [reagent.core :as reagent] - [status-im.contexts.wallet.common.temp :as temp] [status-im.contexts.wallet.create-account.new-keypair.check-your-backup.style :as style] [utils.i18n :as i18n] [utils.re-frame :as rf])) @@ -31,7 +30,7 @@ (defn- cheat-warning [] - (let [{:keys [customization-color]} (rf/sub [:profile/profile])] + (let [customization-color (rf/sub [:profile/customization-color])] [:<> [quo/drawer-top {:title (i18n/label :t/do-not-cheat)}] [quo/text @@ -62,35 +61,41 @@ (defn- view-internal [] - (let [random-indices (random-selection) - quiz-index (reagent/atom 0) - incorrect-count (reagent/atom 0) - show-error? (reagent/atom false)] + (let [random-indices (random-selection) + quiz-index (reagent/atom 0) + incorrect-count (reagent/atom 0) + show-error? (reagent/atom false) + {:keys [secret-phrase random-phrase]} (rf/sub [:wallet/create-account])] (fn [] - (let [current-word-index (get random-indices (min @quiz-index (dec questions-count))) - current-word (get temp/secret-phrase current-word-index) - [options-r-0 options-r-1] (random-words-with-string temp/random-words current-word) - on-button-press (fn [word] - (if (= word current-word) - (do - (reset! quiz-index (inc @quiz-index)) - (reset! incorrect-count 0) - (reset! show-error? false)) - (do - (when (> @incorrect-count 0) - (rf/dispatch [:show-bottom-sheet - {:content cheat-warning}])) - (reset! incorrect-count (inc @incorrect-count)) - (reset! show-error? true))))] + (let [current-word-index (get random-indices + (min @quiz-index (dec questions-count))) + current-word (get secret-phrase current-word-index) + [options-row-0 options-row-1] (random-words-with-string random-phrase current-word) + on-button-press (fn [word] + (if (= word current-word) + (do + (when (< @quiz-index questions-count) + (reset! quiz-index (inc @quiz-index))) + (reset! incorrect-count 0) + (reset! show-error? false) + (when (= @quiz-index questions-count) + (rf/dispatch [:navigate-to + :wallet-keypair-name]))) + (do + (when (> @incorrect-count 0) + (rf/dispatch [:show-bottom-sheet + {:content cheat-warning}])) + (reset! incorrect-count (inc @incorrect-count)) + (reset! show-error? true))))] [rn/view {:style {:flex 1}} [quo/page-nav {:icon-name :i/arrow-left :on-press #(rf/dispatch [:navigate-back]) :accessibility-label :top-bar}] - [quo/text-combinations - {:container-style style/header-container - :title (i18n/label :t/check-your-backup) - :description (i18n/label :t/confirm-the-position)}] + [quo/page-top + {:title (i18n/label :t/check-your-backup) + :description :text + :description-text (i18n/label :t/confirm-the-position)}] [rn/flat-list {:data random-indices :render-fn (fn [num index] @@ -109,7 +114,7 @@ :else :disabled) - :word (get temp/secret-phrase num) + :word (get secret-phrase num) :number (inc num) :on-press #(when (= @quiz-index index) (reset! show-error? false))}]) @@ -119,9 +124,9 @@ [buttons-row {:on-press on-button-press :margin-bottom 12 - :options options-r-0}] + :options options-row-0}] [buttons-row {:on-press on-button-press - :options options-r-1}]]])))) + :options options-row-1}]]])))) (def view (quo.theme/with-theme view-internal)) diff --git a/src/status_im/contexts/wallet/create_account/new_keypair/keypair_name/style.cljs b/src/status_im/contexts/wallet/create_account/new_keypair/keypair_name/style.cljs new file mode 100644 index 00000000000..62f63984c08 --- /dev/null +++ b/src/status_im/contexts/wallet/create_account/new_keypair/keypair_name/style.cljs @@ -0,0 +1,11 @@ +(ns status-im.contexts.wallet.create-account.new-keypair.keypair-name.style) + +(def header-container + {:margin-horizontal 20 + :margin-vertical 12}) + +(def bottom-action + {:position :absolute + :bottom 12 + :left 0 + :right 0}) diff --git a/src/status_im/contexts/wallet/create_account/new_keypair/keypair_name/view.cljs b/src/status_im/contexts/wallet/create_account/new_keypair/keypair_name/view.cljs new file mode 100644 index 00000000000..9af50600549 --- /dev/null +++ b/src/status_im/contexts/wallet/create_account/new_keypair/keypair_name/view.cljs @@ -0,0 +1,40 @@ +(ns status-im.contexts.wallet.create-account.new-keypair.keypair-name.view + (:require + [quo.core :as quo] + [react-native.core :as rn] + [reagent.core :as reagent] + [status-im.contexts.wallet.create-account.new-keypair.keypair-name.style :as style] + [utils.i18n :as i18n] + [utils.re-frame :as rf])) + +(def keypair-name-max-length 15) + +(defn view + [] + (let [keypair-name (reagent/atom "")] + (fn [] + (let [customization-color (rf/sub [:profile/customization-color])] + [rn/view {:style {:flex 1}} + [quo/page-nav + {:icon-name :i/arrow-left + :on-press #(rf/dispatch [:navigate-back]) + :accessibility-label :top-bar}] + [quo/text-combinations + {:container-style style/header-container + :title (i18n/label :t/keypair-name) + :description (i18n/label :t/keypair-name-description)}] + [quo/input + {:container-style {:margin-horizontal 20} + :placeholder (i18n/label :t/keypair-name-input-placeholder) + :label (i18n/label :t/keypair-name) + :char-limit keypair-name-max-length + :on-change-text #(reset! keypair-name %)}] + [quo/bottom-actions + {:actions :one-action + :button-one-label (i18n/label :t/continue) + :button-one-props {:disabled? (or (zero? (count @keypair-name)) + (> (count @keypair-name) keypair-name-max-length)) + :customization-color customization-color + :on-press #(rf/dispatch [:wallet/new-keypair-continue + {:keypair-name @keypair-name}])} + :container-style style/bottom-action}]])))) diff --git a/src/status_im/contexts/wallet/create_account/select_keypair/style.cljs b/src/status_im/contexts/wallet/create_account/select_keypair/style.cljs index 9057d08f09f..61fa431ebdb 100644 --- a/src/status_im/contexts/wallet/create_account/select_keypair/style.cljs +++ b/src/status_im/contexts/wallet/create_account/select_keypair/style.cljs @@ -1,9 +1,7 @@ (ns status-im.contexts.wallet.create-account.select-keypair.style) (def header-container - {:margin-horizontal 20 - :margin-top 12 - :margin-bottom 20}) + {:margin-bottom 8}) (def bottom-action-container {:position :absolute diff --git a/src/status_im/contexts/wallet/create_account/select_keypair/view.cljs b/src/status_im/contexts/wallet/create_account/select_keypair/view.cljs index 1a283e2532d..6b192848660 100644 --- a/src/status_im/contexts/wallet/create_account/select_keypair/view.cljs +++ b/src/status_im/contexts/wallet/create_account/select_keypair/view.cljs @@ -42,8 +42,7 @@ [] (let [{:keys [public-key compressed-key customization-color]} (rf/sub [:profile/profile]) - display-name (first (rf/sub [:contacts/contact-two-names-by-identity - public-key])) + [display-name _] (rf/sub [:contacts/contact-two-names-by-identity public-key]) profile-with-image (rf/sub [:profile/profile-with-image]) profile-picture (profile.utils/photo profile-with-image)] [rn/view {:style {:flex 1}} @@ -51,29 +50,30 @@ {:icon-name :i/close :on-press #(rf/dispatch [:navigate-back]) :accessibility-label :top-bar}] - [quo/text-combinations - {:container-style style/header-container - :title (i18n/label :t/keypairs) - :description (i18n/label :t/keypairs-description) - :button-icon :i/add - :button-on-press #(rf/dispatch [:show-bottom-sheet - {:content keypair-options}]) - :customization-color customization-color}] + [quo/page-top + {:container-style style/header-container + :title (i18n/label :t/keypairs) + :title-right :action + :title-right-props {:icon :i/add + :customization-color customization-color + :on-press #(rf/dispatch + [:show-bottom-sheet {:content keypair-options}])} + :description :text + :description-text (i18n/label :t/keypairs-description)}] [quo/keypair - (merge - {:customization-color customization-color - :profile-picture profile-picture - :status-indicator false - :type :default-keypair - :stored :on-device - :on-options-press #(js/alert "Options pressed") - :action :selector - :blur? false - :details {:full-name display-name - :address (utils/get-shortened-compressed-key compressed-key)} - :accounts accounts - :container-style {:margin-horizontal 20 - :margin-vertical 8}})] + {:customization-color customization-color + :profile-picture profile-picture + :status-indicator false + :type :default-keypair + :stored :on-device + :on-options-press #(js/alert "Options pressed") + :action :selector + :blur? false + :details {:full-name display-name + :address (utils/get-shortened-compressed-key compressed-key)} + :accounts accounts + :container-style {:margin-horizontal 20 + :margin-vertical 8}}] [quo/bottom-actions {:actions :one-action :button-one-label (i18n/label :t/confirm-account-origin) diff --git a/src/status_im/contexts/wallet/create_account/view.cljs b/src/status_im/contexts/wallet/create_account/view.cljs index c9ca86bca07..37367b66c3a 100644 --- a/src/status_im/contexts/wallet/create_account/view.cljs +++ b/src/status_im/contexts/wallet/create_account/view.cljs @@ -10,7 +10,6 @@ [status-im.common.emoji-picker.utils :as emoji-picker.utils] [status-im.common.standard-authentication.core :as standard-auth] [status-im.constants :as constants] - [status-im.contexts.wallet.common.sheets.account-origin.view :as account-origin] [status-im.contexts.wallet.common.utils :as utils] [status-im.contexts.wallet.create-account.style :as style] [status-im.feature-flags :as ff] @@ -20,19 +19,16 @@ [utils.security.core :as security] [utils.string])) -(defn keypair-string - [full-name] - (let [first-name (utils/get-first-name full-name)] - (i18n/label :t/keypair-title {:name first-name}))) - -(defn get-keypair-data - [name derivation-path account-color] - [{:title (keypair-string name) - :image :avatar - :image-props {:full-name (utils.string/get-initials name 1) - :size :xxs - :customization-color account-color} - :action :button +(defn- get-keypair-data + [primary-name derivation-path account-color {:keys [keypair-name]}] + [{:title (or keypair-name (i18n/label :t/keypair-title {:name primary-name})) + :image (if keypair-name :icon :avatar) + :image-props (if keypair-name + :i/seed + {:full-name (utils.string/get-initials primary-name 1) + :size :xxs + :customization-color account-color}) + :action (when-not keypair-name :button) :action-props {:on-press #(ff/alert ::ff/wallet.edit-default-keypair (fn [] (rf/dispatch [:navigate-to :wallet-select-keypair]))) @@ -51,7 +47,7 @@ :description :text :description-props {:text (string/replace derivation-path #"/" " / ")}}]) -(defn- view-internal +(defn- f-view [] (let [top (safe-area/get-top) bottom (safe-area/get-bottom) @@ -64,80 +60,86 @@ derivation-path (reagent/atom (utils/get-derivation-path number-of-accounts)) {:keys [public-key]} (rf/sub [:profile/profile]) on-change-text #(reset! account-name %) - [primary-name _] (first (rf/sub [:contacts/contact-two-names-by-identity public-key])) + primary-name (first (rf/sub [:contacts/contact-two-names-by-identity public-key])) {window-width :width} (rn/get-window)] (fn [{:keys [theme]}] - [rn/view {:style {:flex 1}} - [quo/page-nav - {:type :no-title - :background :blur - :right-side [{:icon-name :i/info - :on-press #(rf/dispatch [:show-bottom-sheet - {:content account-origin/view}])}] - :icon-name :i/close - :on-press #(rf/dispatch [:navigate-back])}] - [quo/gradient-cover - {:customization-color @account-color - :container-style (style/gradient-cover-container top)}] - [rn/view - {:style style/account-avatar-container} - [quo/account-avatar - {:customization-color @account-color - :size 80 - :emoji @emoji - :type :default}] - [quo/button - {:size 32 - :type :grey - :background :photo - :icon-only? true - :on-press #(rf/dispatch [:emoji-picker/open - {:on-select (fn [selected-emoji] - (reset! emoji selected-emoji))}]) - :container-style style/reaction-button-container} :i/reaction]] - [quo/title-input - {:customization-color @account-color - :placeholder placeholder - :on-change-text on-change-text - :max-length constants/wallet-account-name-max-length - :blur? true - :disabled? false - :auto-focus true - :default-value @account-name - :container-style style/title-input-container}] - [quo/divider-line] - [rn/view - {:style style/color-picker-container} - [quo/text - {:size :paragraph-2 - :weight :medium - :style (style/color-label theme)} - (i18n/label :t/colour)] - [quo/color-picker - {: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)}}]] - [quo/divider-line] - [quo/category - {:list-type :settings - :label (i18n/label :t/origin) - :data (get-keypair-data primary-name @derivation-path @account-color)}] - [standard-auth/slide-button - {:size :size-48 - :track-text (i18n/label :t/slide-to-create-account) - :customization-color @account-color - :on-auth-success (fn [entered-password] - (rf/dispatch [:wallet/derive-address-and-add-account - {:sha3-pwd (security/safe-unmask-data entered-password) - :emoji @emoji - :color @account-color - :path @derivation-path - :account-name @account-name}])) - :auth-button-label (i18n/label :t/confirm) - ;; TODO (@rende11) Add this property when sliding button issue will fixed - ;; https://github.com/status-im/status-mobile/pull/18683#issuecomment-1941564785 - ;; :disabled? (empty? @account-name) - :container-style (style/slide-button-container bottom)}]]))) + (let [{:keys [new-keypair]} (rf/sub [:wallet/create-account])] + (rn/use-effect (fn [] #(rf/dispatch [:wallet/clear-new-keypair]))) + [rn/view {:style {:flex 1}} + [quo/page-nav + {:type :no-title + :background :blur + :right-side [{:icon-name :i/info}] + :icon-name :i/close + :on-press #(rf/dispatch [:navigate-back])}] + [quo/gradient-cover + {:customization-color @account-color + :container-style (style/gradient-cover-container top)}] + [rn/view + {:style style/account-avatar-container} + [quo/account-avatar + {:customization-color @account-color + :size 80 + :emoji @emoji + :type :default}] + [quo/button + {:size 32 + :type :grey + :background :photo + :icon-only? true + :on-press #(rf/dispatch [:emoji-picker/open + {:on-select (fn [selected-emoji] + (reset! emoji selected-emoji))}]) + :container-style style/reaction-button-container} :i/reaction]] + [quo/title-input + {:customization-color @account-color + :placeholder placeholder + :on-change-text on-change-text + :max-length constants/wallet-account-name-max-length + :blur? true + :disabled? false + :default-value @account-name + :container-style style/title-input-container}] + [quo/divider-line] + [rn/view + {:style style/color-picker-container} + [quo/text + {:size :paragraph-2 + :weight :medium + :style (style/color-label theme)} + (i18n/label :t/colour)] + [quo/color-picker + {: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)}}]] + [quo/divider-line] + [quo/category + {:list-type :settings + :label (i18n/label :t/origin) + :data (get-keypair-data primary-name @derivation-path @account-color new-keypair)}] + [standard-auth/slide-button + {:size :size-48 + :track-text (i18n/label :t/slide-to-create-account) + :customization-color @account-color + :on-auth-success (fn [entered-password] + (if new-keypair + (js/alert "Feature under development") + (rf/dispatch [:wallet/derive-address-and-add-account + {:sha3-pwd (security/safe-unmask-data + entered-password) + :emoji @emoji + :color @account-color + :path @derivation-path + :account-name @account-name}]))) + :auth-button-label (i18n/label :t/confirm) + ;; TODO (@rende11) Add this property when sliding button issue will fixed + ;; https://github.com/status-im/status-mobile/pull/18683#issuecomment-1941564785 + ;; :disabled? (empty? @account-name) + :container-style (style/slide-button-container bottom)}]])))) + +(defn- view-internal + [] + [:f> f-view]) (def view (quo.theme/with-theme view-internal)) diff --git a/src/status_im/contexts/wallet/effects.cljs b/src/status_im/contexts/wallet/effects.cljs index cad9a4680b1..7c4037b17c1 100644 --- a/src/status_im/contexts/wallet/effects.cljs +++ b/src/status_im/contexts/wallet/effects.cljs @@ -1,7 +1,19 @@ (ns status-im.contexts.wallet.effects - (:require [re-frame.core :as rf] - [react-native.share :as share])) + (:require + [clojure.string :as string] + [native-module.core :as native-module] + [re-frame.core :as rf] + [react-native.share :as share])) (rf/reg-fx :effects.share/open (fn [content] (share/open content))) + +(rf/reg-fx + :effects.wallet/create-account-from-mnemonic + (fn [{:keys [secret-phrase keypair-name]}] + (native-module/create-account-from-mnemonic + {:MnemonicPhrase (string/join " " secret-phrase)} + (fn [new-keypair] + (rf/dispatch [:wallet/new-keypair-created + {:new-keypair (assoc new-keypair :keypair-name keypair-name)}]))))) diff --git a/src/status_im/contexts/wallet/events.cljs b/src/status_im/contexts/wallet/events.cljs index 634fc5f45d5..29caad50302 100644 --- a/src/status_im/contexts/wallet/events.cljs +++ b/src/status_im/contexts/wallet/events.cljs @@ -386,3 +386,35 @@ {:title title :subject title :message content})]]})) + +(defn store-secret-phrase + [{:keys [db]} [{:keys [secret-phrase random-phrase]}]] + {:db (-> db + (assoc-in [:wallet :ui :create-account :secret-phrase] secret-phrase) + (assoc-in [:wallet :ui :create-account :random-phrase] random-phrase)) + :fx [[:dispatch-later [{:ms 20 :dispatch [:navigate-to :wallet-check-your-backup]}]]]}) + +(rf/reg-event-fx :wallet/store-secret-phrase store-secret-phrase) + + +(defn new-keypair-created + [{:keys [db]} [{:keys [new-keypair]}]] + {:db (assoc-in db [:wallet :ui :create-account :new-keypair] new-keypair) + :fx [[:dispatch [:navigate-back-to :wallet-create-account]]]}) + +(rf/reg-event-fx :wallet/new-keypair-created new-keypair-created) + +(defn new-keypair-continue + [{:keys [db]} [{:keys [keypair-name]}]] + (let [secret-phrase (get-in db [:wallet :ui :create-account :secret-phrase])] + {:fx [[:effects.wallet/create-account-from-mnemonic + {:secret-phrase secret-phrase + :keypair-name keypair-name}]]})) + +(rf/reg-event-fx :wallet/new-keypair-continue new-keypair-continue) + +(defn clear-new-keypair + [{:keys [db]}] + {:db (update-in db [:wallet :ui :create-account] dissoc :new-keypair)}) + +(rf/reg-event-fx :wallet/clear-new-keypair clear-new-keypair) diff --git a/src/status_im/contexts/wallet/events/collectibles.cljs b/src/status_im/contexts/wallet/events/collectibles.cljs index f287759f210..51578967387 100644 --- a/src/status_im/contexts/wallet/events/collectibles.cljs +++ b/src/status_im/contexts/wallet/events/collectibles.cljs @@ -56,7 +56,8 @@ (defn store-last-collectible-details [{:keys [db]} [collectible]] - {:db (assoc-in db [:wallet :last-collectible-details] collectible)}) + {:db (assoc-in db [:wallet :last-collectible-details] collectible) + :dispatch [:navigate-to :wallet-collectible]}) (rf/reg-event-fx :wallet/store-last-collectible-details store-last-collectible-details) @@ -126,3 +127,8 @@ (log/error "failed to get collectible details" {:event :wallet/get-collectible-details-done :response response}))))) + +(rf/reg-event-fx + :wallet/clear-last-collectible-details + (fn [{:keys [db]}] + {:db (update-in db [:wallet] dissoc :last-collectible-details)})) diff --git a/src/status_im/contexts/wallet/events_test.cljs b/src/status_im/contexts/wallet/events_test.cljs index 1813f58a4c0..3cec6a9845e 100644 --- a/src/status_im/contexts/wallet/events_test.cljs +++ b/src/status_im/contexts/wallet/events_test.cljs @@ -24,6 +24,38 @@ result-db (:db effects)] (is (match? result-db expected-db)))))) +(deftest store-secret-phrase + (let [db {} + props [{:secret-phrase "test-secret" :random-phrase "random-test"}] + expected-db {:wallet {:ui {:create-account {:secret-phrase "test-secret" + :random-phrase "random-test"}}}} + effects (events/store-secret-phrase {:db db} props) + result-db (:db effects)] + (is (match? result-db expected-db)))) + +(deftest new-keypair-created + (let [db {} + props [{:new-keypair "test-keypair"}] + expected-db {:wallet {:ui {:create-account {:new-keypair "test-keypair"}}}} + effects (events/new-keypair-created {:db db} props) + result-db (:db effects)] + (is (match? result-db expected-db)))) + +(deftest new-keypair-continue + (let [db {:wallet {:ui {:create-account {:secret-phrase "test-secret"}}}} + props [{:keypair-name "test-keypair"}] + expected-effects [[:effects.wallet/create-account-from-mnemonic + {:secret-phrase "test-secret" :keypair-name "test-keypair"}]] + effects (events/new-keypair-continue {:db db} props)] + (is (match? effects {:fx expected-effects})))) + +(deftest clear-new-keypair + (let [db {:wallet {:ui {:create-account {:new-keypair "test-keypair"}}}} + expected-db {:wallet {:ui {:create-account {}}}} + effects (events/clear-new-keypair {:db db})] + (is (match? (:db effects) expected-db)))) + + (deftest store-collectibles (testing "(displayable-collectible?) helper function" (let [expected-results [[true diff --git a/src/status_im/contexts/wallet/home/tabs/view.cljs b/src/status_im/contexts/wallet/home/tabs/view.cljs index 95669b4b8fb..e7c9428609d 100644 --- a/src/status_im/contexts/wallet/home/tabs/view.cljs +++ b/src/status_im/contexts/wallet/home/tabs/view.cljs @@ -16,6 +16,5 @@ :collectibles [collectibles/view {:collectibles collectible-list :on-collectible-press (fn [{:keys [id]}] - (rf/dispatch [:wallet/get-collectible-details id]) - (rf/dispatch [:navigate-to :wallet-collectible]))}] + (rf/dispatch [:wallet/get-collectible-details id]))}] [activity/view])])) diff --git a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs index ebccde8117d..bb03e6d4923 100644 --- a/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs +++ b/src/status_im/contexts/wallet/send/input_amount/component_spec.cljs @@ -60,19 +60,15 @@ :total-balance 100 :market-values-per-currency {:usd {:price 10}}}}) -(defn- render - [component] - (h/render-with-theme-provider component :light)) - (h/describe "Send > input amount screen" (h/setup-restorable-re-frame) (h/test "Default render" (h/setup-subs sub-mocks) - (render [input-amount/view - {:crypto-decimals 2 - :limit-crypto 250 - :initial-crypto-currency? false}]) + (h/render-with-theme-provider [input-amount/view + {:crypto-decimals 2 + :limit-crypto 250 + :initial-crypto-currency? false}]) (h/is-truthy (h/get-by-text "0")) (h/is-truthy (h/get-by-text "ETH")) (h/is-truthy (h/get-by-text "$0.00")) @@ -82,11 +78,11 @@ (h/test "Fill token input and confirm" (h/setup-subs sub-mocks) (let [on-confirm (h/mock-fn)] - (render [input-amount/view - {:on-confirm on-confirm - :crypto-decimals 10 - :limit-crypto 1000 - :initial-crypto-currency? false}]) + (h/render-with-theme-provider [input-amount/view + {:on-confirm on-confirm + :crypto-decimals 10 + :limit-crypto 1000 + :initial-crypto-currency? false}]) (h/fire-event :press (h/query-by-label-text :keyboard-key-1)) (h/fire-event :press (h/query-by-label-text :keyboard-key-2)) @@ -106,11 +102,11 @@ (h/setup-subs sub-mocks) (let [on-confirm (h/mock-fn)] - (render [input-amount/view - {:crypto-decimals 10 - :limit-crypto 1000 - :on-confirm on-confirm - :initial-crypto-currency? false}]) + (h/render-with-theme-provider [input-amount/view + {:crypto-decimals 10 + :limit-crypto 1000 + :on-confirm on-confirm + :initial-crypto-currency? false}]) (h/fire-event :press (h/query-by-label-text :keyboard-key-1)) (h/fire-event :press (h/query-by-label-text :keyboard-key-2)) @@ -128,9 +124,9 @@ (h/test "Try to fill more than limit" (h/setup-subs sub-mocks) - (render [input-amount/view - {:crypto-decimals 1 - :limit-crypto 1}]) + (h/render-with-theme-provider [input-amount/view + {:crypto-decimals 1 + :limit-crypto 1}]) (h/fire-event :press (h/query-by-label-text :keyboard-key-2)) (h/fire-event :press (h/query-by-label-text :keyboard-key-9)) @@ -140,10 +136,10 @@ (h/test "Switch from crypto to fiat and check limit" (h/setup-subs sub-mocks) - (render [input-amount/view - {:crypto-decimals 1 - :limit-crypto 1 - :on-confirm #()}]) + (h/render-with-theme-provider [input-amount/view + {:crypto-decimals 1 + :limit-crypto 1 + :on-confirm #()}]) (h/fire-event :press (h/query-by-label-text :keyboard-key-9)) (h/is-truthy (h/get-by-label-text :container-error)) diff --git a/src/status_im/contexts/wallet/send/select_address/style.cljs b/src/status_im/contexts/wallet/send/select_address/style.cljs index f462bcc9ea0..037f9cbd985 100644 --- a/src/status_im/contexts/wallet/send/select_address/style.cljs +++ b/src/status_im/contexts/wallet/send/select_address/style.cljs @@ -3,10 +3,6 @@ (def container {:flex 1}) -(def title-container - {:margin-horizontal 20 - :margin-vertical 12}) - (def tabs {:padding-top 20 :padding-bottom 12}) diff --git a/src/status_im/contexts/wallet/send/select_address/view.cljs b/src/status_im/contexts/wallet/send/select_address/view.cljs index 4d19c38a8e7..e376a37d109 100644 --- a/src/status_im/contexts/wallet/send/select_address/view.cljs +++ b/src/status_im/contexts/wallet/send/select_address/view.cljs @@ -160,9 +160,8 @@ :wallet-select-address}]) :customization-color color} (i18n/label :t/continue)])} - [quo/text-combinations + [quo/page-top {:title (i18n/label :t/send-to) - :container-style style/title-container :title-accessibility-label :title-label}] [address-input input-value input-focused?] [quo/divider-line] diff --git a/src/status_im/contexts/wallet/send/select_asset/view.cljs b/src/status_im/contexts/wallet/send/select_asset/view.cljs index 9420da669d3..991a64d44e2 100644 --- a/src/status_im/contexts/wallet/send/select_asset/view.cljs +++ b/src/status_im/contexts/wallet/send/select_asset/view.cljs @@ -69,9 +69,8 @@ {:icon-name :i/arrow-left :on-press on-close :switcher-type :select-account}] - [quo/text-combinations + [quo/page-top {:title (i18n/label :t/select-asset) - :container-style style/title-container :title-accessibility-label :title-label}] [quo/segmented-control {:size 32 diff --git a/src/status_im/contexts/wallet/share_address/style.cljs b/src/status_im/contexts/wallet/share_address/style.cljs index f4a108f6d0c..4e30e0b96d7 100644 --- a/src/status_im/contexts/wallet/share_address/style.cljs +++ b/src/status_im/contexts/wallet/share_address/style.cljs @@ -1,5 +1,3 @@ (ns status-im.contexts.wallet.share-address.style) -(def header-container - {:padding-horizontal 20 - :padding-vertical 12}) +(def header-container {:margin-bottom 8}) diff --git a/src/status_im/contexts/wallet/share_address/view.cljs b/src/status_im/contexts/wallet/share_address/view.cljs index f593b1de245..e306b1eeaa0 100644 --- a/src/status_im/contexts/wallet/share_address/view.cljs +++ b/src/status_im/contexts/wallet/share_address/view.cljs @@ -32,18 +32,18 @@ (defn- open-preferences [selected-networks] - (rf/dispatch [:show-bottom-sheet - {:theme :dark - :shell? true - :content - (fn [] - [network-preferences/view - {:blur? true - :selected-networks (set @selected-networks) - :on-save (fn [chain-ids] - (rf/dispatch [:hide-bottom-sheet]) - (reset! selected-networks (map #(get utils/id->network %) - chain-ids)))}])}])) + (let [on-save (fn [chain-ids] + (rf/dispatch [:hide-bottom-sheet]) + (reset! selected-networks (map utils/id->network chain-ids))) + sheet-content (fn [] + [network-preferences/view + {:blur? true + :selected-networks (set @selected-networks) + :on-save on-save}])] + (rf/dispatch [:show-bottom-sheet + {:theme :dark + :shell? true + :content sheet-content}]))) (defn view @@ -74,8 +74,7 @@ [quo/overlay {:type :shell} [rn/view {:flex 1 - :padding-top padding-top - :key :share-adress} + :padding-top padding-top} [quo/page-nav {:icon-name :i/close :on-press #(rf/dispatch [:navigate-back]) @@ -83,9 +82,9 @@ :right-side [{:icon-name :i/scan :on-press #(js/alert "To be implemented")}] :accessibility-label :top-bar}] - [quo/text-combinations - {:container-style style/header-container - :title title}] + [quo/page-top + {:title title + :container-style style/header-container}] [rn/view {:style {:padding-horizontal 20}} [quo/share-qr-code {:type (if watch-only? :watched-address :wallet) diff --git a/src/status_im/navigation/screens.cljs b/src/status_im/navigation/screens.cljs index b7fd909b87b..eda7697b444 100644 --- a/src/status_im/navigation/screens.cljs +++ b/src/status_im/navigation/screens.cljs @@ -16,6 +16,7 @@ addresses-for-permissions] [status-im.contexts.communities.actions.airdrop-addresses.view :as airdrop-addresses] [status-im.contexts.communities.actions.request-to-join.view :as join-menu] + [status-im.contexts.communities.actions.share-community-channel.view :as share-community-channel] [status-im.contexts.communities.discover.view :as communities.discover] [status-im.contexts.communities.overview.view :as communities.overview] [status-im.contexts.onboarding.create-password.view :as create-password] @@ -63,6 +64,7 @@ wallet-backup-recovery-phrase] [status-im.contexts.wallet.create-account.new-keypair.check-your-backup.view :as wallet-check-your-backup] + [status-im.contexts.wallet.create-account.new-keypair.keypair-name.view :as wallet-keypair-name] [status-im.contexts.wallet.create-account.select-keypair.view :as wallet-select-keypair] [status-im.contexts.wallet.create-account.view :as wallet-create-account] [status-im.contexts.wallet.edit-account.view :as wallet-edit-account] @@ -114,6 +116,10 @@ :options {:sheet? true} :component join-menu/view} + {:name :share-community-channel + :options options/transparent-screen-options + :component share-community-channel/view} + {:name :community-account-selection :options {:sheet? true} :component communities.accounts-selection/view} @@ -372,6 +378,10 @@ :options {:insets {:top? true :bottom? true}} :component wallet-check-your-backup/view} + {:name :wallet-keypair-name + :options {:insets {:top? true :bottom? true}} + :component wallet-keypair-name/view} + {:name :wallet-share-address :options options/transparent-screen-options :component wallet-share-address/view} diff --git a/src/status_im/subs/chats.cljs b/src/status_im/subs/chats.cljs index c19a4c09c0e..3dd2243a900 100644 --- a/src/status_im/subs/chats.cljs +++ b/src/status_im/subs/chats.cljs @@ -221,6 +221,16 @@ :community-id :emoji]))) +(re-frame/reg-sub + :chats/community-channel-ui-details-by-id + :<- [:chats/chats] + (fn [chats [_ chat-id]] + (select-keys + (get chats chat-id) + [:chat-name + :color + :emoji]))) + (re-frame/reg-sub :chats/current-chat-message-list-view-context :<- [:chats/current-chat-chat-view] diff --git a/src/status_im/subs/chats_test.cljs b/src/status_im/subs/chats_test.cljs index c2be6510e6e..060675bba0a 100644 --- a/src/status_im/subs/chats_test.cljs +++ b/src/status_im/subs/chats_test.cljs @@ -161,3 +161,19 @@ (is (not (:can-delete-message-for-everyone? (rf/sub [sub-name])))) (is (not (:group-admin? (rf/sub [sub-name])))) (is (not (:message-pin-enabled (rf/sub [sub-name]))))))) + +(h/deftest-sub :chats/community-channel-ui-details-by-id + [sub-name] + (testing "returns specific ui details of a given community channel chat id" + (let [chats {chat-id (assoc community-chat + :color :army + :emoji "🍑" + :chat-name "test")}] + (swap! rf-db/app-db assoc + :chats + chats) + (let [result (rf/sub [sub-name chat-id])] + (is (= 3 (count (keys result)))) + (is (= :army (:color result))) + (is (= "test" (:chat-name result))) + (is (= "🍑" (:emoji result))))))) diff --git a/src/status_im/subs/communities.cljs b/src/status_im/subs/communities.cljs index 6cda8007d73..151c0778c11 100644 --- a/src/status_im/subs/communities.cljs +++ b/src/status_im/subs/communities.cljs @@ -330,6 +330,7 @@ highest-permission-role (:type highest-role) can-request-access? (and (boolean highest-permission-role) (not networks-not-supported?))] {:can-request-access? can-request-access? + :checking? checking? :highest-permission-role highest-permission-role :networks-not-supported? networks-not-supported? :no-member-permission? (and highest-permission-role diff --git a/src/status_im/subs/profile.cljs b/src/status_im/subs/profile.cljs index f022201cda1..517528a31c2 100644 --- a/src/status_im/subs/profile.cljs +++ b/src/status_im/subs/profile.cljs @@ -337,6 +337,18 @@ (fn [[{:keys [key-uid]} profiles]] (get profiles key-uid))) +(re-frame/reg-sub + :profile/login-processing + :<- [:profile/login] + (fn [{:keys [processing]}] + processing)) + +(re-frame/reg-sub + :profile/login-password + :<- [:profile/login] + (fn [{:keys [password]}] + password)) + ;; LINK PREVIEW ;; ======================================================================================================== diff --git a/src/status_im/subs/wallet/wallet.cljs b/src/status_im/subs/wallet/wallet.cljs index d10f2543561..ce9b5b705c6 100644 --- a/src/status_im/subs/wallet/wallet.cljs +++ b/src/status_im/subs/wallet/wallet.cljs @@ -38,6 +38,11 @@ :<- [:wallet/ui] :-> :tokens-loading?) +(rf/reg-sub + :wallet/create-account + :<- [:wallet/ui] + :-> :create-account) + (rf/reg-sub :wallet/current-viewing-account-address :<- [:wallet] diff --git a/status-go-version.json b/status-go-version.json index 5cf9022ca4b..f564d5274eb 100644 --- a/status-go-version.json +++ b/status-go-version.json @@ -3,7 +3,7 @@ "_comment": "Instead use: scripts/update-status-go.sh ", "owner": "status-im", "repo": "status-go", - "version": "v0.174.8", - "commit-sha1": "8a3e71378f7208f75bd688c02b0ae5c43ca600f2", - "src-sha256": "10wn93xn6xnkg2d8slyygy9rfrwiargm49738bdjj1g4b81220bq" + "version": "v0.175.1", + "commit-sha1": "cba3ac570337404e71da0db424d658b6c29f7ad9", + "src-sha256": "186hpv6lcj4189aa67jvg62gij1z5q42j1qxijijvf3kqnvd4lmq" } diff --git a/test/appium/views/chat_view.py b/test/appium/views/chat_view.py index d4cbaafc919..25ea010b090 100644 --- a/test/appium/views/chat_view.py +++ b/test/appium/views/chat_view.py @@ -1242,8 +1242,13 @@ def send_images_with_description(self, description, indexes=None): self.show_images_button.click() self.allow_button.click_if_shown() self.allow_all_button.click_if_shown() - [self.get_image_by_index(i).click() for i in indexes] - self.images_confirm_selection_button.click() + confirm_button = self.images_confirm_selection_button + for i in indexes: + # ToDo: should be changed to just 1 click when https://github.com/status-im/status-mobile/issues/18872 when is fixed + self.get_image_by_index(i).click() + if not confirm_button.is_element_displayed(sec=3): + self.get_image_by_index(i).click() + confirm_button.click() self.chat_message_input.send_keys(description) self.send_message_button.click() diff --git a/translations/en.json b/translations/en.json index ae887020767..3e183d64837 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1260,6 +1260,7 @@ "scan-or-enter-sync-code": "Scan or enter sync code", "scan-qr": "Scan QR", "scan-qr-code": "Scan QR code", + "scan-with-status-app": "Scan with the Status app on another device", "invalid-qr": "Oops! This QR doesn’t work with Status", "search": "Search", "search-discover-communities": "Search communities or categories", @@ -2512,5 +2513,9 @@ "origin-desc": "Origin is where your key pair (your private and public key) comes from. You can generate a new key pair or import an existing private key.", "derivation-path-header": "Derivation path", "derivation-path-desc": "Derivation paths are the routes your Status Wallet uses to generate addresses from your private key.", - "select-networks": "Select networks" + "select-networks": "Select networks", + "generating-keypair": "Generating keypair...", + "keypair-name": "Keypair name", + "keypair-name-description": "Name keypair for your own personal reference", + "keypair-name-input-placeholder": "Collectibles account, Old vault...." }