Compare commits

..
Author SHA1 Message Date
Andrea Maria Piana 5edbd0f31c Update snx/synth contract 2020-10-06 12:13:23 +02:00
andrey 9f0ba0f67e fixed custom tokens 2020-10-06 11:38:54 +02:00
andrey 4a0ad12f3a fixed keycard tokens 2020-10-06 10:44:21 +02:00
andrey e52706a48e fix lint 2020-10-06 09:25:39 +02:00
andrey 5d4f48662a do not request tokens for new account 2020-10-06 08:20:48 +02:00
andrey 619c589bc8 update token balances and prices when selecting token 2020-10-06 07:42:26 +02:00
andrey 31e18663bd fix token balances for account creation 2020-10-05 20:12:08 +02:00
jakub 2a21b6c142 fix availability of INFURA_TOKEN for Android build
The env variable `INFURA_TOKEN` is used at build time of JS bundle, not
the final APK file. We never passed the `secretsFile` to the
derivation for JS bundle so it never saw the `INFURA_TOKEN`.

Signed-off-by: Jakub Sokołowski <jakub@status.im>
2020-10-05 16:41:09 +02:00
andrey e1cbd3936f fix init wallet 2020-10-05 16:19:06 +02:00
andrey 99c6aa8512 fix js object 2020-10-05 14:48:50 +02:00
Andrea Maria Piana 2ad863a854 Bump version to 1.7.2 2020-10-05 13:11:42 +02:00
andrey c7ba1dea21 do not show zeros for token balances, and fetch all tokens only when creating new account 2020-10-05 13:10:08 +02:00
Andrea Maria Piana e4a65b3a23 Fix infura token
Setting a top-level closure-defines does not have any effect,
it needs to be for some reason inside each environment.
2020-10-05 13:08:50 +02:00
Andrea Maria Piana 385bf0d023 Add hotfix for wallet balance 2020-10-05 13:02:14 +02:00
Andrea Maria Piana 2d4638ab7f Fix migration when interrupted 2020-10-01 14:40:43 +02:00
andrey e40664533d override custom tokens
Signed-off-by: andrey <motor4ik@gmail.com>
2020-09-25 14:05:54 +02:00
Churikova Tetiana f152f8156f disable collectible e2e
Signed-off-by: andrey <motor4ik@gmail.com>
2020-09-25 14:05:53 +02:00
andrey b206a4e955 [#11218] Hard code fix for SUPR NFT support
Drop collectibles details support
2020-09-25 14:05:51 +02:00
andrey a18c429fee add images
Signed-off-by: andrey <motor4ik@gmail.com>
2020-09-25 14:05:51 +02:00
andrey 420e3f3586 [#11222] Add aUSDC token and optimize search for Aave (LEND) (aka Ethlend) 2020-09-25 14:05:50 +02:00
384 changed files with 5907 additions and 20185 deletions
+1 -1
View File
@@ -13,7 +13,7 @@ update_configs:
update_type: "security"
# Keep /mobile/js_files/yarn.lock up to date, batching pull requests weekly
- package_manager: "javascript"
directory: "/"
directory: "/mobile/js_files"
update_schedule: "weekly"
allowed_updates:
- match:
-3
View File
@@ -24,7 +24,4 @@ QR_READ_TEST_MENU=1
ENABLE_ROOT_ALERT=1
ENABLE_REFERRAL_INVITE=1
ENABLE_QUO_PREVIEW=1
MAX_IMAGES_BATCH=5
APN_TOPIC=im.status.ethereum.pr
COMMUNITIES_ENABLED=1
COMMUNITIES_MANAGEMENT_ENABLED=1
-4
View File
@@ -23,8 +23,4 @@ KEYCARD_TEST_MENU=1
QR_READ_TEST_MENU=1
ENABLE_ROOT_ALERT=0
ENABLE_REFERRAL_INVITE=1
MAX_IMAGES_BATCH=5
APN_TOPIC=im.status.ethereum.pr
VERIFY_TRANSACTION_CHAIN_ID=3
COMMUNITIES_ENABLED=1
COMMUNITIES_MANAGEMENT_ENABLED=0
-5
View File
@@ -23,8 +23,3 @@ ENABLE_ROOT_ALERT=1
ENABLE_REFERRAL_INVITE=1
DISABLE_WALLET_ON_MOBILE_NETWORK=1
APN_TOPIC=im.status.ethereum.pr
BLANK_PREVIEW=0
MAX_IMAGES_BATCH=5
GOOGLE_FREE=0
COMMUNITIES_ENABLED=1
COMMUNITIES_MANAGEMENT_ENABLED=0
+1 -4
View File
@@ -17,7 +17,4 @@ RPC_NETWORKS_ONLY=0
PARTITIONED_TOPIC=0
CONTRACT_NODES=1
ENABLE_ROOT_ALERT=1
ENABLE_REFERRAL_INVITE=0
MAX_IMAGES_BATCH=5
BLANK_PREVIEW=0
COMMUNITIES_ENABLED=1
ENABLE_REFERRAL_INVITE=1
-1
View File
@@ -16,5 +16,4 @@ SNOOPY=0
RPC_NETWORKS_ONLY=1
PARTITIONED_TOPIC=0
ENABLE_ROOT_ALERT=1
MAX_IMAGES_BATCH=1
ENABLE_REFERRAL_INVITE=0
+11 -1
View File
@@ -5,6 +5,8 @@
# the repo. Unless a later match takes precedence,
# @global-owner1 and @global-owner2 will be requested for
# review when someone opens a pull request.
* @status-im/status-core
/ci @jakubgs
/fastlane @jakubgs
/scripts @jakubgs
@@ -22,4 +24,12 @@
/components @status-im/status-core-ui
/test/appium/ @churik
desktop/ @vkjr
modules/react-native-desktop*/ @vkjr
modules/react-native-desktop*/ @vkjr
/doc @oskarth @yenda @jeluard
/deployment @vkjr
/test/appium/ @antdanchenko @churik
-16
View File
@@ -1,16 +0,0 @@
name: Zenhub integration assigned
on:
issues:
types:
- assigned
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: status-im/zenhub-automations@master
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ZENHUB_API_KEY: ${{ secrets.ZENHUB_TOKEN }}
INPROG_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzMyODI1Mg
REVIEW_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzIyNjk0MTA
-14
View File
@@ -1,14 +0,0 @@
name: Zenhub integration branch
on:
create:
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: status-im/zenhub-automations@master
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ZENHUB_API_KEY: ${{ secrets.ZENHUB_TOKEN }}
INPROG_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzMyODI1Mg
REVIEW_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzIyNjk0MTA
-19
View File
@@ -1,19 +0,0 @@
name: Zenhub integration PR
on:
pull_request:
branches: [ develop ]
types:
- ready_for_review
- opened
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: status-im/zenhub-automations@master
if: github.event.pull_request.draft == false
with:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ZENHUB_API_KEY: ${{ secrets.ZENHUB_TOKEN }}
INPROG_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzMyODI1Mg
REVIEW_COLUMN: Z2lkOi8vcmFwdG9yL1BpcGVsaW5lLzIyNjk0MTA
-7
View File
@@ -127,17 +127,10 @@ _tmpdir-rm: SHELL := /bin/sh
_tmpdir-rm: ##@prepare Remove TMPDIR
rm -fr "$(TMPDIR)"
# Remove directories and ignored files
clean: SHELL := /bin/sh
clean: _fix-node-perms _tmpdir-rm ##@prepare Remove all output folders
git clean -dXf
# Remove directories, ignored and non-ignored files
purge: SHELL := /bin/sh
purge: _fix-node-perms _tmpdir-rm ##@prepare Remove all output folders
git clean -dxf
watchman-clean: export TARGET := watchman
watchman-clean: ##@prepare Delete repo directory from watchman
watchman watch-del $${STATUS_REACT_HOME}
+1 -1
View File
@@ -1 +1 @@
1.10.1
1.7.2
-5
View File
@@ -123,11 +123,6 @@ def jscFlavor = 'org.webkit:android-jsc:+'
*/
def enableHermes = project.ext.react.get("enableHermes", false);
/**
* Exclude google library so we can publish to external android stores
*/
def googleFree = project.env.get("GOOGLE_FREE", false)
def getVersionCode = { ->
new ByteArrayOutputStream().withStream { stdOut ->
if (project.hasProperty("versionCode")) {
-1
View File
@@ -75,7 +75,6 @@
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity"/>
<service android:name="im.status.ethereum.module.ForegroundService"></service>
<service android:name="im.status.ethereum.module.LocalNotificationsService" />
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
@@ -18,7 +18,6 @@ import java.util.List;
import im.status.ethereum.keycard.RNStatusKeycardPackage;
import im.status.ethereum.module.StatusPackage;
import im.status.ethereum.pushnotifications.PushNotificationPackage;
public class MainApplication extends MultiDexApplication implements ReactApplication {
@@ -31,12 +30,10 @@ public class MainApplication extends MultiDexApplication implements ReactApplica
@Override
protected List<ReactPackage> getPackages() {
StatusPackage statusPackage = new StatusPackage(RootUtil.isDeviceRooted());
List<ReactPackage> packages = new PackageList(this).getPackages();
packages.add(statusPackage);
packages.add(new ReactNativeDialogsPackage());
packages.add(new RNStatusKeycardPackage());
packages.add(new PushNotificationPackage());
return packages;
}
+5 -7
View File
@@ -1,4 +1,4 @@
library 'status-react-jenkins@v1.2.8'
library 'status-react-jenkins@v1.2.5'
pipeline {
agent { label 'linux' }
@@ -101,14 +101,12 @@ pipeline {
} else { /* if no universal is available pick first */
env.PKG_URL = urls.first()
}
jenkins.setBuildDesc(APK: env.PKG_URL)
/* e2e builds get tested in SauceLabs */
if (utils.isE2EBuild()) {
env.SAUCE_URL = android.uploadToSauceLabs()
}
if (utils.isNightlyBuild()) {
env.DIAWI_URL = android.uploadToDiawi()
}
if (utils.isE2EBuild()) {
env.SAUCE_URL = android.uploadToSauceLabs()
}
}
}
}
@@ -116,7 +114,7 @@ pipeline {
}
stage('Cleanup') {
steps {
sh 'make purge'
sh 'make clean'
}
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-react-jenkins@v1.2.8'
library 'status-react-jenkins@v1.2.5'
pipeline {
agent { label 'linux' }
+3 -4
View File
@@ -1,4 +1,4 @@
library 'status-react-jenkins@v1.2.8'
library 'status-react-jenkins@v1.2.5'
pipeline {
agent { label 'macos-xcode-11.5' }
@@ -99,9 +99,8 @@ pipeline {
steps {
script {
env.PKG_URL = s3.uploadArtifact(api)
jenkins.setBuildDesc(IPA: env.PKG_URL)
/* e2e builds get tested in SauceLabs */
if (utils.isE2EBuild()) {
if (btype == 'e2e') {
env.SAUCE_URL = ios.uploadToSauceLabs()
} else {
env.DIAWI_URL = ios.uploadToDiawi()
@@ -114,7 +113,7 @@ pipeline {
stage('Cleanup') {
steps {
sh 'make watchman-clean'
sh 'make purge'
sh 'make clean'
}
}
}
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-react-jenkins@v1.2.8'
library 'status-react-jenkins@v1.2.5'
pipeline {
agent { label params.AGENT_LABEL }
+3 -9
View File
@@ -44,19 +44,13 @@ pipeline {
credentialsId: 'etherscan-api-key',
variable: 'ETHERSCAN_API_KEY'
),
string(
credentialsId: 'infura-e2e-token',
variable: 'WEB3_INFURA_PROJECT_ID'
),
]) {
dir('test/appium/tests') {
sh """
python3 -m pytest \
--numprocesses 15 \
--rerun_count=2 \
--testrail_report=True \
-m testrail_id \
python3 -m pytest -m testrail_id \
-m "not upgrade" \
-n24 --rerun_count=2 \
--testrail_report=True \
--network=${params.NETWORK} \
--apk=${params.APK_NAME}
"""
+1 -6
View File
@@ -80,15 +80,10 @@ pipeline {
credentialsId: 'etherscan-api-key',
variable: 'ETHERSCAN_API_KEY'
),
string(
credentialsId: 'infura-e2e-token',
variable: 'WEB3_INFURA_PROJECT_ID'
),
]) {
dir('test/appium/tests') {
sh """
python3 -m pytest \
--numprocesses 15 \
python3 -m pytest -n24 \
--rerun_count=2 \
--testrail_report=True \
-m "${params.TEST_MARKERS}" \
+2 -8
View File
@@ -48,17 +48,11 @@ pipeline {
credentialsId: 'etherscan-api-key',
variable: 'ETHERSCAN_API_KEY'
),
string(
credentialsId: 'infura-e2e-token',
variable: 'WEB3_INFURA_PROJECT_ID'
),
]) {
dir('test/appium/tests') {
sh """
python3 -m pytest \
-m upgrade \
--numprocesses 15 \
--rerun_count=2 \
python3 -m pytest -m upgrade \
-n24 --rerun_count=2 \
--testrail_report=True \
--network=${params.NETWORK} \
--apk=${params.APK_NAME} \
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-react-jenkins@v1.2.8'
library 'status-react-jenkins@v1.2.5'
pipeline {
agent { label 'macos' }
+1 -1
View File
@@ -1,4 +1,4 @@
library 'status-react-jenkins@v1.2.8'
library 'status-react-jenkins@v1.2.5'
pipeline {
agent { label 'linux' }
-94
View File
@@ -1,94 +0,0 @@
# Description
This document describes how to update Status APK builds for the [F-Droid](https://f-droid.org/) Android application catalogue.
# Intro
In simplest terms F-Droid requires a YAML file that defines the steps necessary to create a universal unsigned APK build. This is achieved by submitting a new app versions into the `metadata/im.status.ethereum.yml` file in the [fdroiddata](https://gitlab.com/fdroid/fdroiddata) repository.
The app builds defined this way run on servers that generate the unsigned APKs using the [fdroidserver](https://gitlab.com/fdroid/fdroidserver) software. The [server setup](https://f-droid.org/en/docs/Build_Server_Setup/) is quite involved but is not necessary unless you want to run your own instance. Normally the applications defines in `fdroiddata` are built by servers maintained by [the F-Droid volunteers](https://f-droid.org/en/contribute/).
First release of Status app was merged in [fdroid/fdroiddata#7179](https://gitlab.com/fdroid/fdroiddata/-/merge_requests/7179).
# Adding New Versions
You can find our configuration file at [`metadata/im.status.ethereum.yml`](https://gitlab.com/fdroid/fdroiddata/-/blob/master/metadata/im.status.ethereum.yml)
The file defines all the necessary metadata like `SourceCode`, `Website`, or `License`, but the most important key is `Builds`, which looks like this:
```yml
Builds:
- versionName: 1.4.1
versionCode: 2020070112
commit: cfb825a11b61d312af8cb5d36686af540c31f481
sudo:
- mkdir -m 0755 /nix
- chown vagrant /nix
init: ./nix/scripts/setup.sh
output: ./result/app-release-unsigned.apk
scanignore:
- android/build.gradle
scandelete:
- ios
build: make release-android BUILD_TYPE=release BUILD_NUMBER=2020070112 ANDROID_APK_SIGNED=false
```
It contains a list of objects defining each release of the application. In order to add a new release simply copy a previous release object and adjust the following values:
* `versionName` - String version like `1.4.1`
* `versionCode` - Android `versionCode`. We use a timestamp generated by [a script](../scripts/version/gen_build_no.sh)
* `commit` - Specific commit SHA1 from which the given release was built
* `BUILD_NUMBER` in `build` step - Same value as `versionCode`
The `versionCode` should be the same as the one in build that was uplodade to Play Store. It can be found in the build logs or by using:
```
> apkanalyzer manifest version-code StatusIm-v1.4.1.apk
2020070112
```
At the bottom of the file you should also update the following keys:
* `CurrentVersion` - Same as the new `versionName` added
* `CurrentVersionCode` - Same as the `versionCode` added
Then submit a merge request to the [fdroid/fdroiddata](https://gitlab.com/fdroid/fdroiddata) repository.
# Checking Builds
The simplest way to test if the app builds via F-Droid is to use the Docker image:
https://gitlab.com/fdroid/docker-executable-fdroidserver
Which is available under `registry.gitlab.com/fdroid/docker-executable-fdroidserver:latest`.
Because we use Nix to build the mobile app we need to slightly modify the image with this `Dockerfile`:
```Dockerfile
FROM registry.gitlab.com/fdroid/docker-executable-fdroidserver:latest
ARG BUILDER_UID=1000
ENV BUILDER_USER=vagrant
RUN useradd -u $BUILDER_UID $BUILDER_USER
RUN mkdir -m 0755 /nix /home/$BUILDER_USER \
&& chown -R $BUILDER_USER /nix /home/$BUILDER_USER
```
Build it using:
```
docker build --build-arg=BUILDER_UID=$UID -t statusteam/docker-executable-fdroidserver:latest .
```
Then clone the [fdroiddata](https://gitlab.com/fdroid/fdroiddata) and [fdroidserver](https://gitlab.com/fdroid/fdroidserver) repos and use it to test the build of a specific Status Android app version: `1.4.1`
```
docker run --rm \
-u $UID:$GID \
-v $(pwd)/nix:/nix \
-v $(pwd)/fdroiddata:/repo \
-v $(pwd)/fdroidserver:/fdroidserver \
statusteam/docker-executable-fdroidserver:latest \
build im.status.ethereum:1.4.1
```
We have to create a user and specify the UID because Nix cannot run as `root` and that is the default user for the F-Droid Docker image. By adding our own user and setting the UID we also make it possible to mount folders like `fdroiddata` and `fdroidserver`.
You can specify a `--vebose` flag for `build` command for additional information.
You should also run `lint im.status.ethereum` to verify the YAML format is correct.
# Details
The original research was done in [#8512](https://github.com/status-im/status-react/issues/8512).
Normally F-Droid server wants to run Gradle itself, but we do not specify the `gradle` key in order to run `make release-android` ourselves in `build` step.
+5 -68
View File
@@ -1,11 +1,4 @@
# Codebase Strucuture and Guidelines
## Starting the app
The app is bundled and run in a Nix environment. Information regarding how to run it locally can be found [here](https://status.im/technical/build_status/).
## Business Logic Modules
# Business Logic Modules
Each business logic module is managed in a module directory.
@@ -38,7 +31,7 @@ Rationale and how to get there:
Currently a lot of business logic is lost in utils and screens namespaces and should be moved to dedicated top level directories.
This should make core logic of the app more accessible and organized
### core.cljs
## core.cljs
Core namespace must only contain functions that can be called outside of the module (i.e. in events or other modules):
@@ -52,7 +45,7 @@ Core namespace must only contain functions that can be called outside of the mod
{:db (module.db/set-current-account db)})
```
### db.cljs
## db.cljs
- must contain specs for the app-db subpart the module modifies
- must contain getter and setter functions used by fx producing functions and subscriptions
@@ -62,15 +55,13 @@ Rationale:
These guidelines make db.cljs namespaces the place to go when making changes to the db layout and minimize breaking changes when adding/refactoring features
## re-frame
### Subscriptions
# Subscriptions
- all subscriptions must be defined in the single `status-im.subs` namespace
- subscriptions must subscribe only on other subscriptions, and never on app-db itself
- `reg-root-key-sub` should be used for the root keys subscriptions
### Events
# Events
- all events must be defined in the single `status-im.events` namespace which can be considered as an index of everything going on in the app
- events must always be declared with `register-handler-fx`, no `register-handler-db`
@@ -87,57 +78,3 @@ These guidelines make db.cljs namespaces the place to go when making changes to
- `:module.ui/` for user triggered events
- `:module.callback/` for callback events, which are events bringing back the result of an fx to the event loop, the name of the event should end with `-success` or `-error` most of the time. Other possibilities can be `-granted`, `-denied` for instance.
- `:module/` for internal events, examples are time based events marked `-timed-out`, external changes marked `-changed` or reception of external events marked `-received`.
## Testing flow
- All PRs automatically go to "REVIEW" column on [Pipeline for QA](https://github.com/status-im/status-react/projects/7) project on Github. This is our main board for QA / devs interaction
- After the PR gets at least 1 approval, it should be moved to "E2E Tests" column. Some PRs may need approvals from more than one person.
- Critical path tests are automatically run for all PRs in "E2E Tests" column.
- If E2E tests pass:
- If PR doesn't need manual QA (it is small change or change doesn't relate to app) - after passing e2e tests it can be merged (don't use the Github UI to merge, check section on merging PRs).
- If manual QA needed - add label 'request manual qa'. The QA team will process it (make sure the summary and test instructions are clear). QA team will review results and test PR on different platforms and assign one of the three labels:
- No issues - label 'TESTED-OK' and then you can merge it.
- If issues - label 'TESTED-ISSUES' and comment from QA with bugs.
- After fix and/or discussion the process is repeated.
- If manual QA is not needed but all tests don't pass, you can ping @churik or @Serhy to confirm that failed E2E tests are not unrelated.
## Enabling debug logs
Calls to `log/debug` will not be printed to the console by default. It can be enabled under "Advanced settings" in the app:
![Enable Debug Logs](./log-settings.png)
## Translations
The app relies on system locale to select a language from the [list of supported languages](https://github.com/status-im/status-react/blob/bda73867471cf2bb8a68b1cc27c9f94b92d9a58b/src/status_im/i18n_resources.cljs#L9). It falls back to English in cash the system locale is not supported.
We use Lokalise App to manage [translations](https://translate.status.im/). In case you need to add/remove a key to translations, you only need to change `en.json`. Missing keys fallback to `en.json`. The actual translations will be added by Lokalise.
## re-frisk
re-frisk is a state visualization tool written by our very own Andrey (@flexsurfer). To start re-frisk, execute the following command:
```bash
$ yarn shadow-cljs run re-frisk-remote.core/start
```
or you can also use make:
```bash
$ make run-re-frisk
```
A server will be started at http://localhost:4567. It might show "not connected" at first. Don't worry and just start using the app. The events and state will populate.
## Merging approved PRs
We don't Github's UI to merge. Instead `./scripts/merge-pr.sh` is used to sign and merge PR to `develop`. You first need to enable [GPG signing on you commits](https://github.com/status-im/status-react/blob/develop/STARTING_GUIDE.md#configure-gpg-keys-for-signing-commits).
Once your commits are verfied and PR approved, you can run the script like so:
```bash
$ git checkout develop
$ git fetch
$ git reset --hard origin/develop
$ ./scripts/merge-pr.sh 11370
```
Replace 11370 with your PR id.
## Release process
TODO(shivekkhurana): Compile release notes
Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

+21 -41
View File
@@ -11,6 +11,18 @@
# There are a few env variables defined in the .env file in
# this directory (fastlane/.env)
# unlocks keychain if KEYCHAIN_PASSWORD variable is present
# (to be used on CI machines)
def unlock_keychain_if_needed
return unless ENV['KEYCHAIN_PASSWORD']
unlock_keychain(
path: 'login.keychain',
password: ENV['KEYCHAIN_PASSWORD'],
set_default: true
)
end
def curl_upload(url, file, auth, conn_timeout = 5, timeout = 60, retries = 3)
rval = sh(
'curl',
@@ -69,32 +81,6 @@ def upload_to_saucelabs(file)
end
end
# Creates and unlocks a keychain into which Fastlane match imports signing keys and certs.
class Keychain
attr_accessor :name, :pass
def initialize(name)
# Local devs will not have KEYCHAIN_PASSWORD set, and will be prompted for password.
return "login.keychain-db" unless ENV['KEYCHAIN_PASSWORD']
# We user the same keychain every time because we need to set a default.
@name = "#{name}.keychain-db"
@pass = ENV['KEYCHAIN_PASSWORD']
Fastlane::Actions::CreateKeychainAction.run(
name: @name,
password: @pass,
unlock: true,
# Fastlane can't find the signing cert without setting a default.
default_keychain: true,
# Deleting the keychain would cause race condition for parallel jobs.
require_create: false,
# Lock it up after 25 minutes just in case we don't delete it.
lock_when_sleeps: true,
lock_after_timeout: true,
timeout: 1500
)
end
end
# builds an ios app with ad-hoc configuration and put it
# to "status-ios" output folder
# `readonly`:
@@ -109,15 +95,12 @@ def build_ios_adhoc(readonly: false, pr_build: false)
scheme = pr_build ? 'StatusImPR' : 'StatusIm'
app_id = pr_build ? 'im.status.ethereum.pr' : 'im.status.ethereum'
kc = Keychain.new('fastlane')
match(
type: 'adhoc',
force_for_new_devices: true,
readonly: readonly,
app_identifier: app_id,
force_for_new_devices: true,
keychain_name: kc.name,
keychain_password: kc.pass
keychain_name: 'login.keychain'
)
build_ios_app(
@@ -145,14 +128,11 @@ def build_ios_e2e
showsdks_output = sh('xcodebuild', '-showsdks')
simulator_sdk = showsdks_output.scan(/iphonesimulator\d\d?\.\d\d?/).first
kc = Keychain.new('fastlane')
match(
type: 'adhoc',
readonly: true,
force_for_new_devices: true,
keychain_name: kc.name,
keychain_password: kc.pass
readonly: true,
keychain_name: 'login.keychain'
)
build_ios_app(
@@ -201,6 +181,7 @@ platform :ios do
desc 'It creates an .ipa that can be used by a list of devices, registeded in the App Store Connect.'
desc 'This .ipa is ready to be distibuted through diawi.com'
lane :adhoc do
unlock_keychain_if_needed
build_ios_adhoc(readonly: true)
end
@@ -208,31 +189,31 @@ platform :ios do
desc 'This lane is used for SauceLabs end-to-end testing.'
desc 'It creates an .app that can be used inside of a iPhone simulator.'
lane :e2e do
unlock_keychain_if_needed
build_ios_e2e
end
desc '`fastlane ios pr` - makes a new pr build'
desc 'This lane builds a new adhoc build and leaves an .ipa that is ad-hoc signed (can be uploaded to diawi)'
lane :pr do
unlock_keychain_if_needed
build_ios_adhoc(pr_build: true)
end
desc '`fastlane ios nightly` - makes a new nightly'
desc 'This lane builds a new nightly and leaves an .ipa that is ad-hoc signed (can be uploaded to diawi)'
lane :nightly do
unlock_keychain_if_needed
build_ios_adhoc()
end
desc '`fastlane ios release` builds a release & uploads it to TestFlight'
lane :release do
kc = Keychain.new('fastlane')
match(
type: 'appstore',
readonly: true,
app_identifier: 'im.status.ethereum',
keychain_name: kc.name,
keychain_password: kc.pass
keychain_name: 'login.keychain'
)
build_ios_app(
@@ -249,7 +230,6 @@ platform :ios do
"ITSAppUsesNonExemptEncryption": false
}
)
upload_to_testflight(
ipa: 'status-ios/StatusIm.ipa',
skip_waiting_for_build_processing: true
+19 -21
View File
@@ -6,22 +6,22 @@ GEM
public_suffix (>= 2.0.2, < 5.0)
atomos (0.1.3)
aws-eventstream (1.1.0)
aws-partitions (1.383.0)
aws-sdk-core (3.109.1)
aws-partitions (1.350.0)
aws-sdk-core (3.104.3)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.239.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.39.0)
aws-sdk-core (~> 3, >= 3.109.0)
aws-sdk-kms (1.36.0)
aws-sdk-core (~> 3, >= 3.99.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.83.1)
aws-sdk-core (~> 3, >= 3.109.0)
aws-sdk-s3 (1.75.0)
aws-sdk-core (~> 3, >= 3.104.1)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.2.2)
aws-sigv4 (1.2.1)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
babosa (1.0.3)
claide (1.0.3)
colored (1.2)
colored2 (3.1.2)
@@ -35,17 +35,16 @@ GEM
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.6)
emoji_regex (3.0.0)
excon (0.78.0)
faraday (1.1.0)
excon (0.76.0)
faraday (1.0.1)
multipart-post (>= 1.2, < 3)
ruby2_keywords
faraday-cookie_jar (0.0.7)
faraday (>= 0.8.0)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (1.0.0)
faraday (~> 1.0)
fastimage (2.2.0)
fastlane (2.164.0)
fastlane (2.154.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
aws-sdk-s3 (~> 1.0)
@@ -96,17 +95,17 @@ GEM
google-cloud-core (1.5.0)
google-cloud-env (~> 1.0)
google-cloud-errors (~> 1.0)
google-cloud-env (1.4.0)
google-cloud-env (1.3.3)
faraday (>= 0.17.3, < 2.0)
google-cloud-errors (1.0.1)
google-cloud-storage (1.29.1)
google-cloud-storage (1.27.0)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-api-client (~> 0.33)
google-cloud-core (~> 1.2)
googleauth (~> 0.9)
mini_mime (~> 1.0)
googleauth (0.14.0)
googleauth (0.13.1)
faraday (>= 0.17.3, < 2.0)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
@@ -120,7 +119,7 @@ GEM
httpclient (2.8.3)
jmespath (1.4.0)
json (2.3.1)
jwt (2.2.2)
jwt (2.2.1)
memoist (0.16.2)
mime-types (3.3.1)
mime-types-data (~> 3.2015)
@@ -134,7 +133,7 @@ GEM
netrc (0.11.0)
os (1.1.1)
plist (3.5.0)
public_suffix (4.0.6)
public_suffix (4.0.5)
rake (13.0.1)
representable (3.0.4)
declarative (< 0.1.0)
@@ -147,7 +146,6 @@ GEM
netrc (~> 0.8)
retriable (3.1.2)
rouge (2.0.7)
ruby2_keywords (0.0.2)
rubyzip (2.3.0)
security (0.1.3)
signet (0.14.0)
@@ -172,7 +170,7 @@ GEM
unf_ext (0.0.7.7)
unicode-display_width (1.7.0)
word_wrap (1.0.0)
xcodeproj (1.19.0)
xcodeproj (1.17.1)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
+33 -43
View File
@@ -35,10 +35,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1as2xr2yjsylrjys084bm2q90la0nw7rm1cgwx57wcds58i9zrwb";
sha256 = "1rwd13lqambjpq94qhccw3ixn6bvwnqcnd3v1rdlmpcvqq2rw49c";
type = "gem";
};
version = "1.383.0";
version = "1.350.0";
};
aws-sdk-core = {
dependencies = ["aws-eventstream" "aws-partitions" "aws-sigv4" "jmespath"];
@@ -46,10 +46,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0xmppcxq7jm8lffqibkhq257hfwfbv82zm2y1fbhwm3icgxzwlfx";
sha256 = "1xfv8nfz8n700z29di51mcyyrnmbpq7flff4hx9mm92avnly1ysy";
type = "gem";
};
version = "3.109.1";
version = "3.104.3";
};
aws-sdk-kms = {
dependencies = ["aws-sdk-core" "aws-sigv4"];
@@ -57,10 +57,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0ly1m631qm2ciif7sysbzrgczjvz95ga3g6w6vrzvfdv31jjnl9a";
sha256 = "0rpwpj4f4q9wdrbgiqngzwfdaaqyz0iif8sv16z6z0mm6y3cb06q";
type = "gem";
};
version = "1.39.0";
version = "1.36.0";
};
aws-sdk-s3 = {
dependencies = ["aws-sdk-core" "aws-sdk-kms" "aws-sigv4"];
@@ -68,10 +68,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "021yqghdb1i980vn249hv44jajr0v3hq4ik4r6fqh9kwp04fsbqv";
sha256 = "068xx6wp86wkmikdzg4wqxmg570hc3ydp8211j02g13djjr3k28n";
type = "gem";
};
version = "1.83.1";
version = "1.75.0";
};
aws-sigv4 = {
dependencies = ["aws-eventstream"];
@@ -79,20 +79,20 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1ll9382c1x2hp750cilh01h1cycgyhdr4cmmgx23k94hyyb8chv5";
sha256 = "0aknh3q37rq3ixxa84x2p26g8a15zmiig2rm1pmailsb9vqhfh3j";
type = "gem";
};
version = "1.2.2";
version = "1.2.1";
};
babosa = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "16dwqn33kmxkqkv51cwiikdkbrdjfsymlnc0rgbjwilmym8a9phq";
sha256 = "10nn9bw63i4awpzn5vrx6kmpx1sg7z8r3fhw9r8bvg9pz2wh489g";
type = "gem";
};
version = "1.0.4";
version = "1.0.3";
};
CFPropertyList = {
groups = ["default"];
@@ -212,21 +212,21 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1hi89v53pm2abfv9j8lgqdd7hgkr7fr0gwrczr940iwbb3xv7rrs";
sha256 = "05is0kb650j8wrdi4rgkdls662chnhdg2p64pgq3zkd3d7l2a9zw";
type = "gem";
};
version = "0.78.0";
version = "0.76.0";
};
faraday = {
dependencies = ["multipart-post" "ruby2_keywords"];
dependencies = ["multipart-post"];
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "16dapwi5pivrl25r4lkr1mxjrzkznj4wlcb08fzkmxnj4g5c6y35";
sha256 = "0wwks9652xwgjm7yszcq5xr960pjypc07ivwzbjzpvy9zh2fw6iq";
type = "gem";
};
version = "1.1.0";
version = "1.0.1";
};
faraday-cookie_jar = {
dependencies = ["faraday" "http-cookie"];
@@ -234,10 +234,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "00hligx26w9wdnpgsrf0qdnqld4rdccy8ym6027h5m735mpvxjzk";
sha256 = "1di4gx6446a6zdkrpj679m5k515i53wvb4yxcsqvy8d8zacxiiv6";
type = "gem";
};
version = "0.0.7";
version = "0.0.6";
};
faraday_middleware = {
dependencies = ["faraday"];
@@ -266,10 +266,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1mr143fx505iwgci6v9bl4pd6v305wrc4q1s329sjmy67jfbm47w";
sha256 = "05y7qn8f1d3q355vf1fvbwz0sf73bwiwbcpzidd1szh49400h65b";
type = "gem";
};
version = "2.164.0";
version = "2.154.0";
};
fastlane-plugin-clean_testflight_testers = {
groups = ["default"];
@@ -330,10 +330,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0bjgxyvagy6hjj8yg7fqq24rwdjxb6hx7fdd1bmn4mwd846lci2i";
sha256 = "0frifczbhs5k699avaxnaypijfmjd2zb1rbdmcb30vdx8sskypa9";
type = "gem";
};
version = "1.4.0";
version = "1.3.3";
};
google-cloud-errors = {
groups = ["default"];
@@ -351,10 +351,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1d8yc807dbd4pcwrrg2pdl30hghcnjid55qrjl2shffhzgiyl54h";
sha256 = "06pmgk210frapxjjshy9iax6jb5ps8fbylcy0c9ypwji6cwxk990";
type = "gem";
};
version = "1.29.1";
version = "1.27.0";
};
googleauth = {
dependencies = ["faraday" "jwt" "memoist" "multi_json" "os" "signet"];
@@ -362,10 +362,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "0cm60nbmwzf83fzy06f3iyn5a6sw91siw8x9bdvpwwmjsmivana6";
sha256 = "0ldhllhv8mlbalp8a3zb1hsj5p2i8f0vf88r71vm083gq7820iwn";
type = "gem";
};
version = "0.14.0";
version = "0.13.1";
};
highline = {
groups = ["default"];
@@ -433,10 +433,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "14ynyq1q483spj20ffl4xayfqx1a8qr761mqjfxczf8lwlap392n";
sha256 = "01zg1vp3lyl3flyjdkrcc93ghf833qgfgh2p1biqfhkzz11r129c";
type = "gem";
};
version = "2.2.2";
version = "2.2.1";
};
memoist = {
groups = ["default"];
@@ -564,10 +564,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1xqcgkl7bwws1qrlnmxgh8g4g9m10vg60bhlw40fplninb3ng6d9";
sha256 = "0vywld400fzi17cszwrchrzcqys4qm6sshbv73wy5mwcixmrgg7g";
type = "gem";
};
version = "4.0.6";
version = "4.0.5";
};
rake = {
groups = ["default"];
@@ -621,16 +621,6 @@
};
version = "2.0.7";
};
ruby2_keywords = {
groups = ["default"];
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "17pcc0wgvh3ikrkr7bm3nx0qhyiqwidd13ij0fa50k7gsbnr2p0l";
type = "gem";
};
version = "0.0.2";
};
rubyzip = {
groups = ["default"];
platforms = [];
@@ -792,10 +782,10 @@
platforms = [];
source = {
remotes = ["https://rubygems.org"];
sha256 = "1411j6sfnz0cx4fiw52f0yqx4bgcn8cmpgi3i5rwmmahayyjz2fn";
sha256 = "0mv5rsbgwq4vzri31w2f1474arrsr5j69rdhklrci6jnjps8dmx9";
type = "gem";
};
version = "1.19.0";
version = "1.17.1";
};
xcpretty = {
dependencies = ["rouge"];
@@ -1,12 +1,12 @@
Status es una herramienta de comunicación segura y privada. Chatea con amigos, almacena activos y explora el futuro de la web sin ser explotado por tu información personal.
Status é uma ferramenta de comunicação segura e privada. Converse com os seus amigos, armazene ativos e explore o futuro da web sem que os seus dados sejam explorados.
Solo tú controlas tu información, con Status.
Com a Status, apenas você controlas as suas informações.
CHAT
Status quita de en medio terceros centralizados a tus mensajes. No sólo tu contenido es protegido, sino también tu metadata: por máxima privacidad.
CONVERSA
A Status remove terceiros centralizados das suas mensagens. Não é apenas o seu conteúdo que está protegido, mas também os seus metadados - para uma privacidade máxima.
TRANSFIERE
Almacena activos digitales en tu monedero Status (ERC20 and ERC721). Envía y recibe monedas de tus amigos, o transfiere activos con aplicaciónes descentralizadas.
TRANSACIONA
Armazene ativos digitais na sua carteira Status. Envie e solicite tokens aos seus amigos, ou transacione com aplicações descentralizadas.
EXPLORA
Accede a aplicaciones basadas en Ethereum de la Web3. Juega, intercambia bienes digitales y más.
Acesse à aplicações baseadas na Ethereum na web3. Joge jogos, troce ativos digitais e muito mais.
@@ -1 +1 @@
Chatea y transfiere de forma segura
Converse e faça transações de uma forma segura
+1 -1
View File
@@ -1 +1 @@
Status - Comunicación Privada
Status - Comunição Privada
+10 -16
View File
@@ -1,7 +1,5 @@
PODS:
- boost-for-react-native (1.63.0)
- BVLinearGradient (2.5.6):
- React
- CocoaAsyncSocket (7.6.4)
- CocoaLibEvent (1.0.0)
- DoubleConversion (1.1.6)
@@ -259,8 +257,8 @@ PODS:
- React
- react-native-splash-screen (3.2.0):
- React
- react-native-webview (10.9.2):
- React-Core
- react-native-webview (10.3.1):
- React
- React-RCTActionSheet (0.62.2):
- React-Core/RCTActionSheetHeaders (= 0.62.2)
- React-RCTAnimation (0.62.2):
@@ -336,7 +334,7 @@ PODS:
- React
- RNFS (2.16.6):
- React
- RNGestureHandler (1.8.0):
- RNGestureHandler (1.6.1):
- React
- RNImageCropPicker (0.31.1):
- React-Core
@@ -355,9 +353,9 @@ PODS:
- React
- RNReactNativeHapticFeedback (1.9.0):
- React
- RNReanimated (1.13.0):
- RNReanimated (1.8.0):
- React
- RNScreens (2.10.1):
- RNScreens (2.5.0):
- React
- RNSVG (9.13.6):
- React
@@ -375,7 +373,6 @@ PODS:
- Yoga (~> 1.14)
DEPENDENCIES:
- BVLinearGradient (from `../node_modules/react-native-linear-gradient`)
- DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`)
- FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`)
- FBReactNativeSpec (from `../node_modules/react-native/Libraries/FBReactNativeSpec`)
@@ -476,8 +473,6 @@ SPEC REPOS:
- YogaKit
EXTERNAL SOURCES:
BVLinearGradient:
:path: "../node_modules/react-native-linear-gradient"
DoubleConversion:
:podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec"
FBLazyVector:
@@ -593,7 +588,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
@@ -607,7 +601,7 @@ SPEC CHECKSUMS:
Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
FlipperKit: afd4259ef9eadeeb2d30250b37d95cb3b6b97a69
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: d6cca0516fb0ca3697a5b2e199ea83dfc7133411
glog: 1f3da668190260b06b429bb211bfbee5cd790c28
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
Permission-Camera: afad27bf90337684d4a86f3825112d648c8c4d3b
Permission-Microphone: 0ffabc3fe1c75cfb260525ee3f529383c9f4368c
@@ -630,7 +624,7 @@ SPEC CHECKSUMS:
react-native-shake: de052eaa3eadc4a326b8ddd7ac80c06e8d84528c
react-native-slider: 12bd76d3d568c9c5500825db54123d44b48e4ad4
react-native-splash-screen: 200d11d188e2e78cea3ad319964f6142b6384865
react-native-webview: 4e96d493f9f90ba4f03b28933f30b2964df07e39
react-native-webview: 40bbeb6d011226f34cb83f845aeb0fdf515cfc5f
React-RCTActionSheet: f41ea8a811aac770e0cc6e0ad6b270c644ea8b7c
React-RCTAnimation: 49ab98b1c1ff4445148b72a3d61554138565bad0
React-RCTBlob: a332773f0ebc413a0ce85942a55b064471587a71
@@ -649,14 +643,14 @@ SPEC CHECKSUMS:
RNCPushNotificationIOS: c145c6253ea016e5efeff604f2720736b4a596f7
RNDeviceInfo: b6e650fbd234732c759544218657d549b4339038
RNFS: 2bd9eb49dc82fa9676382f0585b992c424cd59df
RNGestureHandler: 7a5833d0f788dbd107fbb913e09aa0c1ff333c39
RNGestureHandler: 8f09cd560f8d533eb36da5a6c5a843af9f056b38
RNImageCropPicker: 38865ab4af1b0b2146ad66061196bc0184946855
RNKeychain: 216f37338fcb9e5c3a2530f1e3295f737a690cb1
RNLanguages: 962e562af0d34ab1958d89bcfdb64fafc37c513e
RNPermissions: ad71dd4f767ec254f2cd57592fbee02afee75467
RNReactNativeHapticFeedback: 2566b468cc8d0e7bb2f84b23adc0f4614594d071
RNReanimated: 89f5e0a04d1dd52fbf27e7e7030d8f80a646a3fc
RNScreens: b748efec66e095134c7166ca333b628cd7e6f3e2
RNReanimated: 955cf4068714003d2f1a6e2bae3fb1118f359aff
RNScreens: ac02d0e4529f08ced69f5580d416f968a6ec3a1d
RNSVG: 8ba35cbeb385a52fd960fd28db9d7d18b4c2974f
SQLCipher: f9fcf29b2e59ced7defc2a2bdd0ebe79b40d4990
SSZipArchive: 62d4947b08730e4cda640473b0066d209ff033c9
-13
View File
@@ -171,18 +171,5 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
{
[RNCPushNotificationIOS didReceiveLocalNotification:notification];
}
// Manage notifications while app is in the foreground
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler
{
NSDictionary *userInfo = notification.request.content.userInfo;
NSString *notificationType = userInfo[@"notificationType"]; // check your notification type
if (![notificationType isEqual: @"local-notification"]) { // we silence all notifications which are not local
completionHandler(UNNotificationPresentationOptionNone);
return;
}
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
@end
+5
View File
@@ -63,6 +63,11 @@
<true/>
<key>NSExceptionDomains</key>
<dict>
<key>api.status.im</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
</dict>
<key>localhost</key>
<dict>
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
@@ -1,20 +0,0 @@
package im.status.ethereum.module;
import android.content.Intent;
import android.os.Bundle;
import com.facebook.react.HeadlessJsTaskService;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.jstasks.HeadlessJsTaskConfig;
import javax.annotation.Nullable;
public class LocalNotificationsService extends HeadlessJsTaskService {
@Override
protected @Nullable HeadlessJsTaskConfig getTaskConfig(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
return new HeadlessJsTaskConfig("LocalNotifications", Arguments.fromBundle(extras), 60000, true);
}
return null;
}
}
@@ -7,10 +7,8 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Build;
import android.os.Environment;
import android.preference.PreferenceManager;
import androidx.core.content.FileProvider;
@@ -18,15 +16,9 @@ import androidx.core.content.FileProvider;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebView;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebStorage;
import android.content.Context;
import android.view.View;
import android.widget.TextView;
import android.widget.EditText;
import android.view.inputmethod.InputMethodManager;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
@@ -38,9 +30,6 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.UIBlock;
import com.facebook.react.uimanager.NativeViewHierarchyManager;
import statusgo.SignalHandler;
import statusgo.Statusgo;
@@ -163,18 +152,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
newMessageSignalHandler.handleNewMessageSignal(jsonEvent);
}
}
if(eventType.equals("local-notifications")) {
Context ctx = this.getReactApplicationContext();
Intent intent = new Intent(ctx, LocalNotificationsService.class);
Bundle bundle = new Bundle();
bundle.putString("event", jsonEventString);
intent.putExtras(bundle);
ctx.startService(intent);
}
WritableMap params = Arguments.createMap();
params.putString("jsonEvent", jsonEventString);
this.getReactApplicationContext().getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class).emit("gethEvent", params);
@@ -1065,22 +1042,6 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
}
@ReactMethod
public void toggleWebviewDebug(final boolean val) {
Log.d(TAG, "toggleWebviewDebug");
final Activity activity = getCurrentActivity();
if (activity == null) {
return;
}
activity.runOnUiThread(new Runnable() {
@Override
public void run() {
WebView.setWebContentsDebuggingEnabled(val);
}
});
}
@ReactMethod
public void clearStorageAPIs() {
Log.d(TAG, "clearStorageAPIs");
@@ -1145,21 +1106,9 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
}
@ReactMethod
public void startWallet(final boolean watchNewBlocks) {
public void startWallet() {
Log.d(TAG, "StartWallet");
Statusgo.startWallet(watchNewBlocks);
}
@ReactMethod
public void stopLocalNotifications() {
Log.d(TAG, "stopLocalNotifications");
Statusgo.stopLocalNotifications();
}
@ReactMethod
public void startLocalNotifications() {
Log.d(TAG, "startLocalNotifications");
Statusgo.startLocalNotifications();
Statusgo.startWallet();
}
@ReactMethod
@@ -1349,6 +1298,7 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
StatusThreadPoolExecutor.getInstance().execute(r);
}
@ReactMethod
public void getNodesFromContract(final String rpcEndpoint, final String contractAddress, final Callback callback) {
Log.d(TAG, "getNodesFromContract");
@@ -1436,24 +1386,5 @@ class StatusModule extends ReactContextBaseJavaModule implements LifecycleEventL
});
}
}
@ReactMethod
public void resetKeyboardInputCursor(final int reactTagToReset, final int selection) {
UIManagerModule uiManager = getReactApplicationContext().getNativeModule(UIManagerModule.class);
uiManager.addUIBlock(new UIBlock() {
@Override
public void execute(NativeViewHierarchyManager nativeViewHierarchyManager) {
InputMethodManager imm = (InputMethodManager) getReactApplicationContext().getBaseContext().getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
View viewToReset = nativeViewHierarchyManager.resolveView(reactTagToReset);
imm.restartInput(viewToReset);
try {
EditText textView = (EditText) viewToReset;
textView.setSelection(selection);
} catch (Exception e) {}
}
}
});
}
}
@@ -1,110 +0,0 @@
package im.status.ethereum.pushnotifications;
import android.app.Activity;
import android.app.Application;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.core.app.NotificationManagerCompat;
import java.security.SecureRandom;
import com.facebook.react.bridge.ActivityEventListener;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableMap;
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery;
public class PushNotification extends ReactContextBaseJavaModule implements ActivityEventListener {
public static final String LOG_TAG = "PushNotification";
private final SecureRandom mRandomNumberGenerator = new SecureRandom();
private PushNotificationHelper pushNotificationHelper;
private PushNotificationJsDelivery delivery;
public PushNotification(ReactApplicationContext reactContext) {
super(reactContext);
reactContext.addActivityEventListener(this);
Application applicationContext = (Application) reactContext.getApplicationContext();
pushNotificationHelper = new PushNotificationHelper(applicationContext);
delivery = new PushNotificationJsDelivery(reactContext);
}
@Override
public String getName() {
return "PushNotification";
}
// removed @Override temporarily just to get it working on different versions of RN
public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
onActivityResult(requestCode, resultCode, data);
}
// removed @Override temporarily just to get it working on different versions of RN
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// Ignored, required to implement ActivityEventListener for RN 0.33
}
private Bundle getBundleFromIntent(Intent intent) {
Bundle bundle = null;
if (intent.hasExtra("notification")) {
bundle = intent.getBundleExtra("notification");
} else if (intent.hasExtra("google.message_id")) {
bundle = new Bundle();
bundle.putBundle("data", intent.getExtras());
}
if(null != bundle && !bundle.getBoolean("foreground", false) && !bundle.containsKey("userInteraction")) {
bundle.putBoolean("userInteraction", true);
}
return bundle;
}
@Override
public void onNewIntent(Intent intent) {
Bundle bundle = this.getBundleFromIntent(intent);
if (bundle != null) {
delivery.notifyNotification(bundle);
}
}
@ReactMethod
/**
* Creates a channel if it does not already exist. Returns whether the channel was created.
*/
public void createChannel(ReadableMap channelInfo, Callback callback) {
boolean created = pushNotificationHelper.createChannel(channelInfo);
if(callback != null) {
callback.invoke(created);
}
}
@ReactMethod
public void presentLocalNotification(ReadableMap details) {
Bundle bundle = Arguments.toBundle(details);
// If notification ID is not provided by the user, generate one at random
if (bundle.getString("id") == null) {
bundle.putString("id", String.valueOf(mRandomNumberGenerator.nextInt()));
}
pushNotificationHelper.sendToNotificationCentre(bundle);
}
}
@@ -1,90 +0,0 @@
package im.status.ethereum.pushnotifications;
import android.os.Build;
import android.app.Application;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import im.status.ethereum.pushnotifications.PushNotificationJsDelivery;
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
public class PushNotificationActions extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
String intentActionPrefix = context.getPackageName() + ".ACTION_";
Log.i(LOG_TAG, "PushNotificationBootEventReceiver loading scheduled notifications");
if (null == intent.getAction() || !intent.getAction().startsWith(intentActionPrefix)) {
return;
}
final Bundle bundle = intent.getBundleExtra("notification");
// Dismiss the notification popup.
NotificationManager manager = (NotificationManager) context.getSystemService(context.NOTIFICATION_SERVICE);
int notificationID = Integer.parseInt(bundle.getString("id"));
boolean autoCancel = bundle.getBoolean("autoCancel", true);
if(autoCancel) {
if (bundle.containsKey("tag")) {
String tag = bundle.getString("tag");
manager.cancel(tag, notificationID);
} else {
manager.cancel(notificationID);
}
}
boolean invokeApp = bundle.getBoolean("invokeApp", true);
// Notify the action.
if(invokeApp) {
PushNotificationHelper helper = new PushNotificationHelper((Application) context.getApplicationContext());
helper.invokeApp(bundle);
} else {
// We need to run this on the main thread, as the React code assumes that is true.
// Namely, DevServerHelper constructs a Handler() without a Looper, which triggers:
// "Can't create handler inside thread that has not called Looper.prepare()"
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
// Construct and load our normal React JS code bundle
final ReactInstanceManager mReactInstanceManager = ((ReactApplication) context.getApplicationContext()).getReactNativeHost().getReactInstanceManager();
ReactContext context = mReactInstanceManager.getCurrentReactContext();
PushNotificationJsDelivery delivery = new PushNotificationJsDelivery(context);
// If it's constructed, send a notification
if (context != null) {
delivery.notifyNotificationAction(bundle);
} else {
// Otherwise wait for construction, then send the notification
mReactInstanceManager.addReactInstanceEventListener(new ReactInstanceManager.ReactInstanceEventListener() {
public void onReactContextInitialized(ReactContext context) {
PushNotificationJsDelivery delivery = new PushNotificationJsDelivery(context);
delivery.notifyNotificationAction(bundle);
mReactInstanceManager.removeReactInstanceEventListener(this);
}
});
if (!mReactInstanceManager.hasStartedCreatingInitialContext()) {
// Construct it in the background
mReactInstanceManager.createReactContextInBackground();
}
}
}
});
}
}
}
@@ -1,549 +0,0 @@
// https://github.com/zo0r/react-native-push-notification/blob/bedc8f646aab67d594f291449fbfa24e07b64fe8/android/src/main/java/com/dieam/reactnativepushnotification/modules/RNPushNotificationHelper.java Copy-Paste with removed firebase
package im.status.ethereum.pushnotifications;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.AlarmManager;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.ApplicationInfo;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.media.AudioAttributes;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.service.notification.StatusBarNotification;
import android.util.Log;
import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableMap;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.Map;
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
public class PushNotificationHelper {
private Context context;
private static final long DEFAULT_VIBRATION = 300L;
private static final String CHANNEL_ID = "status-im-notifications";
public PushNotificationHelper(Application context) {
this.context = context;
}
private NotificationManager notificationManager() {
return (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
public void invokeApp(Bundle bundle) {
String packageName = context.getPackageName();
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
String className = launchIntent.getComponent().getClassName();
try {
Class<?> activityClass = Class.forName(className);
Intent activityIntent = new Intent(context, activityClass);
if(bundle != null) {
activityIntent.putExtra("notification", bundle);
}
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(activityIntent);
} catch(Exception e) {
Log.e(LOG_TAG, "Class not found", e);
return;
}
}
public void sendToNotificationCentre(final Bundle bundle) {
PushNotificationPicturesAggregator aggregator = new PushNotificationPicturesAggregator(new PushNotificationPicturesAggregator.Callback() {
public void call(Bitmap largeIconImage, Bitmap bigPictureImage) {
sendToNotificationCentreWithPicture(bundle, largeIconImage, bigPictureImage);
}
});
aggregator.setLargeIconUrl(context, bundle.getString("largeIconUrl"));
aggregator.setBigPictureUrl(context, bundle.getString("bigPictureUrl"));
}
public void sendToNotificationCentreWithPicture(final Bundle bundle, Bitmap largeIconBitmap, Bitmap bigPictureBitmap) {
try {
Class intentClass = getMainActivityClass();
if (intentClass == null) {
Log.e(LOG_TAG, "No activity class found for the notification");
return;
}
if (bundle.getString("message") == null) {
// this happens when a 'data' notification is received - we do not synthesize a local notification in this case
Log.d(LOG_TAG, "Ignore this message if you sent data-only notification. Cannot send to notification centre because there is no 'message' field in: " + bundle);
return;
}
String notificationIdString = bundle.getString("id");
if (notificationIdString == null) {
Log.e(LOG_TAG, "No notification ID specified for the notification");
return;
}
Resources res = context.getResources();
String packageName = context.getPackageName();
String title = bundle.getString("title");
if (title == null) {
ApplicationInfo appInfo = context.getApplicationInfo();
title = context.getPackageManager().getApplicationLabel(appInfo).toString();
}
int priority = NotificationCompat.PRIORITY_HIGH;
final String priorityString = bundle.getString("priority");
if (priorityString != null) {
switch (priorityString.toLowerCase()) {
case "max":
priority = NotificationCompat.PRIORITY_MAX;
break;
case "high":
priority = NotificationCompat.PRIORITY_HIGH;
break;
case "low":
priority = NotificationCompat.PRIORITY_LOW;
break;
case "min":
priority = NotificationCompat.PRIORITY_MIN;
break;
case "default":
priority = NotificationCompat.PRIORITY_DEFAULT;
break;
default:
priority = NotificationCompat.PRIORITY_HIGH;
}
}
int visibility = NotificationCompat.VISIBILITY_PRIVATE;
final String visibilityString = bundle.getString("visibility");
if (visibilityString != null) {
switch (visibilityString.toLowerCase()) {
case "private":
visibility = NotificationCompat.VISIBILITY_PRIVATE;
break;
case "public":
visibility = NotificationCompat.VISIBILITY_PUBLIC;
break;
case "secret":
visibility = NotificationCompat.VISIBILITY_SECRET;
break;
default:
visibility = NotificationCompat.VISIBILITY_PRIVATE;
}
}
String channel_id = bundle.getString("channelId");
if(channel_id == null) {
channel_id = this.getNotificationDefaultChannelId();
}
NotificationCompat.Builder notification = new NotificationCompat.Builder(context, channel_id)
.setContentTitle(title)
.setTicker(bundle.getString("ticker"))
.setVisibility(visibility)
.setPriority(priority)
.setAutoCancel(bundle.getBoolean("autoCancel", true))
.setOnlyAlertOnce(bundle.getBoolean("onlyAlertOnce", false));
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // API 24 and higher
// Restore showing timestamp on Android 7+
// Source: https://developer.android.com/reference/android/app/Notification.Builder.html#setShowWhen(boolean)
boolean showWhen = bundle.getBoolean("showWhen", true);
notification.setShowWhen(showWhen);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { // API 26 and higher
// Changing Default mode of notification
notification.setDefaults(Notification.DEFAULT_LIGHTS);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) { // API 20 and higher
String group = bundle.getString("group");
if (group != null) {
notification.setGroup(group);
}
if (bundle.containsKey("groupSummary") || bundle.getBoolean("groupSummary")) {
notification.setGroupSummary(bundle.getBoolean("groupSummary"));
}
}
String numberString = bundle.getString("number");
if (numberString != null) {
notification.setNumber(Integer.parseInt(numberString));
}
// Small icon
int smallIconResId = 0;
String smallIcon = bundle.getString("smallIcon");
if (smallIcon != null && !smallIcon.isEmpty()) {
smallIconResId = res.getIdentifier(smallIcon, "mipmap", packageName);
} else if(smallIcon == null) {
smallIconResId = res.getIdentifier("ic_stat_notify_status", "drawable", packageName);
}
if (smallIconResId == 0) {
smallIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName);
if (smallIconResId == 0) {
smallIconResId = android.R.drawable.ic_dialog_info;
}
}
notification.setSmallIcon(smallIconResId);
// Large icon
if(largeIconBitmap == null) {
int largeIconResId = 0;
String largeIcon = bundle.getString("largeIcon");
if (largeIcon != null && !largeIcon.isEmpty()) {
largeIconResId = res.getIdentifier(largeIcon, "mipmap", packageName);
} else if(largeIcon == null) {
largeIconResId = res.getIdentifier("ic_launcher", "mipmap", packageName);
}
// Before Lolipop there was no large icon for notifications.
if (largeIconResId != 0 && (largeIcon != null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)) {
largeIconBitmap = BitmapFactory.decodeResource(res, largeIconResId);
}
}
if (largeIconBitmap != null){
notification.setLargeIcon(largeIconBitmap);
}
String message = bundle.getString("message");
notification.setContentText(message);
String subText = bundle.getString("subText");
if (subText != null) {
notification.setSubText(subText);
}
String bigText = bundle.getString("bigText");
if (bigText == null) {
bigText = message;
}
NotificationCompat.Style style;
if(bigPictureBitmap != null) {
style = new NotificationCompat.BigPictureStyle()
.bigPicture(bigPictureBitmap)
.setBigContentTitle(title)
.setSummaryText(message);
} else {
style = new NotificationCompat.BigTextStyle().bigText(bigText);
}
notification.setStyle(style);
Intent intent = new Intent(context, intentClass);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
bundle.putBoolean("foreground", this.isApplicationInForeground());
bundle.putBoolean("userInteraction", true);
intent.putExtra("notification", bundle);
Uri soundUri = null;
if (!bundle.containsKey("playSound") || bundle.getBoolean("playSound")) {
String soundName = bundle.getString("soundName");
if (soundName == null) {
soundName = "default";
}
soundUri = getSoundUri(soundName);
notification.setSound(soundUri);
}
if (soundUri == null || Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
notification.setSound(null);
}
if (bundle.containsKey("ongoing") || bundle.getBoolean("ongoing")) {
notification.setOngoing(bundle.getBoolean("ongoing"));
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
notification.setCategory(NotificationCompat.CATEGORY_CALL);
String color = bundle.getString("color");
int defaultColor = -1;
if (color != null) {
notification.setColor(Color.parseColor(color));
} else if (defaultColor != -1) {
notification.setColor(defaultColor);
}
}
int notificationID = Integer.parseInt(notificationIdString);
PendingIntent pendingIntent = PendingIntent.getActivity(context, notificationID, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager notificationManager = notificationManager();
long[] vibratePattern = new long[]{0};
if (!bundle.containsKey("vibrate") || bundle.getBoolean("vibrate")) {
long vibration = bundle.containsKey("vibration") ? (long) bundle.getDouble("vibration") : DEFAULT_VIBRATION;
if (vibration == 0)
vibration = DEFAULT_VIBRATION;
vibratePattern = new long[]{0, vibration};
notification.setVibrate(vibratePattern);
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// Define the shortcutId
String shortcutId = bundle.getString("shortcutId");
if (shortcutId != null) {
notification.setShortcutId(shortcutId);
}
Long timeoutAfter = (long) bundle.getDouble("timeoutAfter");
if (timeoutAfter != null && timeoutAfter >= 0) {
notification.setTimeoutAfter(timeoutAfter);
}
}
Long when = (long) bundle.getDouble("when");
if (when != null && when >= 0) {
notification.setWhen(when);
}
notification.setUsesChronometer(bundle.getBoolean("usesChronometer", false));
notification.setChannelId(channel_id);
notification.setContentIntent(pendingIntent);
JSONArray actionsArray = null;
try {
actionsArray = bundle.getString("actions") != null ? new JSONArray(bundle.getString("actions")) : null;
} catch (JSONException e) {
Log.e(LOG_TAG, "Exception while converting actions to JSON object.", e);
}
if (actionsArray != null) {
// No icon for now. The icon value of 0 shows no icon.
int icon = 0;
// Add button for each actions.
for (int i = 0; i < actionsArray.length(); i++) {
String action;
try {
action = actionsArray.getString(i);
} catch (JSONException e) {
Log.e(LOG_TAG, "Exception while getting action from actionsArray.", e);
continue;
}
Intent actionIntent = new Intent(context, PushNotificationActions.class);
actionIntent.setAction(packageName + ".ACTION_" + i);
actionIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
// Add "action" for later identifying which button gets pressed.
bundle.putString("action", action);
actionIntent.putExtra("notification", bundle);
actionIntent.setPackage(packageName);
PendingIntent pendingActionIntent = PendingIntent.getBroadcast(context, notificationID, actionIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
notification.addAction(new NotificationCompat.Action.Builder(icon, action, pendingActionIntent).build());
} else {
notification.addAction(icon, action, pendingActionIntent);
}
}
}
if (!(this.isApplicationInForeground() && bundle.getBoolean("ignoreInForeground"))) {
Notification info = notification.build();
info.defaults |= Notification.DEFAULT_LIGHTS;
if (bundle.containsKey("tag")) {
String tag = bundle.getString("tag");
notificationManager.notify(tag, notificationID, info);
} else {
notificationManager.notify(notificationID, info);
}
}
} catch (Exception e) {
Log.e(LOG_TAG, "failed to send push notification", e);
}
}
private boolean checkOrCreateChannel(NotificationManager manager, String channel_id, String channel_name, String channel_description, Uri soundUri, int importance, long[] vibratePattern, boolean showBadge) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return false;
if (manager == null)
return false;
NotificationChannel channel = manager.getNotificationChannel(channel_id);
if (
channel == null && channel_name != null && channel_description != null ||
channel != null &&
(
channel_name != null && !channel.getName().equals(channel_name) ||
channel_description != null && !channel.getDescription().equals(channel_description)
)
) {
// If channel doesn't exist create a new one.
// If channel name or description is updated then update the existing channel.
channel = new NotificationChannel(channel_id, channel_name, importance);
channel.setDescription(channel_description);
channel.enableLights(true);
channel.enableVibration(vibratePattern != null);
channel.setVibrationPattern(vibratePattern);
channel.setShowBadge(showBadge);
if (soundUri != null) {
AudioAttributes audioAttributes = new AudioAttributes.Builder()
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
.setUsage(AudioAttributes.USAGE_NOTIFICATION)
.build();
channel.setSound(soundUri, audioAttributes);
} else {
channel.setSound(null, null);
}
manager.createNotificationChannel(channel);
return true;
}
return false;
}
public boolean createChannel(ReadableMap channelInfo) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
return false;
String channelId = channelInfo.getString("channelId");
String channelName = channelInfo.getString("channelName");
String channelDescription = channelInfo.hasKey("channelDescription") ? channelInfo.getString("channelDescription") : "";
String soundName = channelInfo.hasKey("soundName") ? channelInfo.getString("soundName") : "default";
int importance = channelInfo.hasKey("importance") ? channelInfo.getInt("importance") : 4;
boolean vibrate = channelInfo.hasKey("vibrate") && channelInfo.getBoolean("vibrate");
long[] vibratePattern = vibrate ? new long[] { DEFAULT_VIBRATION } : null;
boolean showBadge = channelInfo.hasKey("showBadge") && channelInfo.getBoolean("showBadge");
NotificationManager manager = notificationManager();
Uri soundUri = getSoundUri(soundName);
return checkOrCreateChannel(manager, channelId, channelName, channelDescription, soundUri, importance, vibratePattern, showBadge);
}
public String getNotificationDefaultChannelId() {
return this.CHANNEL_ID;
}
private Uri getSoundUri(String soundName) {
if (soundName == null || "default".equalsIgnoreCase(soundName)) {
return RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
} else {
// sound name can be full filename, or just the resource name.
// So the strings 'my_sound.mp3' AND 'my_sound' are accepted
// The reason is to make the iOS and android javascript interfaces compatible
int resId;
if (context.getResources().getIdentifier(soundName, "raw", context.getPackageName()) != 0) {
resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
} else {
soundName = soundName.substring(0, soundName.lastIndexOf('.'));
resId = context.getResources().getIdentifier(soundName, "raw", context.getPackageName());
}
return Uri.parse("android.resource://" + context.getPackageName() + "/" + resId);
}
}
public Class getMainActivityClass() {
String packageName = context.getPackageName();
Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName);
String className = launchIntent.getComponent().getClassName();
try {
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
return null;
}
}
public boolean isApplicationInForeground() {
ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
List<RunningAppProcessInfo> processInfos = activityManager.getRunningAppProcesses();
if (processInfos != null) {
for (RunningAppProcessInfo processInfo : processInfos) {
if (processInfo.processName.equals(context.getPackageName())
&& processInfo.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND
&& processInfo.pkgList.length > 0) {
return true;
}
}
}
return false;
}
}
@@ -1,86 +0,0 @@
package im.status.ethereum.pushnotifications;
import android.os.Build;
import android.app.Application;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.modules.core.DeviceEventManagerModule;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Set;
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
class PushNotificationJsDelivery {
private ReactContext reactContext;
PushNotificationJsDelivery(ReactContext context){
reactContext = context;
}
String convertJSON(Bundle bundle) {
try {
JSONObject json = convertJSONObject(bundle);
return json.toString();
} catch (JSONException e) {
return null;
}
}
// a Bundle is not a map, so we have to convert it explicitly
private JSONObject convertJSONObject(Bundle bundle) throws JSONException {
JSONObject json = new JSONObject();
Set<String> keys = bundle.keySet();
for (String key : keys) {
Object value = bundle.get(key);
if (value instanceof Bundle) {
json.put(key, convertJSONObject((Bundle)value));
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
json.put(key, JSONObject.wrap(value));
} else {
json.put(key, value);
}
}
return json;
}
void notifyNotification(Bundle bundle) {
String bundleString = convertJSON(bundle);
WritableMap params = Arguments.createMap();
params.putString("dataJSON", bundleString);
sendEvent("remoteNotificationReceived", params);
}
void notifyNotificationAction(Bundle bundle) {
String bundleString = convertJSON(bundle);
WritableMap params = Arguments.createMap();
params.putString("dataJSON", bundleString);
sendEvent("notificationActionReceived", params);
}
void sendEvent(String eventName, Object params) {
if (reactContext.hasActiveCatalystInstance()) {
reactContext
.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
.emit(eventName, params);
}
}
}
@@ -1,27 +0,0 @@
package im.status.ethereum.pushnotifications;
import im.status.ethereum.pushnotifications.PushNotification;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JavaScriptModule;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import java.util.Collections;
import java.util.List;
public class PushNotificationPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
return Collections.<NativeModule>singletonList(new PushNotification(reactContext));
}
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
@@ -1,136 +0,0 @@
package im.status.ethereum.pushnotifications;
import androidx.annotation.Nullable;
import com.facebook.common.executors.CallerThreadExecutor;
import com.facebook.common.references.CloseableReference;
import com.facebook.datasource.DataSource;
import com.facebook.drawee.backends.pipeline.Fresco;
import com.facebook.imagepipeline.common.Priority;
import com.facebook.imagepipeline.core.ImagePipeline;
import com.facebook.imagepipeline.datasource.BaseBitmapDataSubscriber;
import com.facebook.imagepipeline.image.CloseableImage;
import com.facebook.imagepipeline.request.ImageRequest;
import com.facebook.imagepipeline.request.ImageRequestBuilder;
import android.util.Log;
import android.content.Context;
import android.graphics.Bitmap;
import android.net.Uri;
import java.util.concurrent.atomic.AtomicInteger;
import static im.status.ethereum.pushnotifications.PushNotification.LOG_TAG;
public class PushNotificationPicturesAggregator {
interface Callback {
public void call(Bitmap largeIconImage, Bitmap bigPictureImage);
}
private AtomicInteger count = new AtomicInteger(0);
private Bitmap largeIconImage;
private Bitmap bigPictureImage;
private Callback callback;
public PushNotificationPicturesAggregator(Callback callback) {
this.callback = callback;
}
public void setBigPicture(Bitmap bitmap) {
this.bigPictureImage = bitmap;
this.finished();
}
public void setBigPictureUrl(Context context, String url) {
if(null == url) {
this.setBigPicture(null);
return;
}
Uri uri = null;
try {
uri = Uri.parse(url);
} catch(Exception ex) {
Log.e(LOG_TAG, "Failed to parse bigPictureUrl", ex);
this.setBigPicture(null);
return;
}
final PushNotificationPicturesAggregator aggregator = this;
this.downloadRequest(context, uri, new BaseBitmapDataSubscriber() {
@Override
public void onNewResultImpl(@Nullable Bitmap bitmap) {
aggregator.setBigPicture(bitmap);
}
@Override
public void onFailureImpl(DataSource dataSource) {
aggregator.setBigPicture(null);
}
});
}
public void setLargeIcon(Bitmap bitmap) {
this.largeIconImage = bitmap;
this.finished();
}
public void setLargeIconUrl(Context context, String url) {
if(null == url) {
this.setLargeIcon(null);
return;
}
Uri uri = null;
try {
uri = Uri.parse(url);
} catch(Exception ex) {
Log.e(LOG_TAG, "Failed to parse largeIconUrl", ex);
this.setLargeIcon(null);
return;
}
final PushNotificationPicturesAggregator aggregator = this;
this.downloadRequest(context, uri, new BaseBitmapDataSubscriber() {
@Override
public void onNewResultImpl(@Nullable Bitmap bitmap) {
aggregator.setLargeIcon(bitmap);
}
@Override
public void onFailureImpl(DataSource dataSource) {
aggregator.setLargeIcon(null);
}
});
}
private void downloadRequest(Context context, Uri uri, BaseBitmapDataSubscriber subscriber) {
ImageRequest imageRequest = ImageRequestBuilder
.newBuilderWithSource(uri)
.setRequestPriority(Priority.HIGH)
.setLowestPermittedRequestLevel(ImageRequest.RequestLevel.FULL_FETCH)
.build();
if(!Fresco.hasBeenInitialized()) {
Fresco.initialize(context);
}
DataSource<CloseableReference<CloseableImage>> dataSource = Fresco.getImagePipeline().fetchDecodedImage(imageRequest, context);
dataSource.subscribe(subscriber, CallerThreadExecutor.getInstance());
}
private void finished() {
synchronized(this.count) {
int val = this.count.incrementAndGet();
if(val >= 2 && this.callback != null) {
this.callback.call(this.largeIconImage, this.bigPictureImage);
}
}
}
}
@@ -747,29 +747,13 @@ RCT_EXPORT_METHOD(stopWallet) {
StatusgoStopWallet();
}
RCT_EXPORT_METHOD(startWallet:(BOOL)watchNewBlocks) {
RCT_EXPORT_METHOD(startWallet) {
#if DEBUG
NSLog(@"StartWallet() method called");
#endif
StatusgoStartWallet(watchNewBlocks);
StatusgoStartWallet();
}
RCT_EXPORT_METHOD(stopLocalNotifications) {
#if DEBUG
NSLog(@"StopLocalNotifications() method called");
#endif
StatusgoStopLocalNotifications();
}
RCT_EXPORT_METHOD(startLocalNotifications) {
#if DEBUG
NSLog(@"StartLocalNotifications() method called");
#endif
StatusgoStartLocalNotifications();
}
RCT_EXPORT_METHOD(setBlankPreviewFlag:(BOOL *)newValue)
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
-17
View File
@@ -38,23 +38,6 @@ If copying from Nix Cache times out you can adjust the timeout by changing [`nix
stalled-download-timeout = 9001
```
## NDK Bundle Download Failures
There is a known issue([#11111](https://github.com/status-im/status-react/issues/11111)) where the fetching of Android NDK Bundle from our own cache host fails in various different ways:
```
unable to download 'https://nix-cache.status.im/nar/64g5wharwjj040rg1v8jnc5qhv1hkgds.nar':
HTTP error 200 (curl error: Stream error in the HTTP/2 framing layer)
```
```
unable to download 'https://nix-cache.status.im/nar/64g5wharwjj040rg1v8jnc5qhv1hkgds.nar':
HTTP error 200 (curl error: Transferred a partial file)
```
```
NAR for '/nix/store/psx79cnz1khfjlzkw3j8x9sb1jhk1v1a-ndk-bundle-21.0.6113669' fetched from 'https://nix-cache.status.im' is incomplete
```
Currently the simplest temporary solution is to edit `nix/nix.conf` and comment out the `extra-substituters` line.
This should allow Nix to download the NDK Bundle directly from Google servers rather than from our own cache.
## `extra-sandbox-paths` Is a Restricted Setting
When building Android on NixOS you might encounter the following error:
-31
View File
@@ -42,34 +42,3 @@ dr-xr-xr-x 3 root root 3 Jan 1 1970 commons-cli
# Dependencies
One dependency these scripts require is the [go-maven-resolver](https://github.com/status-im/go-maven-resolver) which turns a list of packages into list of all URLs of POMs for them and their dependencies.
# Known Issues
One edge case that is currently not handled by this setup is an addition of a new dependency that requires a version of Gradle we don't have. In that case running `make nix-update-gradle` would fail with:
```
AILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':react-native-example-project'.
> Could not resolve all artifacts for configuration ':react-native-example-project:classpath'.
> Could not find com.android.tools.build:gradle:3.4.0.
Searched in the following locations:
- file:/nix/store/34a4qd5qhg2a9kq6a0q9lp7hgmi48q4x-status-react-maven-deps/com/android/tools/build/gradle/3.4.0/gradle-3.4.0.pom
- file:/nix/store/34a4qd5qhg2a9kq6a0q9lp7hgmi48q4x-status-react-maven-deps/com/android/tools/build/gradle/3.4.0/gradle-3.4.0.jar
Required by:
project :react-native-example-project
```
This happens because `get_projects.sh` and `get_deps.sh` depend on running Gradle to generate their output, and that will not work because Gradle cannot find the matching JAR for the new dependency.
A manual solution would involve adding that specific Gradle version into `deps.urls`:
```
echo com.android.tools.build:gradle:3.4.0 | go-maven-resolver >> nix/deps/gradle/deps.urls
```
Then you'll need to remove duplicates and sort `deps.urls`:
```
sort -o nix/deps/gradle/deps.urls nix/deps/gradle/deps.urls
```
And finally generate the `deps.json` for Nix using:
```
nix/deps/gradle/generate.sh gen_deps_json
```
+61 -71
View File
@@ -3542,30 +3542,30 @@
},
{
"path": "com/github/status-im/status-keycard-java/android/3.0.4/android-3.0.4",
"path": "com/github/status-im/status-keycard-java/android/3.0.1/android-3.0.1",
"host": "https://repository.sonatype.org/content/groups/sonatype-public-grid",
"type": "jar",
"pom": {
"sha1": "e6e1933d85ac05b51953effc21ab893679f5864b",
"sha256": "1y9kqp3qgx3kqaf6vm6iwphdj8caqd9x6kncjsnp6f0nirp5ijzq"
"sha1": "e84c8fef96ee43bb485ca30bab3736fadf956e4d",
"sha256": "0ahqp7lsanj8x8k46sz5kmv7yz081r5j5vd8nly1ri5vj88nrj3y"
},
"jar": {
"sha1": "dca6e47e087a649643bbad1c1feb4b0b5e1aaf45",
"sha256": "0krxjj5h5zmap4645llscwkmyszm8qyngwg8vi8ds1mf2kp0jaz1"
"sha1": "d3055cf1607314c5ea4fa6fc3a259267dfad97ef",
"sha256": "0dv0lm2x85ijk8kaxb3fylmkp4hjgd8da3d95m5zhw82wbl4n1ca"
}
},
{
"path": "com/github/status-im/status-keycard-java/lib/3.0.4/lib-3.0.4",
"path": "com/github/status-im/status-keycard-java/lib/3.0.1/lib-3.0.1",
"host": "https://repository.sonatype.org/content/groups/sonatype-public-grid",
"type": "jar",
"pom": {
"sha1": "718d3d286d53186552a84cee1a1283e0975da789",
"sha256": "0s2mbx1638qig4m802rf0ill9bghgga8w3ld0vpcz6x7h2kmvv6g"
"sha1": "89f8e7342acca331648f4fe82c4471ebbfa2064c",
"sha256": "14g7c5x2mdf1fa48sb0c9hg1crr9xq4dz812kdnydylp108ln5gj"
},
"jar": {
"sha1": "b2afa2711a9898d9aeb188195edde53c00984543",
"sha256": "16c7r0667pbgljx1p8zmvahv1igcnway1qjqprbn0n4ny1vy2imm"
"sha1": "eb2728acc9f601ba1ee4750804104795524e31fd",
"sha256": "19dk9752cga9dliv8n3sw3lxk41kamz6vxmkn0v6qxx14ll80mgi"
}
},
@@ -3668,16 +3668,16 @@
},
{
"path": "commons-codec/commons-codec/1.15/commons-codec-1.15",
"path": "commons-codec/commons-codec/1.14/commons-codec-1.14",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "c08f2dcdbba1a9466f3f9fa05e669fd61c3a47b7",
"sha256": "0n5b40x4wsmygna7fivix3cy9rs2yv5ikx30g141adsslfcf2vn8"
"sha1": "3e98fb226cb1c6a9caa5fdb2a522ba42f4ea16d2",
"sha256": "19mp203aw77s79mv7gqcqdg0i8mww4dcih66pvw6z5s9z31611cn"
},
"jar": {
"sha1": "49d94806b6e3dc933dacbd8acb0fdbab8ebd1e5d",
"sha256": "0qzd8v96j4x7jjcfpvvdh9ar1xhwxpxi2rh51nzhj0br7bbgdsdk"
"sha1": "3cb1181b2141a7e752f5bdc998b7ef1849f726cf",
"sha256": "1s9kmlbms3hbmvp3rd4ff45h61ly05rjikv4xlfkirdb7zwy8a51"
}
},
@@ -5676,16 +5676,16 @@
},
{
"path": "com/squareup/okhttp3/okhttp/4.9.0/okhttp-4.9.0",
"path": "com/squareup/okhttp3/okhttp/4.8.1/okhttp-4.8.1",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "8806abdf57ce7ec2d72b5a89eb79ec8907af7eb0",
"sha256": "125x8lm1iz2hf9dsxhd25dgpw4x70s2bravwj609wl44wzfr52ag"
"sha1": "06674a5ab0fe82b134a2fe02a18ccf9c51e9a0b2",
"sha256": "08dyq3vxk27na7d5g3p100vi5ihplf6ylrsyibg7lzfc4sxdawmc"
},
"jar": {
"sha1": "08e17601d3bdc8cf57902c154de021931d2c27c1",
"sha256": "0z0zaw06f2ihgs1rik50b4y3sjkgk6nwqqv20ksbj0mhxh2bphnv"
"sha1": "dd36d61fbfa0a33c805e3d92f64e0832234c56c6",
"sha256": "1scg21n0a41rhv2n4crx62kmfl5yavj45hgl97acw3c7kccgaggi"
}
},
@@ -5724,16 +5724,16 @@
},
{
"path": "com/squareup/okio/okio/2.8.0/okio-2.8.0",
"path": "com/squareup/okio/okio/2.7.0/okio-2.7.0",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "db3559887f215bc3cdbb4ad37d246d04fbbdff8e",
"sha256": "10clihpazwlsml3jhn2pqi8w37cs5a07d1gyr1x46zsczml40896"
"sha1": "c171afa3f9084ec998ad1ff7b24e7b857b5bdf24",
"sha256": "1p1fnhr6rbry0r1y97mwr5fmb6ld5bf7gd7234yafjj3fhjvh1hw"
},
"jar": {
"sha1": "49b64e09d81c0cc84b267edd0c2fd7df5a64c78c",
"sha256": "1j5v14ps6s5c9i2ran6zcm2gmqicvzjlcgrrlpccsbwqfdpb15j4"
"sha1": "1181a029fa94760ccf46f264bc06ca2e60262f8f",
"sha256": "1fc65k52z6zxrbahs0fzigpyb0290870fwxslgc5c0hdvsx05ck3"
}
},
@@ -6699,16 +6699,6 @@
}
},
{
"path": "org/apache/apache/23/apache-23",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
"sha1": "0404949e96725e63a10a6d8f9d9b521948d170d5",
"sha256": "07298c2jfkdb6gaxidig2pnl0ckdjfi9qqy5z9vnbwr30r76445w"
}
},
{
"path": "org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1",
"host": "https://repo.maven.apache.org/maven2",
@@ -6866,12 +6856,12 @@
},
{
"path": "org/apache/commons/commons-parent/52/commons-parent-52",
"path": "org/apache/commons/commons-parent/50/commons-parent-50",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
"sha1": "004ee86dedc66d0010ccdc29e5a4ce014c057854",
"sha256": "0bjhnkdhdsdcc12daiqhbwxwvjxlkqplmbns8bzw7r4q9vryinvm"
"sha1": "b47c55b7ee647e1c78546791e7f4fe59b842c320",
"sha256": "01kz260pqzil5h2rv1rjvrpf4aq7r3pxalzmcxc4n1s7yyrjsykv"
}
},
@@ -7368,16 +7358,16 @@
},
{
"path": "org/checkerframework/checker-qual/3.6.1/checker-qual-3.6.1",
"path": "org/checkerframework/checker-qual/3.6.0/checker-qual-3.6.0",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "5a9e629db8b2dc58bf7199c4c5a9c2aa3226540f",
"sha256": "0x2fg03ccsrzhh2x5jknqm9g4cszcyqm9wasm69pwzvai1a23pbs"
"sha1": "cc9a54c245d87d07533a5534ec607d88a66ea82a",
"sha256": "16hhzdvv7jlwzvfjaf5f2l4b7n0lbwnwgkbfhx3i6r7zgpw320yl"
},
"jar": {
"sha1": "52ca62b41f68584c4d2de39d6176758e9383d0b6",
"sha256": "0a7q2lhqbrgf5ll16zqima1q6rpn6x2m5fnli21ahlc1b4n4dl3w"
"sha1": "b39405a5894b39073ad0e70671edd39b673e259a",
"sha256": "0c751lskwkdkkl9ch6scfcxim2sn0knl6mmwzskfq2dpdb4djkrv"
}
},
@@ -7774,12 +7764,12 @@
},
{
"path": "org/jacoco/org.jacoco.build/0.8.6/org.jacoco.build-0.8.6",
"path": "org/jacoco/org.jacoco.build/0.8.5/org.jacoco.build-0.8.5",
"host": "https://repo.maven.apache.org/maven2",
"type": "pom",
"pom": {
"sha1": "3fb028eaf46f792cfd65b2d65be7e5d175623378",
"sha256": "1yahzgqvhsghcvss2nm9pjm53qypv07fr8ndni2irkdqskzpf56r"
"sha1": "ad6a35af94c242182132ceba52f07620ca80832a",
"sha256": "1jn13ax45dyp6j5ly95p4z8qd6990884v8279zmxnzb44z940vmd"
}
},
@@ -7798,16 +7788,16 @@
},
{
"path": "org/jacoco/org.jacoco.core/0.8.6/org.jacoco.core-0.8.6",
"path": "org/jacoco/org.jacoco.core/0.8.5/org.jacoco.core-0.8.5",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "6f4a9abb3333a92f028bf444b596a7b7648db111",
"sha256": "1pk3rwz5fm9ns70rf4r2nyly56xg5kq10hqqamzsyrvh57ggxfx3"
"sha1": "dc976cf0d68a488c893d9b7957d63e61d597c85a",
"sha256": "1vvlncgffkg9yv1djlnmv6vsi6pmzwx393bv9xdxyc87csz9pxrd"
},
"jar": {
"sha1": "8c20544d06b8a54de1a585e4fcd0b101c0b433d9",
"sha256": "1zxn67mkafvk9x5vjdryyzn25yvmk7vgnfp3f2mpdyh1piiwnjwn"
"sha1": "1ac96769aa83e5492d1a1a694774f6baec4eb704",
"sha256": "1p8d3x473wi3ccpd1kigfps4sfxqn9l9a279kqsh777qa38ihn4l"
}
},
@@ -8260,30 +8250,30 @@
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.4.0/kotlin-stdlib-common-1.4.0",
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.3.70/kotlin-stdlib-common-1.3.70",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "03055a223c66d74a15ae3f53870e910e769483ff",
"sha256": "02mx38iv2y3afvmv7bgmqrzsfgz5bm484ryf264gaj1jb929mrcq"
"sha1": "bd1d0642aedfd3780a730235af7499706225ccb3",
"sha256": "1qr8i917sznbmrdsvk8q4ggjic8k7qsij4337zyrfs3mmby2n5kn"
},
"jar": {
"sha1": "1c752cce0ead8d504ccc88a4fed6471fd83ab0dd",
"sha256": "1lgpr4rrvmnm4j4v10jhykgy8b281drkmi7nf7lfajsdsw2f00c6"
"sha1": "3fa8dd6c896d635e78201e5e811545f3846dec04",
"sha256": "0l1sylyady51n9c882l67w72a2sp7c9ip5998jr2z3w9qk7pf8vf"
}
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.4.10/kotlin-stdlib-common-1.4.10",
"path": "org/jetbrains/kotlin/kotlin-stdlib-common/1.3.72/kotlin-stdlib-common-1.3.72",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "a7a2da276e4c795619d6dd862cf8db356906ca3c",
"sha256": "002xa53xg74zhfsgh6p17xzs6k2lbzj91zx694mp9pnllxr0wj33"
"sha1": "c4e521d2c0af9e771afbfc11fff4b2f5111b2678",
"sha256": "1p79gfryfclii2cjda1rc8a0swcy3f8wibyw614q0d09bggiwy14"
},
"jar": {
"sha1": "6229be3465805c99db1142ad75e6c6ddeac0b04c",
"sha256": "1zkl29qhssa8m3k92z7nl2fjyf71b1byv12xb4ipb3566vag50a6"
"sha1": "6ca8bee3d88957eaaaef077c41c908c9940492d8",
"sha256": "0fi0f98xmb05b8hhc093nzsjky0f4g73kk5i50b0qj1yhr91azay"
}
},
@@ -8484,30 +8474,30 @@
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.4.0/kotlin-stdlib-1.4.0",
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.3.70/kotlin-stdlib-1.3.70",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "4758d9ec733fd494e6e67fe493d6ac60cd30659d",
"sha256": "0jkdpk6qkhf8jwqp6jrwwqnr39p8z56kmnyg6dg03f92qjppvdix"
"sha1": "018c32fc0020da57fc1ea22f6d276d672ea91ab1",
"sha256": "0j2hs6zpcrnllx3pzp0nqfz7snsqb75135mb4h4jx33kqlahnhgz"
},
"jar": {
"sha1": "63e75298e93d4ae0b299bb869cf0c627196f8843",
"sha256": "1cbyxn0wwjcawl6klm2dgcxxhl3xgj4f5w8nk8bqy1g9wvk16sk1"
"sha1": "e5d97e25bb5b30dcfc022ec1c8f3959a875257fb",
"sha256": "0crjz4wykw5qrb5mxg5nsl06crlfnawvwsld53g1qa1alc73q11j"
}
},
{
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.4.10/kotlin-stdlib-1.4.10",
"path": "org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72",
"host": "https://repo.maven.apache.org/maven2",
"type": "jar",
"pom": {
"sha1": "1ae8d0e617a4e272ce07664ad928c57b171e31f9",
"sha256": "0qi77kk5dssssijv0j4fav5zgh5rbxvjrm943spj79dx9fxwzfd4"
"sha1": "aecbe532bd46a37d2217a63cc0fed4eca0bd71cc",
"sha256": "10cl234gh961grj2rmvq89cb9azzscg3w5lac92kracyjr55f3ag"
},
"jar": {
"sha1": "ea29e063d2bbe695be13e9d044dcfb0c7add398e",
"sha256": "1aldbd3x859ldvyhlh05bllhnd48l4hwz6l3q4qvjhn0habv1v01"
"sha1": "8032138f12c0180bc4e51fe139d4c52b46db6109",
"sha256": "0sxisi1q565c8nwvd4pacjjwbhjdkknjyaw0wqdnvkdskqsafmiq"
}
},
+2 -2
View File
@@ -297,8 +297,8 @@ com.facebook.soloader:nativeloader:0.8.2
com.facebook.soloader:soloader:0.8.0
com.facebook.soloader:soloader:0.8.2
com.facebook.yoga:proguard-annotations:1.14.1
com.github.status-im.status-keycard-java:android:3.0.4
com.github.status-im.status-keycard-java:lib:3.0.4
com.github.status-im.status-keycard-java:android:3.0.1
com.github.status-im.status-keycard-java:lib:3.0.1
com.github.status-im:function:0.0.1
com.github.yalantis:ucrop:2.2.5-native
com.googlecode.json-simple:json-simple:1.1
+13 -14
View File
@@ -251,8 +251,8 @@ https://repository.sonatype.org/content/groups/sonatype-public-grid/com/facebook
https://repository.sonatype.org/content/groups/sonatype-public-grid/com/facebook/flipper/flipper/0.35.0/flipper-0.35.0.pom
https://repository.sonatype.org/content/groups/sonatype-public-grid/com/facebook/yoga/proguard-annotations/1.14.1/proguard-annotations-1.14.1.pom
https://repository.sonatype.org/content/groups/sonatype-public-grid/com/github/status-im/function/0.0.1/function-0.0.1.pom
https://repository.sonatype.org/content/groups/sonatype-public-grid/com/github/status-im/status-keycard-java/android/3.0.4/android-3.0.4.pom
https://repository.sonatype.org/content/groups/sonatype-public-grid/com/github/status-im/status-keycard-java/lib/3.0.4/lib-3.0.4.pom
https://repository.sonatype.org/content/groups/sonatype-public-grid/com/github/status-im/status-keycard-java/android/3.0.1/android-3.0.1.pom
https://repository.sonatype.org/content/groups/sonatype-public-grid/com/github/status-im/status-keycard-java/lib/3.0.1/lib-3.0.1.pom
https://repository.sonatype.org/content/groups/sonatype-public-grid/com/github/yalantis/ucrop/2.2.5-native/ucrop-2.2.5-native.pom
https://repository.sonatype.org/content/groups/sonatype-public-grid/org/jetbrains/trove4j/trove4j/20160824/trove4j-20160824.pom
https://repo.maven.apache.org/maven2/commons-cli/commons-cli/1.2/commons-cli-1.2.pom
@@ -260,7 +260,7 @@ https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.4/commons-cod
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.6/commons-codec-1.6.pom
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.9/commons-codec-1.9.pom
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.10/commons-codec-1.10.pom
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.15/commons-codec-1.15.pom
https://repo.maven.apache.org/maven2/commons-codec/commons-codec/1.14/commons-codec-1.14.pom
https://repo.maven.apache.org/maven2/commons-io/commons-io/2.4/commons-io-2.4.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.pom
https://repo.maven.apache.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.pom
@@ -410,11 +410,11 @@ https://repo.maven.apache.org/maven2/com/squareup/javapoet/1.8.0/javapoet-1.8.0.
https://repo.maven.apache.org/maven2/com/squareup/javawriter/2.5.0/javawriter-2.5.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp-urlconnection/3.12.1/okhttp-urlconnection-3.12.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/3.12.1/okhttp-3.12.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/4.9.0/okhttp-4.9.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/okhttp/4.8.1/okhttp-4.8.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okhttp3/parent/3.12.1/parent-3.12.1.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio-parent/1.15.0/okio-parent-1.15.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/1.15.0/okio-1.15.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.8.0/okio-2.8.0.pom
https://repo.maven.apache.org/maven2/com/squareup/okio/okio/2.7.0/okio-2.7.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/1.2.0/all-1.2.0.pom
https://repo.maven.apache.org/maven2/com/sun/activation/all/2.0.0-RC3/all-2.0.0-RC3.pom
https://repo.maven.apache.org/maven2/com/sun/activation/jakarta.activation/2.0.0-RC3/jakarta.activation-2.0.0-RC3.pom
@@ -494,7 +494,6 @@ https://repo.maven.apache.org/maven2/org/apache/apache/15/apache-15.pom
https://repo.maven.apache.org/maven2/org/apache/apache/16/apache-16.pom
https://repo.maven.apache.org/maven2/org/apache/apache/18/apache-18.pom
https://repo.maven.apache.org/maven2/org/apache/apache/21/apache-21.pom
https://repo.maven.apache.org/maven2/org/apache/apache/23/apache-23.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.8.1/commons-compress-1.8.1.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-compress/1.12/commons-compress-1.12.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-lang3/3.3.2/commons-lang3-3.3.2.pom
@@ -509,7 +508,7 @@ https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/34/common
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/35/commons-parent-35.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/39/commons-parent-39.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/48/commons-parent-48.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/52/commons-parent-52.pom
https://repo.maven.apache.org/maven2/org/apache/commons/commons-parent/50/commons-parent-50.pom
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.1.1/httpclient-4.1.1.pom
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.2.6/httpclient-4.2.6.pom
https://repo.maven.apache.org/maven2/org/apache/httpcomponents/httpclient/4.5.2/httpclient-4.5.2.pom
@@ -550,7 +549,7 @@ https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.56/bcprov
https://repo.maven.apache.org/maven2/org/bouncycastle/bcprov-jdk15on/1.60/bcprov-jdk15on-1.60.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-compat-qual/2.5.5/checker-compat-qual-2.5.5.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/2.5.2/checker-qual-2.5.2.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.6.1/checker-qual-3.6.1.pom
https://repo.maven.apache.org/maven2/org/checkerframework/checker-qual/3.6.0/checker-qual-3.6.0.pom
https://repo.maven.apache.org/maven2/org/codehaus/codehaus-parent/4/codehaus-parent-4.pom
https://repo.maven.apache.org/maven2/org/codehaus/groovy/groovy-all/2.4.15/groovy-all-2.4.15.pom
https://repo.maven.apache.org/maven2/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.pom
@@ -583,9 +582,9 @@ https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-core/2.2/hamcrest-cor
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest-parent/1.3/hamcrest-parent-1.3.pom
https://repo.maven.apache.org/maven2/org/hamcrest/hamcrest/2.2/hamcrest-2.2.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.build/0.7.4.201502262128/org.jacoco.build-0.7.4.201502262128.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.build/0.8.6/org.jacoco.build-0.8.6.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.build/0.8.5/org.jacoco.build-0.8.5.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.core/0.7.4.201502262128/org.jacoco.core-0.7.4.201502262128.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.core/0.8.6/org.jacoco.core-0.8.6.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.core/0.8.5/org.jacoco.core-0.8.5.pom
https://repo.maven.apache.org/maven2/org/jacoco/org.jacoco.report/0.7.4.201502262128/org.jacoco.report-0.7.4.201502262128.pom
https://repo.maven.apache.org/maven2/org/jdom/jdom2/2.0.6/jdom2-2.0.6.pom
https://repo.maven.apache.org/maven2/org/jetbrains/annotations/13.0/annotations-13.0.pom
@@ -618,8 +617,8 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.20/kotlin-stdlib-common-1.3.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.31/kotlin-stdlib-common-1.3.31.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.50/kotlin-stdlib-common-1.3.50.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.0/kotlin-stdlib-common-1.4.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.4.10/kotlin-stdlib-common-1.4.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.70/kotlin-stdlib-common-1.3.70.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-common/1.3.72/kotlin-stdlib-common-1.3.72.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.2.71/kotlin-stdlib-jdk7-1.2.71.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.20/kotlin-stdlib-jdk7-1.3.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib-jdk7/1.3.50/kotlin-stdlib-jdk7-1.3.50.pom
@@ -634,8 +633,8 @@ https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.0/ko
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.20/kotlin-stdlib-1.3.20.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.31/kotlin-stdlib-1.3.31.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.50/kotlin-stdlib-1.3.50.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.4.0/kotlin-stdlib-1.4.0.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.4.10/kotlin-stdlib-1.4.10.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.70/kotlin-stdlib-1.3.70.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-stdlib/1.3.72/kotlin-stdlib-1.3.72.pom
https://repo.maven.apache.org/maven2/org/jetbrains/kotlin/kotlin-util-io/1.3.50/kotlin-util-io-1.3.50.pom
https://repo.maven.apache.org/maven2/org/junit/jupiter/junit-jupiter-api/5.5.2/junit-jupiter-api-5.5.2.pom
https://repo.maven.apache.org/maven2/org/junit/platform/junit-platform-commons/1.5.2/junit-platform-commons-1.5.2.pom
+30 -50
View File
@@ -26,45 +26,6 @@ DEPS_JSON="${CUR_DIR}/deps.json"
# Raise limit of file descriptors
ulimit -n 16384
# Generate list of Gradle sub-projects.
function gen_proj_list() {
${CUR_DIR}/get_projects.sh | sort -u -o ${PROJ_LIST}
echo -e "Found ${GRN}$(wc -l < ${PROJ_LIST})${RST} sub-projects..."
}
# Check each sub-project in parallel, the ":" is for local deps.
function gen_deps_list() {
PROJECTS=$(cat ${PROJ_LIST})
${CUR_DIR}/get_deps.sh ":" ${PROJECTS[@]} | sort -uV -o ${DEPS_LIST}
echo -e "${CLR}Found ${GRN}$(wc -l < ${DEPS_LIST})${RST} direct dependencies..."
}
# Find download URLs for each dependency.
function gen_deps_urls() {
cat ${DEPS_LIST} | go-maven-resolver | sort -uV -o ${DEPS_URLS}
echo -e "${CLR}Found ${GRN}$(wc -l < ${DEPS_URLS})${RST} dependency URLs..."
}
# Generate the JSON that Nix will consume.
function gen_deps_json() {
# Open the Nix attribute set.
echo -n "[" > ${DEPS_JSON}
# Format URLs into a Nix consumable file.
URLS=$(cat ${DEPS_URLS})
parallel --will-cite --keep-order \
"${CUR_DIR}/url2json.sh" \
::: ${URLS} \
>> ${DEPS_JSON}
# Drop tailing comma on last object, stupid JSON
sed -i '$ s/},/}/' ${DEPS_JSON}
# Close the Nix attribute set
echo "]" >> ${DEPS_JSON}
}
# ------------------------------------------------------------------------------
echo "Regenerating Nix files..."
# Gradle needs to be run in 'android' subfolder
@@ -73,18 +34,37 @@ cd $GIT_ROOT/android
# Stop gradle daemons to avoid locking
./gradlew --stop >/dev/null
# A way to run a specific stage of generation
if [[ -n "${1}" ]] && type ${1} > /dev/null; then
${1}; exit 0
elif [[ -n "${1}" ]]; then
echo "No such function: ${1}"; exit 1
fi
# Generate list of Gradle sub-projects ----------------------------------------
${CUR_DIR}/get_projects.sh | sort -u -o ${PROJ_LIST}
# Run each stage in order
gen_proj_list
gen_deps_list
gen_deps_urls
gen_deps_json
echo -e "Found ${GRN}$(wc -l < ${PROJ_LIST})${RST} sub-projects..."
# Check each sub-project in parallel, the ":" is for local deps ---------------
PROJECTS=$(cat ${PROJ_LIST})
${CUR_DIR}/get_deps.sh ":" ${PROJECTS[@]} | sort -uV -o ${DEPS_LIST}
echo -e "${CLR}Found ${GRN}$(wc -l < ${DEPS_LIST})${RST} direct dependencies..."
# Find download URLs for each dependency --------------------------------------
cat ${DEPS_LIST} | go-maven-resolver | sort -uV -o ${DEPS_URLS}
echo -e "${CLR}Found ${GRN}$(wc -l < ${DEPS_URLS})${RST} dependency URLs..."
# Open the Nix attribute set --------------------------------------------------
echo -n "[" > ${DEPS_JSON}
# Format URLs into a Nix consumable file.
URLS=$(cat ${DEPS_URLS})
parallel --will-cite --keep-order \
"${CUR_DIR}/url2json.sh" \
::: ${URLS} \
>> ${DEPS_JSON}
# Drop tailing comma on last object, stupid JSON
sed -i '$ s/},/}/' ${DEPS_JSON}
# Close the Nix attribute set
echo "]" >> ${DEPS_JSON}
REL_DEPS_JSON=$(realpath --relative-to=${PWD} ${DEPS_JSON})
echo -e "${CLR}Generated Nix deps file: ${REL_DEPS_JSON#../}"
-18
View File
@@ -1,18 +0,0 @@
# Description
This Nix derivation takes the result of the [`nix/deps/nodejs/default.nix`](../nodejs/default.nix) derivation and adjusts it for use with Gradle.
# Details
Modules provided by `yarn2nix` are normally fine, but we use `react-native-*` packages which have their own `gradle.build` files that reference external Maven repositories:
```js
repositories {
google()
jcenter()
}
```
And these need to be patched and replaced with `mavenLocal()` to make sure Gradle doesn't try to fetch dependencies from remote repos.
This derivation symlinks most of the modules found in the `yarn2nix` result and copies the ones that require patching of `gradle.build` files in `patchGradlePhase`.
It also applies other fixes like making `BuildId` static in `patchBuildIdPhase` and fixing a Hermes bug in `patchHermesPhase`.
+18 -24
View File
@@ -6,14 +6,8 @@
stdenv.mkDerivation {
name = "${deps.nodejs.name}-patched";
phases = [
"unpackPhase"
"patchGradlePhase"
"patchBuildIdPhase"
"patchHermesPhase"
"patchJavaPhase"
"installPhase"
];
phases = [ "unpackPhase" "patchPhase" "installPhase" ];
# First symlink all modules as is
# WARNING: Metro has issues when dealing with symlinks!
@@ -25,10 +19,10 @@ stdenv.mkDerivation {
cp -r ${deps.nodejs}/node_modules/.bin ./node_modules/
'';
# Patch build.gradle files in 'react-native-*' dependencies to replace
# maven and google central repositories with our own local directories.
# This prevents the builder from downloading Maven artifacts
patchGradlePhase = ''
# Then patch the modules that have build.gradle files
patchPhase = ''
# Patch maven and google central repositories with our own local directories.
# This prevents the builder from downloading Maven artifacts
for modBuildGradle in $(find -L ./node_modules -name build.gradle); do
relativeToNode=''${modBuildGradle#*node_modules/}
moduleName=''${relativeToNode%%/*}
@@ -39,26 +33,26 @@ stdenv.mkDerivation {
fi
${patchMavenSources} $modBuildGradle
done
'';
# Do not add a BuildId to the generated libraries, for reproducibility
patchBuildIdPhase = ''
patchShebangs ./node_modules
# Do not add a BuildId to the generated libraries, for reproducibility
substituteInPlace ./node_modules/react-native/ReactAndroid/src/main/jni/Application.mk --replace \
'-Wl,--build-id' \
'-Wl,--build-id=none'
'';
# Fix bugs in Hermes usage:
# https://github.com/facebook/react-native/issues/25601#issuecomment-510856047
# - Make PR builds also count as release builds
# - Fix issue where hermes command is being called with same input/output file
patchHermesPhase = ''
# Fix bugs in Hermes usage:
# https://github.com/facebook/react-native/issues/25601#issuecomment-510856047
# - Make PR builds also count as release builds
# - Fix issue where hermes command is being called with same input/output file
substituteInPlace ./node_modules/react-native/react.gradle --replace \
'targetName.toLowerCase().contains("release")' \
'!targetName.toLowerCase().contains("debug")'
'';
# Patch Java files in modules which are not yet ported to AndroidX
patchJavaPhase = ''
# Patch Java files in modules which are not yet ported to AndroidX
${nodejs}/bin/node ./node_modules/jetifier/bin/jetify
'';
installPhase = ''
mkdir -p $out
cp -R node_modules $out/
-58
View File
@@ -1,58 +0,0 @@
# Description
This derivation uses a [yarn2nix](https://github.com/nix-community/yarn2nix) to generate a Nix store package containing all NodeJS dependencies.
# Details
If you look at [`nix/deps/nodejs/default.nix`](./default.nix) you'll see that it it loads `package.json` and `yarn.lock` files and uses them to generate the derivation:
```sh
> make nix-repl
Welcome to Nix version 2.3.9. Type :? for help.
nix-repl> pkgs.deps.nodejs
«derivation /nix/store/23mpmpjjnq7miclv6bc6ilgypy8wz69p-status-react-node-deps-1.8.0.drv»
```
You can build the derivation:
```
nix-repl> :b pkgs.deps.nodejs
this derivation produced the following outputs:
out -> /nix/store/dqb2cjyz1g6n7jic07058y26lnmgaaz9-status-react-node-deps-1.8.0
```
And look inside:
```
> cd /nix/store/dqb2cjyz1g6n7jic07058y26lnmgaaz9-status-react-node-deps-1.8.0
> ls
deps node_modules
> ls node_modules | grep react-native-image
react-native-image-crop-picker
react-native-image-resizer
react-native-image-viewing
```
# Known Issues
It's important that dependencies from GitHub are added in a correct format:
```
git+https://github.com/status-im/bignumber.js.git#v4.0.2-status
```
Notice three things:
* `git+` prefix for the `https://` URL
* Repository name ends with `.git`
* Tag or branch is added after `#` character
__WARNING__: Using branches can cause dependencies to change their hash and cause builds to fail. Using them during development is fine, but tags should be used in the final version.
If this format is not used correctly you can see issues like:
```
fatal: unable to access 'https://github.com/status-im/bignumber.js.git/': Could not resolve host: github.com
```
or
```
error Couldn't find any versions for "bignumber.js" that matches "github.com/status-im/bignumber.js.git#v4.0.2-status" in our cache (possible versions are ""). This is usually caused by a missing entry in the lockfile, running Yarn without the --offline flag may help fix this issue.
```
or
```
error Can't make a request in offline mode ("https://codeload.github.com/status-im/bignumber.js/tar.gz/f322b670969512a35c84441036a0ba4836a96428")
```
+9 -5
View File
@@ -1,10 +1,14 @@
{ lib, yarn2nix-moretea }:
# Create a yarn package for our project that contains all the dependecies.
yarn2nix-moretea.mkYarnModules rec {
pname = "status-react";
name = "${pname}-node-deps-${version}";
let
version = lib.fileContents ../../../VERSION;
yarnLock = ../../../yarn.lock;
packageJSON = ../../../package.json;
}
packageJSONContent = lib.importJSON packageJSON;
in
# Create a yarn package for our project that contains all the dependecies.
yarn2nix-moretea.mkYarnModules rec {
pname = "status-react";
name = "${pname}-node-deps-${version}";
inherit version packageJSON yarnLock;
}
@@ -1,6 +1,7 @@
# Helper for verifying an environment variable is set
name: ''
if [[ -z ''$${name} ]]; then
echo 'WARNING! Env var not set: ${name}' >&2
echo 'Not env var set: ${name}' >&2
exit 1
fi
''
+1 -1
View File
@@ -4,5 +4,5 @@
getConfig = import ./getConfig.nix { inherit lib config; };
mkFilter = import ./mkFilter.nix { inherit lib; };
mergeSh = import ./mergeSh.nix { inherit lib; };
checkEnvVarSet = import ./checkEnvVarSet.nix;
assertEnvVarSet = import ./assertEnvVarSet.nix;
}
-1
View File
@@ -47,7 +47,6 @@ stdenv.mkDerivation {
# For optional INFURA_TOKEN variable
secretsPhase = if (secretsFile != "") then ''
source "${secretsFile}"
${lib.checkEnvVarSet "INFURA_TOKEN"}
'' else ''
echo "No secrets provided!"
'';
+8 -9
View File
@@ -17,7 +17,7 @@ assert (lib.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
let
inherit (lib)
toLower optionalString stringLength assertMsg
getConfig makeLibraryPath checkEnvVarSet elem;
getConfig makeLibraryPath assertEnvVarSet elem;
# Pass secretsFile for INFURA_TOKEN to jsbundle build
builtJsBundle = jsbundle { inherit secretsFile; };
@@ -87,8 +87,8 @@ in stdenv.mkDerivation rec {
STATUS_GO_ANDROID_LIBDIR = "${status-go}";
phases = [
"unpackPhase" "secretsPhase" "keystorePhase"
"buildPhase" "checkPhase" "installPhase"
"unpackPhase" "secretsPhase" "secretsCheckPhase"
"keystorePhase" "buildPhase" "checkPhase" "installPhase"
];
unpackPhase = ''
@@ -100,9 +100,6 @@ in stdenv.mkDerivation rec {
# Ensure we have the right .env file
cp -bf ./${envFileName} ./.env
# Export all vars from .env file
export $(cut -d= -f1 .env)
# Copy index.js and app/ input files
cp -ra --no-preserve=ownership ${builtJsBundle}/* ./
@@ -122,9 +119,6 @@ in stdenv.mkDerivation rec {
# if secretsFile is not set we use generate keystore
secretsPhase = if (secretsFile != "") then ''
source "${secretsFile}"
${checkEnvVarSet "KEYSTORE_ALIAS"}
${checkEnvVarSet "KEYSTORE_PASSWORD"}
${checkEnvVarSet "KEYSTORE_KEY_PASSWORD"}
'' else keystore.shellHook;
# if keystorePath is set copy it into build directory
@@ -134,6 +128,11 @@ in stdenv.mkDerivation rec {
export KEYSTORE_PATH="$PWD/status-im.keystore"
cp -a --no-preserve=ownership "${keystorePath}" "$KEYSTORE_PATH"
'';
secretsCheckPhase = ''
${assertEnvVarSet "KEYSTORE_ALIAS"}
${assertEnvVarSet "KEYSTORE_PASSWORD"}
${assertEnvVarSet "KEYSTORE_KEY_PASSWORD"}
'';
buildPhase = let
adhocEnvVars = optionalString stdenv.isLinux
"LD_LIBRARY_PATH=$LD_LIBRARY_PATH:${makeLibraryPath [ pkgs.zlib ]}";
+1 -1
View File
@@ -3,7 +3,7 @@ extra-substituters = https://nix-cache.status.im/
substituters = https://cache.nixos.org/
trusted-public-keys = nix-cache.status.im-1:x/93lOfLU+duPplwMSBR+OlY4+mo+dCN7n0mr4oPwgY= cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= nix-cache-cn.status.im:WUiOoTQQurm+rEL/yuAuU/a3TViDtMM9DCMgMx/KkOw=
# Some downloads are multiple GB, default is 5 minutes
stalled-download-timeout = 3600
stalled-download-timeout = 600
connect-timeout = 10
max-jobs = auto
# Helps avoid removing currently used dependencies via garbage collection
+3 -3
View File
@@ -48,14 +48,14 @@ let
# paths don't like slashes in them
dropSlashes = builtins.replaceStrings [ "/" ] [ "_" ];
# if version doesn't match this it's probably a commit, it's lax semver
versionRegex = "^v?[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+[[:alnum:]+_.-]*$";
# if version doesn't match this it's probably a commit
versionRegex = "^v?[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+(-[[:alnum:].]+)?$";
sanitizeVersion = version:
if (builtins.match versionRegex version) != null
# Geth forces a 'v' prefix for all versions
then lib.removePrefix "v" (dropSlashes version)
# reduce metrics cardinality in Prometheus
else lib.traceValFn (v: "WARNING: Marking build version as 'develop'!") "develop";
else "develop";
in {
inherit sanitizeVersion
+9 -10
View File
@@ -19,9 +19,9 @@
"@react-native-community/netinfo": "^4.4.0",
"@react-native-community/push-notification-ios": "^1.4.1",
"@react-native-community/slider": "^3.0.0",
"@react-navigation/bottom-tabs": "^5.8.0",
"@react-navigation/native": "^5.7.3",
"@react-navigation/stack": "^5.9.0",
"@react-navigation/bottom-tabs": "^5.7.0",
"@react-navigation/native": "^5.7.0",
"@react-navigation/stack": "^5.7.0",
"bignumber.js": "git+https://github.com/status-im/bignumber.js.git#v4.0.2-status",
"buffer": "^5.4.2",
"chance": "^1.1.0",
@@ -43,27 +43,26 @@
"react-native-dialogs": "^1.0.4",
"react-native-fetch-polyfill": "^1.1.2",
"react-native-fs": "^2.14.1",
"react-native-gesture-handler": "^1.8.0",
"react-native-gesture-handler": "^1.6.0",
"react-native-haptic-feedback": "^1.9.0",
"react-native-image-crop-picker": "^0.31.1",
"react-native-image-resizer": "^1.2.3",
"react-native-image-viewing": "git+https://github.com/Ferossgp/react-native-image-viewing.git#v0.2.1",
"react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git#v.3.0.0-5-status",
"react-native-languages": "^3.0.2",
"react-native-linear-gradient": "^2.5.6",
"react-native-mail": "git+https://github.com/status-im/react-native-mail.git#v4.0.0-status",
"react-native-navigation-bar-color": "^2.0.1",
"react-native-permissions": "^2.1.5",
"react-native-reanimated": "^1.13.0",
"react-native-reanimated": "^1.7.0",
"react-native-redash": "^14.2.2",
"react-native-safe-area-context": "^2.0.0",
"react-native-screens": "^2.10.1",
"react-native-screens": "^2.3.0",
"react-native-shake": "^3.3.1",
"react-native-splash-screen": "^3.2.0",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#v2.5.28",
"react-native-status-keycard": "git+https://github.com/status-im/react-native-status-keycard.git#v2.5.23",
"react-native-svg": "^9.8.4",
"react-native-touch-id": "^4.4.1",
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#v10.9.2",
"react-native-webview": "git+https://github.com/status-im/react-native-webview.git#v10.2.3_7",
"tdigest": "^0.1.1",
"web3-utils": "^1.2.1"
},
@@ -79,6 +78,6 @@
"nyc": "^14.1.1",
"process": "0.11.10",
"rn-snoopy": "git+https://github.com/status-im/rn-snoopy.git#v2.0.2-status",
"shadow-cljs": "^2.10.14"
"shadow-cljs": "2.9.2"
}
}
-3
View File
@@ -1,5 +1,3 @@
const rndi = process.env.GOOGLE_FREE == 1 ? {platforms: {android: null}} : {};
module.exports = {
dependencies: {
'react-native-config': {
@@ -24,6 +22,5 @@ module.exports = {
ios: null,
},
},
'react-native-device-info': rndi,
},
};
+2 -1
View File
@@ -13,6 +13,7 @@
]],
["General", [
"chitchat",
"chitchat",
"hello",
"worldnews",
@@ -130,4 +131,4 @@
"indonesian"
]]
]
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 841 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 553 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 810 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 861 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 367 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 177 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 312 B

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 478 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 202 B

After

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 301 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 426 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

-5
View File
@@ -160,11 +160,6 @@
return sendAPIrequest('qr-code', {regex: regex});
};
EthereumProvider.prototype.on = function (type, handler)
{
console.log("Not supported by Status")
}
EthereumProvider.prototype.request = function (requestArguments)
{
if (!requestArguments) {
+13 -20
View File
@@ -7,19 +7,20 @@ GIT_ROOT=$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)
source "${GIT_ROOT}/scripts/colors.sh"
function must_get_env() {
declare -n VAR_VALUE="$1"
if [[ -n "${VAR_VALUE}" ]]; then
echo "${VAR_VALUE}"
declare -n VAR_NAME="$1"
if [[ -n "${VAR_NAME}" ]]; then
echo "${VAR_NAME}"
return
fi
echo -e "${RED}No required env variable:${RST} ${BLD}${!VAR_VALUE}${RST}" 1>&2
echo -e "${RED}No required env variable:${RST} ${BLD}${!VAR_NAME}${RST}" 1>&2
exit 1
}
function append_env_export() {
VAR_NAME=${1}
VAR_VALUE=$(must_get_env "${VAR_NAME}")
echo "export ${VAR_NAME}=\"${VAR_VALUE}\";" >> "${SECRETS_FILE_PATH}"
ENV_VAR_NAME=${1}
if [[ -n "${!ENV_VAR_NAME}" ]]; then
echo "export ${ENV_VAR_NAME}=\"${!ENV_VAR_NAME}\";" >> "${SECRETS_FILE_PATH}"
fi
}
config=''
@@ -37,23 +38,15 @@ config+="status-im.android.abi-split=\"$(must_get_env ANDROID_ABI_SPLIT)\";"
config+="status-im.android.abi-include=\"$(must_get_env ANDROID_ABI_INCLUDE)\";"
nixOpts=()
# We create if now so the trap knows its location
export SECRETS_FILE_PATH=$(mktemp)
chmod 644 ${SECRETS_FILE_PATH}
# If secrets file was created we want to remove it.
trap "rm -vf ${SECRETS_FILE_PATH}" EXIT ERR INT QUIT
# Secrets like this can't be passed via args or they end up in derivation.
# If no secrets were passed there's no need to pass the 'secretsFile'
if [[ -n "${KEYSTORE_ALIAS}${KEYSTORE_ALIAS}${KEYSTORE_ALIAS}" ]]; then
# WARNING: All three have to be set!
# Secrets like this can't be passed via args or they end up in derivation
SECRETS_FILE_PATH=$(mktemp)
trap "rm -f ${SECRETS_FILE_PATH}" EXIT ERR INT QUIT
chmod 644 ${SECRETS_FILE_PATH}
append_env_export 'KEYSTORE_PASSWORD'
append_env_export 'KEYSTORE_ALIAS'
append_env_export 'KEYSTORE_KEY_PASSWORD'
fi
if [[ -n "${INFURA_TOKEN}" ]]; then
append_env_export 'INFURA_TOKEN'
fi
# If no secrets were passed there's no need to pass the 'secretsFile'.
if [[ -s "${SECRETS_FILE_PATH}" ]]; then
nixOpts+=("--argstr" "secretsFile" "${SECRETS_FILE_PATH}")
fi
+2 -14
View File
@@ -5,7 +5,7 @@ if [[ ! -x "$(command -v nix-prefetch-url)" ]] && [[ -z "${IN_NIX_SHELL}" ]]; th
exit 1
fi
set -ef
set -eof pipefail
GIT_ROOT="$(cd "${BASH_SOURCE%/*}" && git rev-parse --show-toplevel)"
VERSION_FILE="${GIT_ROOT}/status-go-version.json"
@@ -20,7 +20,6 @@ HELP_MESSAGE=$(cat <<-END
This is a tool for upgrading status-go to a given version in:
${VERSION_FILE}
Which is then used by Nix derivations to build status-go for the app.
If the given name matches both a branch and a tag the tag is used.
Usage:
${SCRIPT_FILE} {version}
@@ -56,18 +55,7 @@ if [[ "${STATUS_GO_VERSION}" = PR-* ]]; then
fi
# ls-remote finds only tags, branches, and pull requests, but can't find commits
STATUS_GO_MATCHING_REFS=$(git ls-remote ${REPO_URL} ${STATUS_GO_VERSION})
# It's possible that there's both a branch and a tag matching the given version
STATUS_GO_TAG_SHA1=$(echo "${STATUS_GO_MATCHING_REFS}" | grep 'refs/tags' | cut -f1)
STATUS_GO_BRANCH_SHA1=$(echo "${STATUS_GO_MATCHING_REFS}" | grep 'refs/heads' | cut -f1)
# Prefer tag over branch if both are found
if [[ -n "${STATUS_GO_TAG_SHA1}" ]]; then
STATUS_GO_COMMIT_SHA1="${STATUS_GO_TAG_SHA1}"
else
STATUS_GO_COMMIT_SHA1="${STATUS_GO_BRANCH_SHA1}"
fi
STATUS_GO_COMMIT_SHA1=$(git ls-remote ${REPO_URL} ${STATUS_GO_VERSION} | cut -f1)
if [[ -z "${STATUS_GO_COMMIT_SHA1}" ]]; then
echo "ERROR: Failed to find a SHA1 for rev '${STATUS_GO_VERSION}'."
+2 -6
View File
@@ -39,14 +39,10 @@
:output-dir "app"
:init-fn status-im.core/init
:dev {:devtools {:after-load status-im.reloader/reload
:build-notify status-im.reloader/build-notify
:preloads [re-frisk-remote.preload]}
:closure-defines {status-im.utils.config/INFURA_TOKEN #shadow/env "INFURA_TOKEN"}
:compiler-options {:output-feature-set :es5
:closure-defines
:compiler-options {:closure-defines
{re-frame.trace/trace-enabled? true}
:source-map false
:infer-externs true}
:source-map false}
;; if you want to use a real device, set your local ip
;; in the SHADOW_HOST env variable to make sure that
;; it will use the right interface
-2
View File
@@ -18,11 +18,9 @@
(def react-native
(clj->js {:NativeModules {:RNGestureHandlerModule {:Direction (fn [])}
:PushNotifications {}
:ReanimatedModule {:configureProps (fn [])}}
:View {}
:RefreshControl {}
:FlatList {}
:Text {}
:ProgressBarAndroid {}
+8 -8
View File
@@ -1,13 +1,13 @@
# Status Quo Components
All components in **Quo** should be independent of the app state. They should be _pure_
and _easy to reason about_. Avoiding the app state is also required to make the library
independent and easy to be pulled off as a separate repository when needed.
To avoid high coupling and direct use of internal styling, the components should be
exported via namespace `quo.core` and used by the Status app only from there. This will
All components in **Quo** should be independent of the app state. They should be pure,
and easy to reason about. This is required to make the library independent and
easily pulled off as a separate repository when needed.
Do avoid high coupling and direct use of internal styling, the components should be
exported via namespace `quo.core` and used by status app only from here. This will
allow a more flexible way to update components without possible breakages into the
app style.
**Quo** components should not have any dependency on the Status app, this
**Quo** components should and not have any dependency on the status app, this
will avoid circular dependency and also benefit the independence of the components.
All components are stored inside `components` namespaces. They are stateless and do
@@ -39,8 +39,8 @@ system to be used in too many way which can creating disjointed experiences.
- Avoid external margins for atom components, it can be added on the wrapper
where they are used but can't be removed without overriding.
[Max Stoiber article on margins](https://mxstbr.com/thoughts/margin)
- Design reusable components into [Layout Isolated Components](https://visly.app/blogposts/layout-isolated-components)
(Article more relates to web, but ideas fits also to mobile development)
- Design reusable components into [Layout Isolated Components](https://visly.app/blog/layout-isolated-components)
(Article more relates to web, but ideas fits also to mobile dev**
- Explicit is better than implicit, do not rely on platform default, if you expect
a specific value, then override it
+7 -28
View File
@@ -2,16 +2,14 @@
(:require [quo.animated :as animated]
[quo.design-system.colors :as colors]))
(defn switch-style [state disabled]
(defn switch-style [state]
{:width 52
:height 28
:border-radius 14
:padding 4
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(if disabled
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme)))})
(:interactive-01 @colors/theme))})
(defn switch-bullet-style [state hold]
{:width 20
@@ -26,16 +24,14 @@
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn radio-style [state disabled]
(defn radio-style [state]
{:width 20
:height 20
:border-radius 10
:padding 4
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(if disabled
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme)))})
(:interactive-01 @colors/theme))})
(defn radio-bullet-style [state hold]
{:width 12
@@ -50,7 +46,7 @@
:shadow-color (:shadow-01 @colors/theme)
:shadow-offset {:width 0 :height 4}})
(defn animated-checkbox-style [state disabled]
(defn checkbox-style [state]
{:width 18
:height 18
:border-radius 4
@@ -58,25 +54,8 @@
:align-items :center
:background-color (animated/mix-color state
(:ui-01 @colors/theme)
(if disabled
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme)))})
(:interactive-01 @colors/theme))})
(defn checkbox-style [value disabled]
{:width 18
:height 18
:border-radius 4
:justify-content :center
:align-items :center
:background-color (if value
(if disabled
(:interactive-04 @colors/theme)
(:interactive-01 @colors/theme))
(:ui-01 @colors/theme))})
(defn animated-check-icon-style [state hold]
(defn check-icon-style [state hold]
{:opacity (animated/mix hold 1 0.6)
:transform [{:scale (animated/mix state 0.0001 1)}]})
(defn check-icon-style [value]
{:opacity (if value 1 0)})
+11 -27
View File
@@ -2,7 +2,6 @@
(:require [reagent.core :as reagent]
[cljs-bean.core :as bean]
[quo.react :as react]
[quo.react-native :as rn]
[quo.animated :as animated]
[quo.gesture-handler :as gh]
[quo.design-system.colors :as colors]
@@ -46,42 +45,27 @@
:enabled (boolean (and onChange (not disabled)))})
[animated/view
[component {:transition transition
:hold hold
:disabled disabled}]]]))))
:hold hold}]]]))))
(defn switch-view [{:keys [transition hold disabled]}]
[animated/view {:style (styles/switch-style transition disabled)
(defn switch-view [{:keys [transition hold]}]
[animated/view {:style (styles/switch-style transition)
:accessibility-label :switch
:accessibility-role :switch}
[animated/view {:style (styles/switch-bullet-style transition hold)}]])
(defn radio-view [{:keys [transition hold disabled]}]
[animated/view {:style (styles/radio-style transition disabled)
(defn radio-view [{:keys [transition hold]}]
[animated/view {:style (styles/radio-style transition)
:accessibility-label :radio
:accessibility-role :radio}
[animated/view {:style (styles/radio-bullet-style transition hold)}]])
(defn checkbox-view [props]
(let [{:keys [value onChange disabled]} (bean/bean props)]
(reagent/as-element
[rn/touchable-highlight
{:on-press (when onChange onChange)}
[rn/view {:style (styles/checkbox-style value disabled)
:accessibility-label :checkbox
:accessibility-role :checkbox}
[rn/view {:style (styles/check-icon-style value)}
[icons/tiny-icon :tiny-icons/tiny-check {:color colors/white}]]]])))
(defn animated-checkbox-view [{:keys [transition hold disabled]}]
[animated/view
{:style (styles/animated-checkbox-style transition disabled)
:accessibility-label :checkbox
:accessibility-role :checkbox}
[animated/view {:style (styles/animated-check-icon-style transition hold)}
(defn checkbox-view [{:keys [transition hold]}]
[animated/view {:style (styles/checkbox-style transition)
:accessibility-label :checkbox
:accessibility-role :checkbox}
[animated/view {:style (styles/check-icon-style transition hold)}
[icons/tiny-icon :tiny-icons/tiny-check {:color colors/white}]]])
(def switch (reagent/adapt-react-class (react/memo (control-builder switch-view))))
(def radio (reagent/adapt-react-class (react/memo (control-builder radio-view))))
(def animated-checkbox
(reagent/adapt-react-class (react/memo (control-builder animated-checkbox-view))))
(def checkbox (reagent/adapt-react-class (react/memo checkbox-view)))
(def checkbox (reagent/adapt-react-class (react/memo (control-builder checkbox-view))))
+16 -35
View File
@@ -64,7 +64,7 @@
:justify-content :space-between})}]
children))
(defn icon-column
(defn- icon-column
[{:keys [icon icon-bg-color icon-color size icon-container-style]}]
(when icon
(let [icon-size (size->icon-size size)]
@@ -84,13 +84,10 @@
(defn title-column
[{:keys [title text-color subtitle subtitle-max-lines
title-accessibility-label size text-size title-text-weight
right-side-present?]}]
title-accessibility-label size text-size title-text-weight]}]
[rn/view {:style (merge (:tiny spacing/padding-horizontal)
;; make left-side title grow if nothing is present on right-side
(when-not right-side-present?
{:flex 1
:justify-content :center}))}
{:justify-content :center
:flex 1})}
(cond
(and title subtitle)
@@ -127,35 +124,21 @@
(defn left-side [props]
[rn/view {:style {:flex-direction :row
;; Occupy only content width, never grow, but shrink if need be
:flex-grow 0
:flex-shrink 1
:flex 1
:align-items :center}}
[icon-column props]
[title-column props]])
(defn right-side [{:keys [chevron active accessory accessory-text animated-accessory?]}]
(defn right-side [{:keys [chevron active accessory accessory-text]}]
(when (or chevron accessory)
[rn/view {:style {:align-items :center
:justify-content :flex-end
:flex-direction :row
;; Grow to occupy full space, shrink when need be, but always maitaining 16px left gutter
:flex-grow 1
:flex-shrink 1
:margin-left 16
;; When the left-side leaves no room for right-side, the rendered element is pushed out. A flex-basis ensures that there is some room reserved.
;; The number 80px was determined by trial and error.
:flex-basis 80}}
[rn/view {:style {:align-items :center
:flex-direction :row}}
[rn/view {:style (:tiny spacing/padding-horizontal)}
(case accessory
:radio [controls/radio {:value active}]
:checkbox [(if animated-accessory?
controls/animated-checkbox
controls/checkbox)
{:value active}]
:checkbox [controls/checkbox {:value active}]
:switch [controls/switch {:value active}]
:text [text/text {:color :secondary
:ellipsize-mode :middle
:number-of-lines 1}
accessory-text]
accessory)]
@@ -171,7 +154,7 @@
[{:keys [theme accessory disabled subtitle-max-lines icon icon-container-style
title subtitle active on-press on-long-press chevron size text-size
accessory-text accessibility-label title-accessibility-label
haptic-feedback haptic-type error animated animated-accessory? title-text-weight]
haptic-feedback haptic-type error animated title-text-weight]
:or {subtitle-max-lines 1
theme :main
haptic-feedback true
@@ -218,14 +201,12 @@
:size size
:text-size text-size
:subtitle subtitle
:subtitle-max-lines subtitle-max-lines
:right-side-present? (or accessory chevron)}]
[right-side {:chevron chevron
:active active
:on-press on-press
:accessory-text accessory-text
:animated-accessory? animated-accessory?
:accessory accessory}]]]
:subtitle-max-lines subtitle-max-lines}]
[right-side {:chevron chevron
:active active
:on-press on-press
:accessory-text accessory-text
:accessory accessory}]]]
(when error
[tooltip/tooltip (merge {:bottom-value 0}
(when accessibility-label
+2 -6
View File
@@ -29,7 +29,6 @@
:interactive-01 "rgba(67,96,223,1)" ; Accent color, buttons, own message, actions,active state
:interactive-02 "rgba(236,239,252,1)" ; Light Accent, buttons background, actions background, messages
:interactive-03 "rgba(255,255,255,0.1)" ; Background for interactive above accent
:interactive-04 "rgba(147,155,161,1)" ; Disabled state
:ui-background "rgba(255,255,255,1)" ; Default view background
:ui-01 "rgba(238,242,245,1)" ; Secondary background
:ui-02 "rgba(0,0,0,0.1)" ; Deviders
@@ -47,8 +46,7 @@
:shadow-01 "rgba(0,9,26,0.12)" ; Main shadow color
:backdrop "rgba(0,0,0,0.4)" ; Backdrop for modals and bottom sheet
:border-01 "rgba(238,242,245,1)"
:border-02 "rgba(67, 96, 223, 0.1)"
:highlight "rgba(67,96,223,0.4)"})
:border-02 "rgba(67, 96, 223, 0.1)"})
(def dark-theme
{:positive-01 "rgba(68,208,88,1)"
@@ -60,7 +58,6 @@
:interactive-01 "rgba(97,119,229,1)"
:interactive-02 "rgba(35,37,47,1)"
:interactive-03 "rgba(255,255,255,0.1)"
:interactive-04 "rgba(131,140,145,1)"
:ui-background "rgba(20,20,20,1)"
:ui-01 "rgba(37,37,40,1)"
:ui-02 "rgba(0,0,0,0.1)"
@@ -78,8 +75,7 @@
:shadow-01 "rgba(0,0,0,0.75)"
:backdrop "rgba(0,0,0,0.4)"
:border-01 "rgba(37,37,40,1)"
:border-02 "rgba(97,119,229,0.1)"
:highlight "rgba(67,96,223,0.4)"})
:border-02 "rgba(97,119,229,0.1)"})
(def theme (reagent/atom light-theme))
-13
View File
@@ -1,13 +0,0 @@
(ns quo.previews.icons
(:require [quo.design-system.colors :as colors]
[quo.react-native :as rn]
[status-im.ui.components.icons.icons :as icons]
[status-im.ui.components.icons.vector-icons :as vector-icons]))
(defn preview []
[rn/scroll-view {:background-color (:ui-background @colors/theme)
:flex 1}
(for [i (keys icons/icons)]
[rn/view {:flex-direction :row}
[vector-icons/icon (keyword i)]
[rn/text i]])])
+2 -6
View File
@@ -12,8 +12,7 @@
[reagent.core :as reagent]
[quo.design-system.colors :as colors]
[quo.theme :as theme]
[status-im.ui.screens.routing.core :as navigation]
[quo.previews.icons :as icons]))
[status-im.ui.screens.routing.core :as navigation]))
(def screens [{:name :texts
:insets {:top false}
@@ -38,10 +37,7 @@
:component bottom-sheet/preview}
{:name :controls
:insets {:top false}
:component controls/preview}
{:name :icons
:insets {:top false}
:component icons/preview}])
:component controls/preview}])
(defn theme-switcher []
[rn/view {:style {:flex-direction :row

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