Compare commits

..
Author SHA1 Message Date
Icaro Motta 8abc93f250 WIP Refactoring subscription 2024-02-22 13:03:35 -03:00
Flavio Fraschetti c3ef8729d0 [WIP] Debbuging session 2024-02-22 10:57:43 +00:00
Flavio Fraschetti 145432860a checkpoint-tests 2024-02-21 18:49:22 +00:00
Flavio Fraschetti 5de5b3e225 improve :community/token-permissions subscription 2024-02-21 18:49:21 +00:00
Flavio Fraschetti 3f74c0f930 adapt collectible-tag schema 2024-02-21 18:49:21 +00:00
Flavio Fraschetti b2ce99c4ae lint-fix 2024-02-21 18:49:21 +00:00
Flavio Fraschetti efa9d9c7e4 pass data to bottom-sheet 2024-02-21 18:49:20 +00:00
Flavio Fraschetti ecfd80f6fc implement :community/token-permissions subscription 2024-02-21 18:49:20 +00:00
Flavio Fraschetti ce798ecafe add :communities/token-permissions test 2024-02-21 18:49:19 +00:00
Flavio Fraschetti a02cf6993e checkpoint before refactor/add subscriptions 2024-02-21 18:49:19 +00:00
Flavio Fraschetti 5cc1685619 [WIP] checkpoint before implement Quo Collectible Tag 2024-02-21 18:49:14 +00:00
Siddarth Kumar 3c12ac870a chore: fix few outdated things in docs & readme (#18920) 2024-02-22 00:17:09 +05:30
Paul Fitzgerald 321ff9257b feat(communities): add feature to share community channel qr code (#18807) 2024-02-21 05:59:04 -08:00
Omar Basem 28f43acb83 feat: new keypair: mnemonic, address, KP name screen (#18790)
feat: new keypair: mnemonic, address, KP name screen (#18790)
2024-02-21 15:53:14 +04:00
Andrea Maria Piana cfaed80066 dont display previous state when checking 2024-02-21 11:17:45 +00:00
Ulises Manuel fa9b53854b [#18463] Wallet - Page top refactor (#18755)
* Use page-top in bridge screen

* Use page-top in bridge-to screen

* Use page-top in add-address-to-watch screen

* Use page-top in backup-recovery-phrase screen

* Use page-top in check-your-backup screen

* Add support for title right options to page-top

* Use page-top in check-your-backup screen

* Use page-top in send-to screen

* Use page-top in select-asset screen

* Use page-top in :wallet-share-address screen

* Deprecate text-combinations
2024-02-20 23:24:17 -06:00
Ulises Manuel 680bc33971 [#18545] Add missing linear gradient to dark themed cards (#18689)
* Add missing linear gradient to cards dark themed cards
- Fix the `:ellipsis-mode` property
- Simplify code
2024-02-20 17:29:34 -06:00
mmilad75 c7aa10c789 The last collectible is shown for a moment while opening a new collectible #18750 (#18793)
* fix issue

* move navigation to the event

* move clearing to hook

* revert scroll_page

* resolve comment

* fix duplicate navigation
2024-02-20 18:34:33 +03:30
Ajay Sivan ae08cb161f Check eligibility status after enabling the share all addresses toggle 2024-02-20 14:45:46 +00:00
Volodymyr Kozieiev ae75eaeb33 Link to Malli presentation added to docs (#18849) 2024-02-20 12:43:44 +00:00
Parvesh Monu 424bbc39c4 cleanup leftovers (#18907) 2024-02-20 14:32:03 +05:30
Siddarth Kumar 5a7bfc61cc fix: make run-ios-device script (#18845)
fixes #16310

We used to reply on `react-native cli` and would pass a `--device` flag to deploy the debug variant of `iOS` app on connected `iPhone`.
`react-native cli` under the hood uses `ios-deploy` library to achieve this functionality.
This showed many weird issues, specifically in locating connected devices and failures at build step with ambiguous error messages.

This commit fixes it by using our custom script `run-ios-devices.sh` which does not rely on `ios-deploy`.
We use `libimobiledevice` to identify `UDID` of a connected `iPhone`.
We use `xcrun devicectl device install app` and `xcrun devicectl device process launch` to install and launch the app.

This works well with `Xcode 15` and `iOS 17.x`.
We can now remove `ios-deploy` from `iOS` shell and `nix` overlay.
We also set up a logs folder and add a Readme.

## Review notes

- connect your iPhone to your Laptop via a cable
- `make run-clojure`
- `make run-ios-device`
(note: no need to pass device name now)

## Platforms
- iOS
2024-02-20 10:54:09 +05:30
yqrashawn 50f6c1ef1b fix: password input triggers re-render of whole login view (#18728) 2024-02-20 10:11:22 +08:00
Siddarth Kumar 3c6b38aeea fix: improve iOS simulator selection (#18880)
## Summary

Improve iOS Simulator selection via `make run-ios` command.
Currently : `make run-ios SIMULATOR="iPhone SE (3rd generation)"` would fail because of our scripts inability to deal with this kind of a pattern.

This commit fixes that and makes this script more robust by storing output of `xcrun simctl list devices` in a json file `ios_simulators_list.json` and then using `jq` to properly get `UDIDs` of those simulators.

This script will now also prompt you to download a simulator image if you do not already have it.

The file `ios_simulators_list.json` will also help in future debugging when we want to check a quick summary of iOS simulator status of devs in the future.

We also append `-verbose` to `xcodebuild` for debug `iOS` builds, this helps debugging.

## Review notes
try such options -> `make run-ios SIMULATOR="iPhone SE (3rd generation)"`

## Platform 
- iOS
2024-02-20 07:16:54 +05:30
Siddarth Kumar c44ba69676 fix: we need to tunnel 8081 for connected devices (#18862)
`make run-android` would fail for connected Android devices because the android device was not able to talk to metro bundler.
This was discovered by @J-Son89
This was easily fixed by reverse tcping port 8081.

## Review notes
connect Android device by USB or Wifi
- `make run-clojure`
- `make run-android`
status app must run without any errors on the connected Android device.

we also replace during install on emulator.

otherwise on old emulators `make run-android` fails with :

```
adb: failed to install ./result/app-debug.apk: Failure [INSTALL_FAILED_ALREADY_EXISTS: Attempt to re-install im.status.ethereum.debug without first uninstalling.]
```
2024-02-20 00:52:29 +05:30
Parvesh Monu f394fcc3d5 fix android hardware back button is not working for nested sheet-screens (#18886) 2024-02-19 22:42:34 +05:30
Siddarth Kumar 107f263fb1 chore: improve android & iOS build step (#18900)
fixes #18888

## Summary
`make run-android` was sometimes flaky because we used to send metro to background via `nohup` and then bring it back to foreground after we read metro logs.

Now we do not send metro to background. We first wait for a successful build.
we then install the app on the simulator. After this is done we give command to sleep until metro server has started, Once metro server has started we open the installed app.

In this workflow the command to open the installed app goes in background and metro stays in foreground.
The new workflow should now be less flaky.

## Review notes
`make run-clojure`
`make run-android` OR `make run-ios` should just work 

#### Platforms
- Android
- iOS
2024-02-19 21:11:36 +05:30
Ajay Sivan 678bc548ca Use quo/bottom-actions component in addresses for permissions screen (#18863) 2024-02-19 07:06:35 -08:00
mmilad75 d77033e346 Wallet - Add malli spec to Quo Wallet components (batch 3) (#18783)
* draft

* add account_card

* add account-origin

* add account_overview

* add account_permission

* add address_text

* add confirmation_progress

* wrapping up

* resolve comments and fix ci issues

* fix ci issues

* fix transaction_progress tests

* fix all tests

* fix lint issues

* add network-link

* add token-input

* add wallet-overview

* add context-tag

* add wallet-activity

* add transaction-progress

* add transaction-summary

* add default value to render-with-theme-provider

* draft

* add default value to context-tag schema

* fix lint issues

* resolve comments

* add :string type to image type

* update ?image-source schema
2024-02-19 18:01:07 +03:30
Parvesh Monu 8f85e3c726 fix first tap doesn't work when selecting a photo in the gallery (#18885) 2024-02-19 19:05:31 +05:30
Shivek Khurana ed427cf485 🧪 Extract schema to dedicated namespace (#18858)
* 🧪 Extract schema to dedicated namespace

* ✏️ Fix syntax errors and dep issue

* 🦞 Follow guidelines
2024-02-19 13:16:17 +00:00
BalogunofAfricaandLungu Cristian 9362d12bbd fix: communities review (#18634)
* fix: community tag emoji size

* fix: hide channel category sticky header for none

* fix line wrap

* fix formatting

* refactor emoji component for tags

---------

Co-authored-by: Lungu Cristian <lungucristian95@gmail.com>
2024-02-19 08:26:32 +01:00
Flavio Fraschetti bfed36d19f [Communities] Account selection: сan't see the entire text of the community rules (#18761)
Resolved the scrolling issue pertaining to community rules. Additionally, will ensure compatibility with iOS devices lacking safe-area-view in the follow-up.
2024-02-18 08:03:52 -03:00
Yevheniia Berdnyk 456ccb4c69 e2e: temp fix for image selection 2024-02-17 19:03:20 +02:00
Andrea Maria Piana be2c697b7c set light client 2024-02-16 16:30:44 +00:00
137 changed files with 2391 additions and 1406 deletions
+2 -2
View File
@@ -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
+4 -5
View File
@@ -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
+3 -3
View File
@@ -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
+2
View File
@@ -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)
+37 -22
View File
@@ -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
```
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.
Then build the clojure terminal
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.
```
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.
wait till you see the following message :
```
[: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`
+32 -6
View File
@@ -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
```
+1 -20
View File
@@ -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))
<details>
<summary>How to Find CPU architecture</summary>
CPU architecture of android device can be found using
- `adb shell uname -m` or
- `adb shell getprop ro.product.cpu.abilist`
</details>
### Solution
Disable Hermes while building the app
`make run-android DISABLE_HERMES=true`
+18
View File
@@ -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`.
@@ -342,4 +342,14 @@ public class AccountManager extends ReactContextBaseJavaModule {
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);
}
}
@@ -214,4 +214,20 @@ RCT_EXPORT_METHOD(logout) {
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
+1 -1
View File
@@ -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.
-12
View File
@@ -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 {
+16 -39
View File
@@ -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
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
}
trap cleanupMetro EXIT ERR INT QUIT
runMetro &
waitForMetro
showAdbLogs() {
cat "${ADB_INSTALL_LOG_FILE}" >&2;
cat "${ADB_SHELL_MONKEY_LOG_FILE}" >&2;
}
# Start the installed app.
adb shell monkey -p im.status.ethereum.debug 1
# bring metro job to foreground
fg 'runMetro'
trap showAdbLogs EXIT ERR INT QUIT
installAndLaunchApp &
exec "${GIT_ROOT}/scripts/run-metro.sh" 2>&1
+55
View File
@@ -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
+36 -46
View File
@@ -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"
# 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
# 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.
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
# fetch available iOS Simulators
xcrun simctl list devices -j > "${XCRUN_SIMULATOR_JSON_FILE}"
SIMULATOR=${1}
# get our desired UUID
UUID=$(xcrun simctl list devices | grep -E "$SIMULATOR \(" | head -n 1 | awk -F '[()]' '{print $2}')
# 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}")
# get simulator status
SIMULATOR_STATE=$(xcrun simctl list devices | grep -E "$SIMULATOR \(" | head -n 1 | awk '{print $NF}')
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
+14
View File
@@ -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
@@ -31,7 +31,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
+1 -1
View File
@@ -72,7 +72,7 @@
:PeerExchange true
:Port 0
:UDPPort 0
:LightClient true})
:LightClient false})
(def login-node-config
{:WalletConfig (cond-> {:Enabled true}
+10
View File
@@ -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 %))))
@@ -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)}
@@ -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
@@ -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"))
@@ -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?)
@@ -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))))
@@ -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..."))))
@@ -9,7 +9,7 @@
[:size {:optional true} [:maybe [:enum :size-24 :size-32]]]
[:blur? {:optional true} [:maybe :boolean]]
[:theme :schema.common/theme]
[:collectible-img-src :schema.common/image-source]
[:collectible-img-src [:maybe :schema.common/image-source :string]]
[:collectible-name :string]
[:collectible-id :string]]]]
[:collectible-id {:optional true} [:maybe :string]]]]]
:any])
@@ -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])
+5 -65
View File
@@ -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)))
+15 -9
View File
@@ -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))
@@ -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"))
@@ -12,7 +12,8 @@
:height 32})
(def header-title
{:flex-direction :row
{:flex 1
:flex-direction :row
:column-gap 8})
(def header-counter
@@ -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
@@ -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})
@@ -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}
@@ -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
+1 -1
View File
@@ -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
@@ -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]
@@ -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]]])
@@ -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]]
@@ -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])
@@ -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)))
@@ -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])
@@ -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)))
@@ -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])
@@ -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)))
@@ -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])
@@ -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)))
@@ -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])
@@ -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)))
@@ -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])
@@ -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)))
@@ -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])
@@ -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)))
@@ -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"))))
@@ -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])
@@ -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)))
@@ -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])
@@ -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)))
@@ -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))))
@@ -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])
@@ -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)))
@@ -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))))
@@ -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])
@@ -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)))
@@ -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"))))
@@ -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])
@@ -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)))
+3 -1
View File
@@ -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
+2 -1
View File
@@ -13,7 +13,8 @@
(def ^:private ?image-source
[:or
[:int]
:int
:string
[:map
[:uri [:maybe [:string]]]]])
@@ -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?}]]]]))))
+1 -1
View File
@@ -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
+5 -2
View File
@@ -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]
@@ -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?]}]
@@ -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
@@ -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]
@@ -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]
@@ -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}}]]))
@@ -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]]]}))
@@ -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])
@@ -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)})
@@ -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
@@ -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})
@@ -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]
[status-im.contexts.communities.actions.detail-token-gating.view :as detail-token-gating]
[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
@@ -69,8 +74,7 @@
:context-tag-type :community
:community-name name
:button-icon :i/info
:button-type :grey
:on-button-press not-implemented/alert
:on-button-press #(rf/dispatch [:show-bottom-sheet {:content detail-token-gating/view}])
:community-logo (get-in images [:thumbnail :uri])
:customization-color color}]
@@ -92,47 +96,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)]]]))))
@@ -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)))
@@ -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})
@@ -0,0 +1,10 @@
(ns status-im.contexts.communities.actions.detail-token-gating.style)
(def container
{:flex 1
:background-color :white})
(def highest-role
{:flex-direction :row
:padding-horizontal 22
:margin-bottom 8})
@@ -0,0 +1,56 @@
(ns status-im.contexts.communities.actions.detail-token-gating.view
(:require
[quo.core :as quo]
[react-native.core :as rn]
[status-im.contexts.communities.actions.detail-token-gating.style :as style]
[status-im.contexts.communities.utils :as communities.utils]
[utils.i18n :as i18n]
[utils.re-frame :as rf]))
(defn view
[]
(let [{id :community-id} (rf/sub [:get-screen-params])
{:keys [highest-permission-role can-request-access?]}
(rf/sub [:community/token-gated-overview id])
token-permissions (rf/sub [:community/token-permissions id])
tokens (get token-permissions 2)
token-master (get token-permissions 6)
token-master-name (:symbol (first (first token-master)))
token-master-img (:img-src (first (first token-master)))
highest-role-text
(i18n/label
(communities.utils/role->translation-key highest-permission-role :t/member))
member-role-text (communities.utils/role->translation-key (contains? token-permissions 2)
:t/member)
selected-addresses (rf/sub [:communities/selected-permission-addresses id])]
(tap> ["token master" token-master])
[rn/view {:style style/container}
(when (and highest-permission-role (seq selected-addresses))
[rn/view
{:style style/highest-role}
[rn/view {:style {:flex-direction :column}}
[quo/text {:weight :medium}
(i18n/label :t/you-eligible-to-join-as {:role highest-role-text})]
[quo/text {:style {:padding-bottom 18} :size :paragraph-2}
(if can-request-access?
(i18n/label :t/you-hodl)
(i18n/label :t/you-must-hold))]
[rn/view {:style {:align-items :flex-start}}
(when token-master
[quo/collectible-tag
{:size :size-24
:collectible-name token-master-name
:options :hold
:collectible-img-src token-master-img}])]]])
[rn/view
{:style style/highest-role}
[rn/view {:style {:flex-direction :column :margin-top 12}}
[quo/text {:weight :medium}
(i18n/label :t/you-eligible-to-join-as {:role member-role-text})]
[quo/text {:style {:padding-bottom 18} :size :paragraph-2}
(if can-request-access?
(i18n/label :t/you-hodl)
(i18n/label :t/you-must-hold))]
[quo/token-requirement-list {:tokens tokens}]]]]))
@@ -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})
@@ -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)]]])))
+34 -19
View File
@@ -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]]
@@ -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]
@@ -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
@@ -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
@@ -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"
+1 -1
View File
@@ -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
@@ -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)}))
@@ -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
@@ -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]
@@ -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})

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