Compare commits

..
Author SHA1 Message Date
andrey 877acff46c 1.6.1 2020-09-08 11:35:16 +02:00
Volodymyr Kozieiev a7aac8f488 Restrict message size on input
Signed-off-by: Volodymyr Kozieiev <vkjr.sp@gmail.com>
2020-09-08 11:33:39 +02:00
Gheorghe Pinzaru 21cac9084d Use different acquisition gateway based on chain
Do not persist empty tx

Signed-off-by: Gheorghe Pinzaru <feross95@gmail.com>
2020-08-26 13:27:04 +02:00
485 changed files with 8304 additions and 25957 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:
-4
View File
@@ -24,7 +24,3 @@ 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
-5
View File
@@ -23,8 +23,3 @@ 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
-6
View File
@@ -22,9 +22,3 @@ KEYCARD_TEST_MENU=0
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.6.1
-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.3'
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.3'
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.3'
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.3'
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.3'
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.3'
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
+13 -25
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):
@@ -330,13 +328,11 @@ PODS:
- React
- RNCMaskedView (0.1.9):
- React
- RNCPushNotificationIOS (1.4.1):
- React
- RNDeviceInfo (5.6.1):
- React
- RNFS (2.16.6):
- React
- RNGestureHandler (1.8.0):
- RNGestureHandler (1.6.1):
- React
- RNImageCropPicker (0.31.1):
- React-Core
@@ -355,9 +351,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
@@ -367,7 +363,7 @@ PODS:
- SQLCipher/standard (3.4.2):
- SQLCipher/common
- SSZipArchive (2.2.3)
- TOCropViewController (2.5.4)
- TOCropViewController (2.5.3)
- TouchID (4.4.1):
- React
- Yoga (1.14.0)
@@ -375,7 +371,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`)
@@ -440,7 +435,6 @@ DEPENDENCIES:
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
- "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)"
- "RNCMaskedView (from `../node_modules/@react-native-community/masked-view`)"
- "RNCPushNotificationIOS (from `../node_modules/@react-native-community/push-notification-ios`)"
- RNDeviceInfo (from `../node_modules/react-native-device-info`)
- RNFS (from `../node_modules/react-native-fs`)
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
@@ -476,8 +470,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:
@@ -562,8 +554,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/@react-native-community/clipboard"
RNCMaskedView:
:path: "../node_modules/@react-native-community/masked-view"
RNCPushNotificationIOS:
:path: "../node_modules/@react-native-community/push-notification-ios"
RNDeviceInfo:
:path: "../node_modules/react-native-device-info"
RNFS:
@@ -593,7 +583,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
boost-for-react-native: 39c7adb57c4e60d6c5479dd8623128eb5b3f0f2c
BVLinearGradient: e3aad03778a456d77928f594a649e96995f1c872
CocoaAsyncSocket: 694058e7c0ed05a9e217d1b3c7ded962f4180845
CocoaLibEvent: 2fab71b8bd46dd33ddb959f7928ec5909f838e3f
DoubleConversion: 5805e889d232975c086db112ece9ed034df7a0b2
@@ -607,7 +596,7 @@ SPEC CHECKSUMS:
Flipper-RSocket: 64e7431a55835eb953b0bf984ef3b90ae9fdddd7
FlipperKit: afd4259ef9eadeeb2d30250b37d95cb3b6b97a69
Folly: 30e7936e1c45c08d884aa59369ed951a8e68cf51
glog: d6cca0516fb0ca3697a5b2e199ea83dfc7133411
glog: 682164e7ac67e41afd8f7b6a37a96d04caf61cc0
OpenSSL-Universal: 8b48cc0d10c1b2923617dfe5c178aa9ed2689355
Permission-Camera: afad27bf90337684d4a86f3825112d648c8c4d3b
Permission-Microphone: 0ffabc3fe1c75cfb260525ee3f529383c9f4368c
@@ -630,7 +619,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
@@ -646,25 +635,24 @@ SPEC CHECKSUMS:
RNCAsyncStorage: d059c3ee71738c39834a627476322a5a8cd5bf36
RNCClipboard: 8148e21ac347c51fd6cd4b683389094c216bb543
RNCMaskedView: 71fc32d971f03b7f03d6ab6b86b730c4ee64f5b6
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
TOCropViewController: 2a1ae1242600b1f2d996fd91a5268b2309a33b5c
TOCropViewController: 20a14b6a7a098308bf369e7c8d700dc983a974e6
TouchID: ba4c656d849cceabc2e4eef722dea5e55959ecf4
Yoga: 3ebccbdd559724312790e7742142d062476b698e
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
PODFILE CHECKSUM: 5faa578ff5cb7a30abc18b9d620df288750a72fe
COCOAPODS: 1.9.3
COCOAPODS: 1.9.1
+1 -2
View File
@@ -9,9 +9,8 @@
#import <React/RCTBridgeDelegate.h>
#import <UIKit/UIKit.h>
#import <UserNotifications/UNUserNotificationCenter.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate>
@interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate>
@property (nonatomic, strong) UIWindow *window;
-48
View File
@@ -20,9 +20,6 @@
#import <React/RCTBundleURLProvider.h>
#import <React/RCTRootView.h>
#import <UserNotifications/UserNotifications.h>
#import <RNCPushNotificationIOS.h>
#if DEBUG
#import <FlipperKit/FlipperClient.h>
#import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h>
@@ -91,9 +88,6 @@ static void InitializeFlipper(UIApplication *application) {
[self.window makeKeyAndVisible];
[RNSplashScreen show];
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
return YES;
}
@@ -143,46 +137,4 @@ static void InitializeFlipper(UIApplication *application) {
}
}
// Required to register for notifications
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings
{
[RNCPushNotificationIOS didRegisterUserNotificationSettings:notificationSettings];
}
// Required for the register event.
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken
{
[RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}
// Required for the registrationError event.
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error
{
[RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error];
}
// IOS 10+ Required for localNotification event
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
didReceiveNotificationResponse:(UNNotificationResponse *)response
withCompletionHandler:(void (^)(void))completionHandler
{
[RNCPushNotificationIOS didReceiveNotificationResponse:response];
completionHandler();
}
// IOS 4-10 Required for the localNotification event.
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
{
[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 -15
View File
@@ -4,9 +4,6 @@
{ stdenv, lib, deps, pkgs }:
# Path to the file containing secret environment variables
{ secretsFile ? "" }:
stdenv.mkDerivation {
name = "status-react-build-jsbundle-android";
src =
@@ -39,19 +36,8 @@ stdenv.mkDerivation {
};
};
buildInputs = with pkgs; [ clojure nodejs bash git openjdk];
phases = [
"unpackPhase" "secretsPhase" "patchPhase"
"configurePhase" "buildPhase" "installPhase"
];
# For optional INFURA_TOKEN variable
secretsPhase = if (secretsFile != "") then ''
source "${secretsFile}"
${lib.checkEnvVarSet "INFURA_TOKEN"}
'' else ''
echo "No secrets provided!"
'';
phases = [ "unpackPhase" "patchPhase" "configurePhase" "buildPhase" "installPhase" ];
# Patching shadow-cljs.edn so it uses the local maven repo of dependencies provided by Nix
patchPhase =
let anchor = ''{:source-paths ["src" "test/cljs"]'';
+9 -13
View File
@@ -17,10 +17,7 @@ assert (lib.stringLength watchmanSockPath) > 0 -> stdenv.isDarwin;
let
inherit (lib)
toLower optionalString stringLength assertMsg
getConfig makeLibraryPath checkEnvVarSet elem;
# Pass secretsFile for INFURA_TOKEN to jsbundle build
builtJsBundle = jsbundle { inherit secretsFile; };
getConfig makeLibraryPath assertEnvVarSet elem;
buildType = getConfig "build-type" "release";
buildNumber = getConfig "build-number" 9999;
@@ -87,8 +84,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,11 +97,8 @@ 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}/* ./
cp -ra --no-preserve=ownership ${jsbundle}/* ./
# Copy android/ directory
mkdir -p ./android/build
@@ -122,9 +116,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 +125,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
-2
View File
@@ -32,8 +32,6 @@ in {
gradlePropParser = callPackage ./tools/gradlePropParser.nix { };
# Package version adjustments
go = super.pkgs.go_1_14;
gradle = super.pkgs.gradle_5;
nodejs = super.pkgs.nodejs-12_x;
openjdk = super.pkgs.openjdk8_headless;
xcodeWrapper = callPackage ./pkgs/xcodeenv/compose-xcodewrapper.nix { } {
+2 -2
View File
@@ -13,8 +13,8 @@ let
name = "nixpkgs-source";
owner = "status-im";
repo = "nixpkgs";
rev = "3355743cfd8d89cfa8d3b8e6d40c48e62e72d36a";
sha256 = "1l7559m3xkzwkm202rkjq3a8cz52k7z9vxn9y2adc30cp197wc82";
rev = "6dacca5eb43a8bfb02fb09331df607d4465a28e9";
sha256 = "0whwzll9lvrq4gg5j838skg7fqpvb55w4z7y44pzib32k613y2qn";
# To get the compressed Nix sha256, use:
# nix-prefetch-url --unpack https://github.com/${ORG}/nixpkgs/archive/${REV}.tar.gz
};
+5 -6
View File
@@ -1,16 +1,15 @@
{ stdenv, utils, callPackage, fetchgit, buildGo114Package,
{ stdenv, utils, callPackage, fetchgit, buildGoPackage,
ncurses5, zlib, makeWrapper, patchelf, androidPkgs, xcodeWrapper
}:
let
inherit (stdenv) isDarwin;
inherit (stdenv.lib) optional optionalString strings;
in buildGo114Package rec {
in buildGoPackage rec {
pname = "gomobile";
version = "20200622-${strings.substring 0 7 rev}";
# WARNING: Next commit removes support for ARM 32 bit builds for iOS
rev = "33b80540585f2b31e503da24d6b2a02de3c53ff5";
sha256 = "0c9map2vrv34wmaycsv71k4day3b0z5p16yzxmlp8amvqb38zwlm";
version = "20200329-${strings.substring 0 7 rev}";
rev = "4c31acba000778d337c0e4f32091cc923b3363d2";
sha256 = "0k42pn6fq886k9hn85wbgg4h4y1myj7niw0746sn50zfbrmy3s2c";
goPackagePath = "golang.org/x/mobile";
subPackages = [ "bind" "cmd/gobind" "cmd/gomobile" ];
+11 -66
View File
@@ -1,21 +1,20 @@
# file generated from go.mod using vgo2nix (https://github.com/adisbladis/vgo2nix)
[
{
goPackagePath = "github.com/BurntSushi/xgb";
goPackagePath = "golang.org/x/tools";
fetch = {
type = "git";
url = "https://github.com/BurntSushi/xgb";
rev = "27f122750802";
sha256 = "18lp2x8f5bljvlz0r7xn744f0c9rywjsb9ifiszqqdcpwhsa0kvj";
url = "https://go.googlesource.com/tools";
rev = "6edc0a871e69";
sha256 = "1nxrr7nin65cmsm6i3vxdc57n03v1i541hfllw0p4zw8f414wfll";
};
}
{
goPackagePath = "golang.org/x/crypto";
goPackagePath = "golang.org/x/mod";
fetch = {
type = "git";
url = "https://go.googlesource.com/crypto";
rev = "87dc89f01550";
sha256 = "0z4i1m2yn3f31ci7wvcm2rxkx2yiv7a78mfzklncmsz2k97rlh2g";
url = "https://go.googlesource.com/mod";
rev = "331c550502dd";
sha256 = "0942gzs6mlsjal4drjmm8gr54pj1cdhsl9mnj3ygm200mf3fj6pi";
};
}
{
@@ -23,7 +22,7 @@
fetch = {
type = "git";
url = "https://go.googlesource.com/exp";
rev = "ec7cb31e5a56";
rev = "ec7cb31e5a56";
sha256 = "19b4kdwfahq9f809v4lmn9h47sq1y67nkl7csnracn5qd334hp06";
};
}
@@ -32,70 +31,16 @@
fetch = {
type = "git";
url = "https://go.googlesource.com/image";
rev = "cff245a6509b";
rev = "cff245a6509b";
sha256 = "0hiznlkiaay30acwvvyq8g6bm32r7bc6gv47pygrcxqpapasbz84";
};
}
{
goPackagePath = "golang.org/x/mod";
fetch = {
type = "git";
url = "https://go.googlesource.com/mod";
rev = "331c550502dd";
sha256 = "0942gzs6mlsjal4drjmm8gr54pj1cdhsl9mnj3ygm200mf3fj6pi";
};
}
{
goPackagePath = "golang.org/x/net";
fetch = {
type = "git";
url = "https://go.googlesource.com/net";
rev = "3b0461eec859";
sha256 = "0l00c8l0a8xnv6qdpwfzxxsr58jggacgzdrwiprrfx2xqm37b6d5";
};
}
{
goPackagePath = "golang.org/x/sync";
fetch = {
type = "git";
url = "https://go.googlesource.com/sync";
rev = "112230192c58";
sha256 = "05i2k43j2d0llq768hg5pf3hb2yhfzp9la1w5wp0rsnnzblr0lfn";
};
}
{
goPackagePath = "golang.org/x/sys";
fetch = {
type = "git";
url = "https://go.googlesource.com/sys";
rev = "97732733099d";
sha256 = "118hkp01i4z1f5h6hcjm0ff2ngqhrzj1f7731n0kw8dr6hvbx0sw";
};
}
{
goPackagePath = "golang.org/x/text";
fetch = {
type = "git";
url = "https://go.googlesource.com/text";
rev = "v0.3.0";
sha256 = "0r6x6zjzhr8ksqlpiwm5gdd7s209kwk5p4lw54xjvz10cs3qlq19";
};
}
{
goPackagePath = "golang.org/x/tools";
fetch = {
type = "git";
url = "https://go.googlesource.com/tools";
rev = "6edc0a871e69";
sha256 = "1nxrr7nin65cmsm6i3vxdc57n03v1i541hfllw0p4zw8f414wfll";
};
}
{
goPackagePath = "golang.org/x/xerrors";
fetch = {
type = "git";
url = "https://go.googlesource.com/xerrors";
rev = "1b5146add898";
rev = "1b5146add8981d58be77b16229c0ff0f8bebd8c1";
sha256 = "0w2akj91krxjag0xdhsg78470888nicc5ismc2ap9jqpss6v1zih";
};
}
+2 -2
View File
@@ -1,4 +1,4 @@
{ lib, stdenv, utils, callPackage, buildGo114Package
{ lib, stdenv, utils, callPackage, buildGoPackage
, go, androidPkgs, openjdk, gomobile, xcodeWrapper
# object with source attributes
, meta, source
@@ -20,7 +20,7 @@ let
# formatted for use with -target
targetArchs = map (a: "${platform}/${a}") architectures;
in buildGo114Package {
in buildGoPackage {
pname = source.repo;
version = "${source.cleanVersion}-${source.shortRev}-${platform}";
+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
+10 -13
View File
@@ -17,11 +17,10 @@
"@react-native-community/hooks": "^2.5.1",
"@react-native-community/masked-view": "^0.1.6",
"@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",
@@ -32,7 +31,7 @@
"hi-base32": "^0.5.0",
"i18n-js": "^3.3.0",
"qrcode": "^1.4.1",
"react": "16.13.0",
"react": "16.11.0",
"react-dom": "^16.4.2",
"react-native": "0.62.2",
"react-native-background-timer": "^2.1.1",
@@ -43,27 +42,25 @@
"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 +76,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,
},
};
+3 -2
View File
@@ -13,6 +13,7 @@
]],
["General", [
"chitchat",
"chitchat",
"hello",
"worldnews",
@@ -112,7 +113,7 @@
]],
["Languages", [
"status-espanol",
"status-spanish",
"statusbrasil",
"status-german",
"status-french",
@@ -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: 1.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 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: 260 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 354 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: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

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