[CHORE] Build official apps on CI (#2701)
* Duplicated target and changed Bridging Header * Display name * Unnecessary dumb swift file removed * Buildable name * Reorder Info.plist * Rename Official target's bundle id * Ignore .mobileprovision * Fix provisioning of official app * Starting signing * stash fastfile * starting official ci iOS * Uncomment Fastfile keychain * Fix CI config * allowProvisioningUpdates * Changing AppIcon and Splash Screen * Remove unnecessary folder inside of Images.xcassets * Reorder notificationservice and shareextension plists * Fix signing * Manual signing style for official * Split official signing * Update project provisioning * Use ENV as profile * Output match * Keys * TestFlight refactor * Setting up android * android-official-play-build job * Start removing unnecessary fastlane tasks on Android * Trying to refactor Android jobs * android-env * Remove foss build for now * Fork * Fix if conditions * Fix push * ios-build command * Rename Android builds * Upload dSYMs * Refactoring workflow * Reorder upload-to-testflight * upload-to-google-play-beta command * Fix ci * Fix android fork build * Fix keystore * Fix options on fastlane android * Fix keystore * Check isOfficial on iOS * Check isOfficial on db * Remove unused imports * Database names on Android * Tag fix * Minor fixes * Set IS_OFFICIAL on CI * Fix detox * follow review suggestions Co-authored-by: Djorkaeff Alexandre <djorkaeff.unb@gmail.com>
|
@ -8,6 +8,11 @@ macos: &macos
|
||||||
bash-env: &bash-env
|
bash-env: &bash-env
|
||||||
BASH_ENV: "~/.nvm/nvm.sh"
|
BASH_ENV: "~/.nvm/nvm.sh"
|
||||||
|
|
||||||
|
android-env: &android-env
|
||||||
|
JAVA_OPTS: '-Xms512m -Xmx2g'
|
||||||
|
GRADLE_OPTS: '-Xmx3g -Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-Xmx2g -XX:+HeapDumpOnOutOfMemoryError"'
|
||||||
|
TERM: dumb
|
||||||
|
|
||||||
install-npm-modules: &install-npm-modules
|
install-npm-modules: &install-npm-modules
|
||||||
name: Install NPM modules
|
name: Install NPM modules
|
||||||
command: yarn
|
command: yarn
|
||||||
|
@ -75,6 +80,231 @@ restore_cache: &restore-gradle-cache
|
||||||
name: Restore gradle cache
|
name: Restore gradle cache
|
||||||
key: android-{{ checksum "android/build.gradle" }}-{{ checksum "android/app/build.gradle" }}
|
key: android-{{ checksum "android/build.gradle" }}-{{ checksum "android/app/build.gradle" }}
|
||||||
|
|
||||||
|
# COMMANDS
|
||||||
|
commands:
|
||||||
|
|
||||||
|
android-build:
|
||||||
|
description: "Build Android app"
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
|
||||||
|
- run: *install-node
|
||||||
|
|
||||||
|
- restore_cache: *restore-npm-cache-linux
|
||||||
|
|
||||||
|
- run: *install-npm-modules
|
||||||
|
|
||||||
|
- restore_cache: *restore-gradle-cache
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Configure Gradle
|
||||||
|
command: |
|
||||||
|
echo -e "" > ./gradle.properties
|
||||||
|
# echo -e "android.enableAapt2=false" >> ./gradle.properties
|
||||||
|
echo -e "android.useAndroidX=true" >> ./gradle.properties
|
||||||
|
echo -e "android.enableJetifier=true" >> ./gradle.properties
|
||||||
|
echo -e "FLIPPER_VERSION=0.51.0" >> ./gradle.properties
|
||||||
|
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
|
||||||
|
|
||||||
|
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
|
||||||
|
echo -e "APPLICATION_ID=chat.rocket.android" >> ./gradle.properties
|
||||||
|
echo -e "BugsnagAPIKey=$BUGSNAG_KEY_OFFICIAL" >> ./gradle.properties
|
||||||
|
echo $CHAT_ROCKET_ANDROID_STORE_FILE_BASE64_JKS | base64 --decode > ./app/$KEYSTORE_OFFICIAL
|
||||||
|
echo -e "KEYSTORE=$KEYSTORE_OFFICIAL" >> ./gradle.properties
|
||||||
|
echo -e "KEYSTORE_PASSWORD=$CHAT_ROCKET_ANDROID_STORE_PASSWORD" >> ./gradle.properties
|
||||||
|
echo -e "KEY_ALIAS=$CHAT_ROCKET_ANDROID_KEY_ALIAS" >> ./gradle.properties
|
||||||
|
echo -e "KEY_PASSWORD=$CHAT_ROCKET_ANDROID_KEY_PASSWORD" >> ./gradle.properties
|
||||||
|
else
|
||||||
|
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
|
||||||
|
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
|
||||||
|
echo $KEYSTORE_BASE64 | base64 --decode > ./app/$KEYSTORE
|
||||||
|
echo -e "KEYSTORE=$KEYSTORE" >> ./gradle.properties
|
||||||
|
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
||||||
|
echo -e "KEY_ALIAS=$KEY_ALIAS" >> ./gradle.properties
|
||||||
|
echo -e "KEY_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
||||||
|
fi
|
||||||
|
working_directory: android
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Set Google Services
|
||||||
|
command: |
|
||||||
|
if [[ $KEYSTORE ]]; then
|
||||||
|
echo $GOOGLE_SERVICES_ANDROID | base64 --decode > google-services.json
|
||||||
|
fi
|
||||||
|
working_directory: android/app
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Config variables
|
||||||
|
command: |
|
||||||
|
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
|
||||||
|
echo -e "export default { BUGSNAG_API_KEY: '$BUGSNAG_KEY_OFFICIAL' };" > ./config.js
|
||||||
|
else
|
||||||
|
echo -e "export default { BUGSNAG_API_KEY: '$BUGSNAG_KEY' };" > ./config.js
|
||||||
|
fi
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Build App
|
||||||
|
command: |
|
||||||
|
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
|
||||||
|
./gradlew bundleOfficialPlayRelease
|
||||||
|
fi
|
||||||
|
if [[ $CIRCLE_JOB == "android-build-experimental" ]]; then
|
||||||
|
./gradlew bundleExperimentalPlayRelease
|
||||||
|
fi
|
||||||
|
if [[ ! $KEYSTORE ]]; then
|
||||||
|
./gradlew assembleExperimentalPlayDebug
|
||||||
|
fi
|
||||||
|
working_directory: android
|
||||||
|
|
||||||
|
- run:
|
||||||
|
name: Upload sourcemaps to Bugsnag
|
||||||
|
command: |
|
||||||
|
if [[ $CIRCLE_JOB == "android-build-official" ]]; then
|
||||||
|
yarn generate-source-maps-android upload \
|
||||||
|
--api-key=$BUGSNAG_KEY_OFFICIAL \
|
||||||
|
--app-version=$CIRCLE_BUILD_NUM \
|
||||||
|
--minifiedFile=android/app/build/generated/assets/react/officialPlay/release/app.bundle \
|
||||||
|
--source-map=android/app/build/generated/sourcemaps/react/officialPlay/release/app.bundle.map \
|
||||||
|
--minified-url=app.bundle \
|
||||||
|
--upload-sources
|
||||||
|
fi
|
||||||
|
if [[ $CIRCLE_JOB == "android-build-experimental" ]]; then
|
||||||
|
yarn generate-source-maps-android upload \
|
||||||
|
--api-key=$BUGSNAG_KEY \
|
||||||
|
--app-version=$CIRCLE_BUILD_NUM \
|
||||||
|
--minifiedFile=android/app/build/generated/assets/react/experimentalPlay/release/app.bundle \
|
||||||
|
--source-map=android/app/build/generated/sourcemaps/react/experimentalPlay/release/app.bundle.map \
|
||||||
|
--minified-url=app.bundle \
|
||||||
|
--upload-sources
|
||||||
|
fi
|
||||||
|
|
||||||
|
- store_artifacts:
|
||||||
|
path: android/app/build/outputs
|
||||||
|
|
||||||
|
- save_cache: *save-npm-cache-linux
|
||||||
|
|
||||||
|
- save_cache: *save-gradle-cache
|
||||||
|
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: .
|
||||||
|
paths:
|
||||||
|
- android/app/build/outputs
|
||||||
|
|
||||||
|
ios-build:
|
||||||
|
description: "Build iOS app"
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- restore_cache: *restore-gems-cache
|
||||||
|
- restore_cache: *restore-npm-cache-mac
|
||||||
|
- run: *install-node
|
||||||
|
- run: *install-npm-modules
|
||||||
|
- run: *update-fastlane-ios
|
||||||
|
- run:
|
||||||
|
name: Set Google Services
|
||||||
|
command: |
|
||||||
|
if [[ $KEYSTORE ]]; then
|
||||||
|
echo $GOOGLE_SERVICES_IOS | base64 --decode > GoogleService-Info.plist
|
||||||
|
fi
|
||||||
|
working_directory: ios
|
||||||
|
- run:
|
||||||
|
name: Upload sourcemaps to Bugsnag
|
||||||
|
command: |
|
||||||
|
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
||||||
|
yarn generate-source-maps-ios
|
||||||
|
curl https://upload.bugsnag.com/react-native-source-map \
|
||||||
|
-F apiKey=$BUGSNAG_KEY_OFFICIAL \
|
||||||
|
-F appBundleVersion=$CIRCLE_BUILD_NUM \
|
||||||
|
-F dev=false \
|
||||||
|
-F platform=ios \
|
||||||
|
-F sourceMap=@ios-release.bundle.map \
|
||||||
|
-F bundle=@ios-release.bundle
|
||||||
|
fi
|
||||||
|
if [[ $CIRCLE_JOB == "ios-build-experimental" ]]; then
|
||||||
|
yarn generate-source-maps-ios
|
||||||
|
curl https://upload.bugsnag.com/react-native-source-map \
|
||||||
|
-F apiKey=$BUGSNAG_KEY \
|
||||||
|
-F appBundleVersion=$CIRCLE_BUILD_NUM \
|
||||||
|
-F dev=false \
|
||||||
|
-F platform=ios \
|
||||||
|
-F sourceMap=@ios-release.bundle.map \
|
||||||
|
-F bundle=@ios-release.bundle
|
||||||
|
fi
|
||||||
|
- run:
|
||||||
|
name: Fastlane Build
|
||||||
|
no_output_timeout: 1200
|
||||||
|
command: |
|
||||||
|
agvtool new-version -all $CIRCLE_BUILD_NUM
|
||||||
|
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
||||||
|
/usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY_OFFICIAL" ./RocketChatRN/Info.plist
|
||||||
|
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL YES" ./RocketChatRN/Info.plist
|
||||||
|
else
|
||||||
|
/usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY" ./RocketChatRN/Info.plist
|
||||||
|
/usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./RocketChatRN/Info.plist
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $APP_STORE_CONNECT_API_KEY ]]; then
|
||||||
|
echo $APP_STORE_CONNECT_API_KEY | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
||||||
|
if [[ $CIRCLE_JOB == "ios-build-official" ]]; then
|
||||||
|
bundle exec fastlane ios build_official
|
||||||
|
else
|
||||||
|
if [[ $KEYSTORE ]]; then
|
||||||
|
bundle exec fastlane ios release # TODO: rename
|
||||||
|
else
|
||||||
|
bundle exec fastlane ios build_fork
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
working_directory: ios
|
||||||
|
- save_cache: *save-npm-cache-mac
|
||||||
|
- save_cache: *save-gems-cache
|
||||||
|
- store_artifacts:
|
||||||
|
path: ios/Rocket.Chat.ipa
|
||||||
|
- store_artifacts:
|
||||||
|
path: ios/Rocket.Chat.app.dSYM.zip
|
||||||
|
- persist_to_workspace:
|
||||||
|
root: .
|
||||||
|
paths:
|
||||||
|
- ios/*.ipa
|
||||||
|
- ios/*.zip
|
||||||
|
|
||||||
|
upload-to-google-play-beta:
|
||||||
|
description: "Upload to Google Play beta"
|
||||||
|
parameters:
|
||||||
|
official:
|
||||||
|
type: boolean
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- attach_workspace:
|
||||||
|
at: android
|
||||||
|
- run:
|
||||||
|
name: Store the google service account key
|
||||||
|
command: echo "$FASTLANE_GOOGLE_SERVICE_ACCOUNT" | base64 --decode > service_account.json
|
||||||
|
working_directory: android
|
||||||
|
- run: *update-fastlane-android
|
||||||
|
- run:
|
||||||
|
name: Fastlane Play Store Upload
|
||||||
|
command: bundle exec fastlane android beta official:<< parameters.official >>
|
||||||
|
working_directory: android
|
||||||
|
|
||||||
|
upload-to-testflight:
|
||||||
|
description: "Upload to TestFlight"
|
||||||
|
parameters:
|
||||||
|
official:
|
||||||
|
type: boolean
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- attach_workspace:
|
||||||
|
at: ios
|
||||||
|
- restore_cache: *restore-gems-cache
|
||||||
|
- run: *update-fastlane-ios
|
||||||
|
- run:
|
||||||
|
name: Fastlane Tesflight Upload
|
||||||
|
command: |
|
||||||
|
echo $APP_STORE_CONNECT_API_KEY | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
||||||
|
bundle exec fastlane ios beta official:<< parameters.official >>
|
||||||
|
working_directory: ios
|
||||||
|
- save_cache: *save-gems-cache
|
||||||
|
|
||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
# EXECUTORS
|
# EXECUTORS
|
||||||
|
@ -119,304 +349,124 @@ jobs:
|
||||||
- save_cache: *save-npm-cache-linux
|
- save_cache: *save-npm-cache-linux
|
||||||
|
|
||||||
# Android builds
|
# Android builds
|
||||||
android-play-build:
|
android-build-experimental:
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/android:api-28-node
|
- image: circleci/android:api-28-node
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
JAVA_OPTS: '-Xms512m -Xmx2g'
|
<<: *android-env
|
||||||
GRADLE_OPTS: '-Xmx3g -Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-Xmx2g -XX:+HeapDumpOnOutOfMemoryError"'
|
|
||||||
TERM: dumb
|
|
||||||
<<: *bash-env
|
<<: *bash-env
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- android-build
|
||||||
|
|
||||||
- run: *install-node
|
android-build-official:
|
||||||
|
|
||||||
- restore_cache: *restore-npm-cache-linux
|
|
||||||
|
|
||||||
- run: *install-npm-modules
|
|
||||||
|
|
||||||
- run: *update-fastlane-android
|
|
||||||
|
|
||||||
- restore_cache: *restore-gradle-cache
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Configure Gradle
|
|
||||||
command: |
|
|
||||||
echo -e "" > ./gradle.properties
|
|
||||||
# echo -e "android.enableAapt2=false" >> ./gradle.properties
|
|
||||||
echo -e "android.useAndroidX=true" >> ./gradle.properties
|
|
||||||
echo -e "android.enableJetifier=true" >> ./gradle.properties
|
|
||||||
echo -e "FLIPPER_VERSION=0.51.0" >> ./gradle.properties
|
|
||||||
echo -e "APPLICATION_ID=chat.rocket.reactnative" >> ./gradle.properties
|
|
||||||
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
|
|
||||||
echo -e "BugsnagAPIKey=$BUGSNAG_KEY" >> ./gradle.properties
|
|
||||||
|
|
||||||
if [[ $KEYSTORE ]]; then
|
|
||||||
echo $KEYSTORE_BASE64 | base64 --decode > ./app/$KEYSTORE
|
|
||||||
echo -e "KEYSTORE=$KEYSTORE" >> ./gradle.properties
|
|
||||||
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
|
||||||
echo -e "KEY_ALIAS=$KEY_ALIAS" >> ./gradle.properties
|
|
||||||
echo -e "KEY_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
|
||||||
fi
|
|
||||||
working_directory: android
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Set Google Services
|
|
||||||
command: |
|
|
||||||
if [[ $KEYSTORE ]]; then
|
|
||||||
echo $GOOGLE_SERVICES_ANDROID | base64 --decode > google-services.json
|
|
||||||
fi
|
|
||||||
working_directory: android/app/src/play
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Config variables
|
|
||||||
command: |
|
|
||||||
echo -e "export default { BUGSNAG_API_KEY: '$BUGSNAG_KEY' };" > ./config.js
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Build Android Play App
|
|
||||||
command: |
|
|
||||||
if [[ $KEYSTORE ]]; then
|
|
||||||
bundle exec fastlane android playRelease
|
|
||||||
else
|
|
||||||
bundle exec fastlane android playBuild
|
|
||||||
fi
|
|
||||||
working_directory: android
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Upload sourcemaps to Bugsnag
|
|
||||||
command: |
|
|
||||||
if [[ $BUGSNAG_KEY ]]; then
|
|
||||||
yarn generate-source-maps-android upload \
|
|
||||||
--api-key=$BUGSNAG_KEY \
|
|
||||||
--app-version=$CIRCLE_BUILD_NUM \
|
|
||||||
--minifiedFile=android/app/build/generated/assets/react/play/release/app.bundle \
|
|
||||||
--source-map=android/app/build/generated/sourcemaps/react/play/release/app.bundle.map \
|
|
||||||
--minified-url=app.bundle \
|
|
||||||
--upload-sources
|
|
||||||
fi
|
|
||||||
|
|
||||||
- store_artifacts:
|
|
||||||
path: android/app/build/outputs
|
|
||||||
|
|
||||||
- save_cache: *save-npm-cache-linux
|
|
||||||
|
|
||||||
- save_cache: *save-gradle-cache
|
|
||||||
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: .
|
|
||||||
paths:
|
|
||||||
- android/fastlane/report.xml
|
|
||||||
- android/app/build/outputs
|
|
||||||
|
|
||||||
android-foss-build:
|
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/android:api-28-node
|
- image: circleci/android:api-28-node
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
JAVA_OPTS: '-Xms512m -Xmx2g'
|
<<: *android-env
|
||||||
GRADLE_OPTS: '-Xmx3g -Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-Xmx2g -XX:+HeapDumpOnOutOfMemoryError"'
|
|
||||||
TERM: dumb
|
|
||||||
<<: *bash-env
|
<<: *bash-env
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- android-build
|
||||||
|
|
||||||
- run: *install-node
|
android-google-play-beta-experimental:
|
||||||
|
|
||||||
- restore_cache: *restore-npm-cache-linux
|
|
||||||
|
|
||||||
- run: *install-npm-modules
|
|
||||||
|
|
||||||
- run: *update-fastlane-android
|
|
||||||
|
|
||||||
- restore_cache: *restore-gradle-cache
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Configure Gradle
|
|
||||||
command: |
|
|
||||||
echo -e "" > ./gradle.properties
|
|
||||||
# echo -e "android.enableAapt2=false" >> ./gradle.properties
|
|
||||||
echo -e "android.useAndroidX=true" >> ./gradle.properties
|
|
||||||
echo -e "android.enableJetifier=true" >> ./gradle.properties
|
|
||||||
echo -e "FLIPPER_VERSION=0.51.0" >> ./gradle.properties
|
|
||||||
echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties
|
|
||||||
echo -e "APPLICATION_ID=chat.rocket.android" >> ./gradle.properties
|
|
||||||
|
|
||||||
if [[ $KEYSTORE ]]; then
|
|
||||||
echo $KEYSTORE_BASE64 | base64 --decode > ./app/$KEYSTORE
|
|
||||||
echo -e "KEYSTORE=$KEYSTORE" >> ./gradle.properties
|
|
||||||
echo -e "KEYSTORE_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
|
||||||
echo -e "KEY_ALIAS=$KEY_ALIAS" >> ./gradle.properties
|
|
||||||
echo -e "KEY_PASSWORD=$KEYSTORE_PASSWORD" >> ./gradle.properties
|
|
||||||
fi
|
|
||||||
working_directory: android
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Build Android Foss App
|
|
||||||
command: bundle exec fastlane android fossRelease
|
|
||||||
working_directory: android
|
|
||||||
|
|
||||||
- store_artifacts:
|
|
||||||
path: android/app/build/outputs
|
|
||||||
|
|
||||||
- save_cache: *save-npm-cache-linux
|
|
||||||
|
|
||||||
- save_cache: *save-gradle-cache
|
|
||||||
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: .
|
|
||||||
paths:
|
|
||||||
- android/fastlane/report.xml
|
|
||||||
- android/app/build/outputs
|
|
||||||
|
|
||||||
android-google-play-beta:
|
|
||||||
<<: *defaults
|
<<: *defaults
|
||||||
docker:
|
docker:
|
||||||
- image: circleci/android:api-28-node
|
- image: circleci/android:api-28-node
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- upload-to-google-play-beta:
|
||||||
|
official: false
|
||||||
|
|
||||||
- attach_workspace:
|
android-google-play-beta-official:
|
||||||
at: android
|
<<: *defaults
|
||||||
|
docker:
|
||||||
|
- image: circleci/android:api-28-node
|
||||||
|
|
||||||
- run:
|
steps:
|
||||||
name: Store the google service account key
|
- upload-to-google-play-beta:
|
||||||
command: echo "$FASTLANE_GOOGLE_SERVICE_ACCOUNT" | base64 --decode > service_account.json
|
official: true
|
||||||
working_directory: android
|
|
||||||
|
|
||||||
- run: *update-fastlane-android
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Fastlane Play Store Upload
|
|
||||||
command: bundle exec fastlane android beta
|
|
||||||
working_directory: android
|
|
||||||
|
|
||||||
# iOS builds
|
# iOS builds
|
||||||
ios-build:
|
ios-build-experimental:
|
||||||
executor: mac-env
|
executor: mac-env
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- ios-build
|
||||||
|
|
||||||
- restore_cache: *restore-gems-cache
|
ios-build-official:
|
||||||
|
|
||||||
- restore_cache: *restore-npm-cache-mac
|
|
||||||
|
|
||||||
- run: *install-node
|
|
||||||
|
|
||||||
- run: *install-npm-modules
|
|
||||||
|
|
||||||
- run: *update-fastlane-ios
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Set Google Services
|
|
||||||
command: |
|
|
||||||
if [[ $KEYSTORE ]]; then
|
|
||||||
echo $GOOGLE_SERVICES_REACTNATIVE | base64 --decode > GoogleService-Info.plist
|
|
||||||
fi
|
|
||||||
working_directory: ios
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Upload sourcemaps to Bugsnag
|
|
||||||
command: |
|
|
||||||
if [[ $BUGSNAG_KEY ]]; then
|
|
||||||
yarn generate-source-maps-ios
|
|
||||||
curl https://upload.bugsnag.com/react-native-source-map \
|
|
||||||
-F apiKey=$BUGSNAG_KEY \
|
|
||||||
-F appBundleVersion=$CIRCLE_BUILD_NUM \
|
|
||||||
-F dev=false \
|
|
||||||
-F platform=ios \
|
|
||||||
-F sourceMap=@ios-release.bundle.map \
|
|
||||||
-F bundle=@ios-release.bundle
|
|
||||||
fi
|
|
||||||
|
|
||||||
- run:
|
|
||||||
name: Fastlane Build
|
|
||||||
no_output_timeout: 1200
|
|
||||||
command: |
|
|
||||||
agvtool new-version -all $CIRCLE_BUILD_NUM
|
|
||||||
/usr/libexec/PlistBuddy -c "Set BugsnagAPIKey $BUGSNAG_KEY" ./RocketChatRN/Info.plist
|
|
||||||
|
|
||||||
if [[ $APP_STORE_CONNECT_API_KEY ]]; then
|
|
||||||
echo $APP_STORE_CONNECT_API_KEY | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
|
||||||
bundle exec fastlane ios release
|
|
||||||
else
|
|
||||||
bundle exec fastlane ios build_fork
|
|
||||||
fi
|
|
||||||
working_directory: ios
|
|
||||||
|
|
||||||
- save_cache: *save-npm-cache-mac
|
|
||||||
|
|
||||||
- save_cache: *save-gems-cache
|
|
||||||
|
|
||||||
- store_artifacts:
|
|
||||||
path: ios/RocketChatRN.ipa
|
|
||||||
|
|
||||||
- persist_to_workspace:
|
|
||||||
root: .
|
|
||||||
paths:
|
|
||||||
- ios/*.ipa
|
|
||||||
- ios/fastlane/report.xml
|
|
||||||
|
|
||||||
ios-testflight:
|
|
||||||
executor: mac-env
|
executor: mac-env
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- ios-build
|
||||||
|
|
||||||
- attach_workspace:
|
ios-testflight-experimental:
|
||||||
at: ios
|
executor: mac-env
|
||||||
|
steps:
|
||||||
|
- upload-to-testflight:
|
||||||
|
official: false
|
||||||
|
|
||||||
- restore_cache: *restore-gems-cache
|
ios-testflight-official:
|
||||||
|
executor: mac-env
|
||||||
- run: *update-fastlane-ios
|
steps:
|
||||||
|
- upload-to-testflight:
|
||||||
- run:
|
official: true
|
||||||
name: Fastlane Tesflight Upload
|
|
||||||
command: |
|
|
||||||
echo $APP_STORE_CONNECT_API_KEY | base64 --decode > ./fastlane/app_store_connect_api_key.p8
|
|
||||||
bundle exec fastlane ios beta
|
|
||||||
working_directory: ios
|
|
||||||
|
|
||||||
- save_cache: *save-gems-cache
|
|
||||||
|
|
||||||
workflows:
|
workflows:
|
||||||
build-and-test:
|
build-and-test:
|
||||||
jobs:
|
jobs:
|
||||||
- lint-testunit
|
- lint-testunit
|
||||||
|
|
||||||
- ios-build:
|
# iOS Experimental
|
||||||
|
- ios-build-experimental:
|
||||||
requires:
|
requires:
|
||||||
- lint-testunit
|
- lint-testunit
|
||||||
- ios-hold-testflight:
|
- ios-hold-testflight-experimental:
|
||||||
type: approval
|
type: approval
|
||||||
requires:
|
requires:
|
||||||
- ios-build
|
- ios-build-experimental
|
||||||
- ios-testflight:
|
- ios-testflight-experimental:
|
||||||
requires:
|
requires:
|
||||||
- ios-hold-testflight
|
- ios-hold-testflight-experimental
|
||||||
|
|
||||||
- android-play-build:
|
# iOS Official
|
||||||
requires:
|
- ios-hold-build-official:
|
||||||
- lint-testunit
|
|
||||||
- android-hold-google-play-beta:
|
|
||||||
type: approval
|
|
||||||
requires:
|
|
||||||
- android-play-build
|
|
||||||
- android-google-play-beta:
|
|
||||||
requires:
|
|
||||||
- android-hold-google-play-beta
|
|
||||||
- android-hold-foss-build:
|
|
||||||
type: approval
|
type: approval
|
||||||
requires:
|
requires:
|
||||||
- lint-testunit
|
- lint-testunit
|
||||||
- android-foss-build:
|
- ios-build-official:
|
||||||
requires:
|
requires:
|
||||||
- android-hold-foss-build
|
- ios-hold-build-official
|
||||||
|
- ios-hold-testflight-official:
|
||||||
|
type: approval
|
||||||
|
requires:
|
||||||
|
- ios-build-official
|
||||||
|
- ios-testflight-official:
|
||||||
|
requires:
|
||||||
|
- ios-hold-testflight-official
|
||||||
|
|
||||||
|
# Android Experimental
|
||||||
|
- android-build-experimental:
|
||||||
|
requires:
|
||||||
|
- lint-testunit
|
||||||
|
- android-hold-google-play-beta-experimental:
|
||||||
|
type: approval
|
||||||
|
requires:
|
||||||
|
- android-build-experimental
|
||||||
|
- android-google-play-beta-experimental:
|
||||||
|
requires:
|
||||||
|
- android-hold-google-play-beta-experimental
|
||||||
|
|
||||||
|
# Android Official
|
||||||
|
- android-hold-build-official:
|
||||||
|
type: approval
|
||||||
|
requires:
|
||||||
|
- lint-testunit
|
||||||
|
- android-build-official:
|
||||||
|
requires:
|
||||||
|
- android-hold-build-official
|
||||||
|
- android-hold-google-play-beta-official:
|
||||||
|
type: approval
|
||||||
|
requires:
|
||||||
|
- android-build-official
|
||||||
|
- android-google-play-beta-official:
|
||||||
|
requires:
|
||||||
|
- android-hold-google-play-beta-official
|
||||||
|
|
|
@ -21,6 +21,7 @@ DerivedData
|
||||||
*.ipa
|
*.ipa
|
||||||
*.xcuserstate
|
*.xcuserstate
|
||||||
project.xcworkspace
|
project.xcworkspace
|
||||||
|
*.mobileprovision
|
||||||
|
|
||||||
# Android/IntelliJ
|
# Android/IntelliJ
|
||||||
#
|
#
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
|
def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
|
||||||
def isPlay = !taskRequests.contains("foss")
|
def isFoss = taskRequests.contains("foss")
|
||||||
|
|
||||||
apply plugin: "com.android.application"
|
apply plugin: "com.android.application"
|
||||||
apply plugin: 'kotlin-android'
|
apply plugin: 'kotlin-android'
|
||||||
|
|
||||||
if (isPlay) {
|
if (!isFoss) {
|
||||||
apply plugin: 'com.google.firebase.crashlytics'
|
apply plugin: 'com.google.firebase.crashlytics'
|
||||||
apply plugin: 'com.bugsnag.android.gradle'
|
apply plugin: 'com.bugsnag.android.gradle'
|
||||||
}
|
}
|
||||||
|
@ -146,7 +146,7 @@ android {
|
||||||
versionCode VERSIONCODE as Integer
|
versionCode VERSIONCODE as Integer
|
||||||
versionName "4.13.0"
|
versionName "4.13.0"
|
||||||
vectorDrawables.useSupportLibrary = true
|
vectorDrawables.useSupportLibrary = true
|
||||||
if (isPlay) {
|
if (!isFoss) {
|
||||||
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
|
||||||
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60" // See note below!
|
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60" // See note below!
|
||||||
}
|
}
|
||||||
|
@ -176,7 +176,7 @@ android {
|
||||||
minifyEnabled enableProguardInReleaseBuilds
|
minifyEnabled enableProguardInReleaseBuilds
|
||||||
setProguardFiles([getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'])
|
setProguardFiles([getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'])
|
||||||
signingConfig signingConfigs.release
|
signingConfig signingConfigs.release
|
||||||
if (isPlay) {
|
if (!isFoss) {
|
||||||
firebaseCrashlytics {
|
firebaseCrashlytics {
|
||||||
nativeSymbolUploadEnabled true
|
nativeSymbolUploadEnabled true
|
||||||
}
|
}
|
||||||
|
@ -193,10 +193,17 @@ android {
|
||||||
|
|
||||||
// applicationVariants are e.g. debug, release
|
// applicationVariants are e.g. debug, release
|
||||||
|
|
||||||
flavorDimensions "type"
|
flavorDimensions "app", "type"
|
||||||
productFlavors {
|
productFlavors {
|
||||||
|
official {
|
||||||
|
dimension = "app"
|
||||||
|
buildConfigField "boolean", "IS_OFFICIAL", "true"
|
||||||
|
}
|
||||||
|
experimental {
|
||||||
|
dimension = "app"
|
||||||
|
buildConfigField "boolean", "IS_OFFICIAL", "false"
|
||||||
|
}
|
||||||
foss {
|
foss {
|
||||||
applicationId APPLICATION_ID
|
|
||||||
dimension = "type"
|
dimension = "type"
|
||||||
buildConfigField "boolean", "FDROID_BUILD", "true"
|
buildConfigField "boolean", "FDROID_BUILD", "true"
|
||||||
}
|
}
|
||||||
|
@ -206,11 +213,20 @@ android {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sourceSets {
|
sourceSets {
|
||||||
playDebug {
|
// TODO: refactor making sure notifications are working properly both on debug and release
|
||||||
|
experimentalPlayDebug {
|
||||||
java.srcDirs = ['src/main/java', 'src/play/java']
|
java.srcDirs = ['src/main/java', 'src/play/java']
|
||||||
manifest.srcFile 'src/play/AndroidManifest.xml'
|
manifest.srcFile 'src/play/AndroidManifest.xml'
|
||||||
}
|
}
|
||||||
playRelease {
|
experimentalPlayRelease {
|
||||||
|
java.srcDirs = ['src/main/java', 'src/play/java']
|
||||||
|
manifest.srcFile 'src/play/AndroidManifest.xml'
|
||||||
|
}
|
||||||
|
officialPlayDebug {
|
||||||
|
java.srcDirs = ['src/main/java', 'src/play/java']
|
||||||
|
manifest.srcFile 'src/play/AndroidManifest.xml'
|
||||||
|
}
|
||||||
|
officialPlayRelease {
|
||||||
java.srcDirs = ['src/main/java', 'src/play/java']
|
java.srcDirs = ['src/main/java', 'src/play/java']
|
||||||
manifest.srcFile 'src/play/AndroidManifest.xml'
|
manifest.srcFile 'src/play/AndroidManifest.xml'
|
||||||
}
|
}
|
||||||
|
@ -287,6 +303,6 @@ task copyDownloadableDepsToLibs(type: Copy) {
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||||
if (isPlay) {
|
if (!isFoss) {
|
||||||
apply plugin: 'com.google.gms.google-services'
|
apply plugin: 'com.google.gms.google-services'
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,83 @@
|
||||||
|
{
|
||||||
|
"project_info": {
|
||||||
|
"project_number": "115198584049",
|
||||||
|
"firebase_url": "https://rocketchat-reactnative-test.firebaseio.com",
|
||||||
|
"project_id": "rocketchat-reactnative-test",
|
||||||
|
"storage_bucket": "rocketchat-reactnative-test.appspot.com"
|
||||||
|
},
|
||||||
|
"client": [
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:115198584049:android:a79216ae48935d2c9ab550",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "chat.rocket.android"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "115198584049-ack609b1338b827fta26s9rd2ab1aad5.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyAWwowhAfACHBw3YxmDOXY3QyakgjhJLqc"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "115198584049-ack609b1338b827fta26s9rd2ab1aad5.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_id": "115198584049-0efgfvm0oh9ap55g7epmqnjm27mq3j4e.apps.googleusercontent.com",
|
||||||
|
"client_type": 2,
|
||||||
|
"ios_info": {
|
||||||
|
"bundle_id": "chat.rocket.reactnative"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_info": {
|
||||||
|
"mobilesdk_app_id": "1:115198584049:android:8be27b1f7c42a2ed",
|
||||||
|
"android_client_info": {
|
||||||
|
"package_name": "chat.rocket.reactnative"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "115198584049-ack609b1338b827fta26s9rd2ab1aad5.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"api_key": [
|
||||||
|
{
|
||||||
|
"current_key": "AIzaSyAWwowhAfACHBw3YxmDOXY3QyakgjhJLqc"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"services": {
|
||||||
|
"appinvite_service": {
|
||||||
|
"other_platform_oauth_client": [
|
||||||
|
{
|
||||||
|
"client_id": "115198584049-ack609b1338b827fta26s9rd2ab1aad5.apps.googleusercontent.com",
|
||||||
|
"client_type": 3
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"client_id": "115198584049-0efgfvm0oh9ap55g7epmqnjm27mq3j4e.apps.googleusercontent.com",
|
||||||
|
"client_type": 2,
|
||||||
|
"ios_info": {
|
||||||
|
"bundle_id": "chat.rocket.reactnative"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"configuration_version": "1"
|
||||||
|
}
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
Before Width: | Height: | Size: 5.2 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 7.7 KiB After Width: | Height: | Size: 7.7 KiB |
Before Width: | Height: | Size: 7.3 KiB After Width: | Height: | Size: 7.3 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
|
@ -1,4 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<resources>
|
|
||||||
<item name="splashBackground" type="color">#000000</item>
|
|
||||||
</resources>
|
|
|
@ -1,28 +0,0 @@
|
||||||
<resources>
|
|
||||||
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
|
|
||||||
<item name="android:colorEdgeEffect">#aaaaaa</item>
|
|
||||||
<item name="colorPrimaryDark">@color/splashBackground</item>
|
|
||||||
<item name="android:navigationBarColor">@color/splashBackground</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="Share.Window" parent="android:Theme">
|
|
||||||
<item name="android:windowEnterAnimation">@null</item>
|
|
||||||
<item name="android:windowExitAnimation">@null</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="Theme.Share.Transparent" parent="android:Theme">
|
|
||||||
<item name="android:windowIsTranslucent">true</item>
|
|
||||||
<item name="android:windowBackground">@color/primary_dark</item>
|
|
||||||
<item name="android:windowContentOverlay">@null</item>
|
|
||||||
<item name="android:windowNoTitle">true</item>
|
|
||||||
<item name="android:windowIsFloating">true</item>
|
|
||||||
<item name="android:backgroundDimEnabled">true</item>
|
|
||||||
<item name="android:windowAnimationStyle">@style/Share.Window</item>
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<style name="BootTheme" parent="AppTheme">
|
|
||||||
<item name="android:background">@drawable/launch_screen</item>
|
|
||||||
<item name="colorPrimaryDark">@color/splashBackground</item>
|
|
||||||
<item name="android:navigationBarColor">@color/splashBackground</item>
|
|
||||||
</style>
|
|
||||||
</resources>
|
|
|
@ -1,5 +1,4 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<item name="splashBackground" type="color">#000000</item>
|
<item name="splashBackground" type="color">#000000</item>
|
||||||
<item name="notification_text" type="color">#1D74F5</item>
|
|
||||||
</resources>
|
</resources>
|
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 19 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
Before Width: | Height: | Size: 2.0 KiB After Width: | Height: | Size: 2.0 KiB |
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.5 KiB After Width: | Height: | Size: 2.5 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 8.6 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
@ -1,40 +0,0 @@
|
||||||
{
|
|
||||||
"project_info": {
|
|
||||||
"project_number": "115198584049",
|
|
||||||
"firebase_url": "https://rocketchat-reactnative-test.firebaseio.com",
|
|
||||||
"project_id": "rocketchat-reactnative-test",
|
|
||||||
"storage_bucket": "rocketchat-reactnative-test.appspot.com"
|
|
||||||
},
|
|
||||||
"client": [
|
|
||||||
{
|
|
||||||
"client_info": {
|
|
||||||
"mobilesdk_app_id": "1:115198584049:android:8be27b1f7c42a2ed",
|
|
||||||
"android_client_info": {
|
|
||||||
"package_name": "chat.rocket.reactnative"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"oauth_client": [
|
|
||||||
{
|
|
||||||
"client_id": "115198584049-ack609b1338b827fta26s9rd2ab1aad5.apps.googleusercontent.com",
|
|
||||||
"client_type": 3
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"api_key": [
|
|
||||||
{
|
|
||||||
"current_key": "AIzaSyAWwowhAfACHBw3YxmDOXY3QyakgjhJLqc"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"services": {
|
|
||||||
"appinvite_service": {
|
|
||||||
"other_platform_oauth_client": [
|
|
||||||
{
|
|
||||||
"client_id": "115198584049-ack609b1338b827fta26s9rd2ab1aad5.apps.googleusercontent.com",
|
|
||||||
"client_type": 3
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"configuration_version": "1"
|
|
||||||
}
|
|
|
@ -1,28 +1,22 @@
|
||||||
package chat.rocket.reactnative;
|
package chat.rocket.reactnative;
|
||||||
|
|
||||||
import android.util.Log;
|
|
||||||
import android.util.Base64;
|
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.util.Base64;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
import com.pedrouid.crypto.RSA;
|
import com.facebook.react.bridge.Arguments;
|
||||||
|
import com.facebook.react.bridge.ReactApplicationContext;
|
||||||
|
import com.facebook.react.bridge.WritableMap;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.nozbe.watermelondb.Database;
|
||||||
import com.pedrouid.crypto.RCTAes;
|
import com.pedrouid.crypto.RCTAes;
|
||||||
import com.pedrouid.crypto.RCTRsaUtils;
|
import com.pedrouid.crypto.RCTRsaUtils;
|
||||||
|
import com.pedrouid.crypto.RSA;
|
||||||
import com.pedrouid.crypto.Util;
|
import com.pedrouid.crypto.Util;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
import com.facebook.react.bridge.Promise;
|
|
||||||
import com.facebook.react.bridge.Arguments;
|
|
||||||
import com.facebook.react.bridge.ReactMethod;
|
|
||||||
import com.facebook.react.bridge.ReadableMap;
|
|
||||||
import com.facebook.react.bridge.WritableMap;
|
|
||||||
import com.facebook.react.bridge.ReactApplicationContext;
|
|
||||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
|
||||||
|
|
||||||
import com.nozbe.watermelondb.Database;
|
|
||||||
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
class Message {
|
class Message {
|
||||||
String _id;
|
String _id;
|
||||||
|
@ -69,8 +63,24 @@ class Encryption {
|
||||||
public static Encryption shared = new Encryption();
|
public static Encryption shared = new Encryption();
|
||||||
private ReactApplicationContext reactContext;
|
private ReactApplicationContext reactContext;
|
||||||
|
|
||||||
public Room readRoom(final Ejson ejson) {
|
public Room readRoom(final Ejson ejson) throws NoSuchFieldException {
|
||||||
Database database = new Database(ejson.serverURL().replace("https://", "") + "-experimental.db", reactContext);
|
int resId = reactContext.getResources().getIdentifier("rn_config_reader_custom_package", "string", reactContext.getPackageName());
|
||||||
|
String className = reactContext.getString(resId);
|
||||||
|
Class clazz = null;
|
||||||
|
Boolean isOfficial = false;
|
||||||
|
try {
|
||||||
|
clazz = Class.forName(className + ".BuildConfig");
|
||||||
|
Field IS_OFFICIAL = clazz.getField("IS_OFFICIAL");
|
||||||
|
isOfficial = (Boolean) IS_OFFICIAL.get(null);
|
||||||
|
} catch (ClassNotFoundException | IllegalAccessException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
String dbName = ejson.serverURL().replace("https://", "");
|
||||||
|
if (!isOfficial) {
|
||||||
|
dbName += "-experimental";
|
||||||
|
}
|
||||||
|
dbName += ".db";
|
||||||
|
Database database = new Database(dbName, reactContext);
|
||||||
String[] query = {ejson.rid};
|
String[] query = {ejson.rid};
|
||||||
Cursor cursor = database.rawQuery("select * from subscriptions where id == ? limit 1", query);
|
Cursor cursor = database.rawQuery("select * from subscriptions where id == ? limit 1", query);
|
||||||
|
|
||||||
|
@ -152,7 +162,7 @@ class Encryption {
|
||||||
|
|
||||||
return m.text;
|
return m.text;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d("[ROCKETCHAT][ENCRYPTION]", Log.getStackTraceString(e));
|
Log.d("[ROCKETCHAT][E2E]", Log.getStackTraceString(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -182,7 +192,7 @@ class Encryption {
|
||||||
|
|
||||||
return keyId + Base64.encodeToString(concat(bytes, data), Base64.NO_WRAP);
|
return keyId + Base64.encodeToString(concat(bytes, data), Base64.NO_WRAP);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.d("[ROCKETCHAT][ENCRYPTION]", Log.getStackTraceString(e));
|
Log.d("[ROCKETCHAT][E2E]", Log.getStackTraceString(e));
|
||||||
}
|
}
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
|
|
|
@ -16,26 +16,20 @@
|
||||||
default_platform(:android)
|
default_platform(:android)
|
||||||
|
|
||||||
platform :android do
|
platform :android do
|
||||||
desc "Play build for development"
|
|
||||||
lane :playBuild do
|
|
||||||
gradle(task: "assemblePlayDebug")
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "Foss build for release"
|
|
||||||
lane :fossRelease do
|
|
||||||
gradle(task: "assembleFossRelease")
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "Play build for release"
|
|
||||||
lane :playRelease do
|
|
||||||
gradle(task: "bundlePlayRelease")
|
|
||||||
end
|
|
||||||
|
|
||||||
desc "Upload App to Play Store Internal"
|
desc "Upload App to Play Store Internal"
|
||||||
lane :beta do
|
lane :beta do |options|
|
||||||
|
if options[:official]
|
||||||
upload_to_play_store(
|
upload_to_play_store(
|
||||||
|
package_name: 'chat.rocket.android',
|
||||||
track: 'internal',
|
track: 'internal',
|
||||||
aab: 'android/app/build/outputs/bundle/playRelease/app-play-release.aab'
|
aab: 'android/app/build/outputs/bundle/officialPlayRelease/app-official-play-release.aab'
|
||||||
|
)
|
||||||
|
else
|
||||||
|
upload_to_play_store(
|
||||||
|
package_name: 'chat.rocket.reactnative',
|
||||||
|
track: 'internal',
|
||||||
|
aab: 'android/app/build/outputs/bundle/experimentalPlayRelease/app-experimental-play-release.aab'
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
import RNConfigReader from 'react-native-config-reader';
|
import RNConfigReader from 'react-native-config-reader';
|
||||||
|
|
||||||
export const isFDroidBuild = RNConfigReader.FDROID_BUILD;
|
export const isFDroidBuild = RNConfigReader.FDROID_BUILD;
|
||||||
|
|
||||||
|
export const isOfficial = RNConfigReader.IS_OFFICIAL;
|
||||||
|
|
|
@ -28,6 +28,7 @@ import serversMigrations from './model/servers/migrations';
|
||||||
|
|
||||||
import { isIOS } from '../../utils/deviceInfo';
|
import { isIOS } from '../../utils/deviceInfo';
|
||||||
import appGroup from '../../utils/appGroup';
|
import appGroup from '../../utils/appGroup';
|
||||||
|
import { isOfficial } from '../../constants/environment';
|
||||||
|
|
||||||
const appGroupPath = isIOS ? appGroup.path : '';
|
const appGroupPath = isIOS ? appGroup.path : '';
|
||||||
|
|
||||||
|
@ -35,9 +36,11 @@ if (__DEV__ && isIOS) {
|
||||||
console.log(appGroupPath);
|
console.log(appGroupPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getDatabasePath = name => `${ appGroupPath }${ name }${ isOfficial ? '' : '-experimental' }.db`;
|
||||||
|
|
||||||
export const getDatabase = (database = '') => {
|
export const getDatabase = (database = '') => {
|
||||||
const path = database.replace(/(^\w+:|^)\/\//, '').replace(/\//g, '.');
|
const path = database.replace(/(^\w+:|^)\/\//, '').replace(/\//g, '.');
|
||||||
const dbName = `${ appGroupPath }${ path }-experimental.db`;
|
const dbName = getDatabasePath(path);
|
||||||
|
|
||||||
const adapter = new SQLiteAdapter({
|
const adapter = new SQLiteAdapter({
|
||||||
dbName,
|
dbName,
|
||||||
|
@ -70,7 +73,7 @@ class DB {
|
||||||
databases = {
|
databases = {
|
||||||
serversDB: new Database({
|
serversDB: new Database({
|
||||||
adapter: new SQLiteAdapter({
|
adapter: new SQLiteAdapter({
|
||||||
dbName: `${ appGroupPath }default-experimental.db`,
|
dbName: getDatabasePath('default'),
|
||||||
schema: serversSchema,
|
schema: serversSchema,
|
||||||
migrations: serversMigrations
|
migrations: serversMigrations
|
||||||
}),
|
}),
|
||||||
|
@ -97,7 +100,7 @@ class DB {
|
||||||
|
|
||||||
setShareDB(database = '') {
|
setShareDB(database = '') {
|
||||||
const path = database.replace(/(^\w+:|^)\/\//, '').replace(/\//g, '.');
|
const path = database.replace(/(^\w+:|^)\/\//, '').replace(/\//g, '.');
|
||||||
const dbName = `${ appGroupPath }${ path }-experimental.db`;
|
const dbName = getDatabasePath(path);
|
||||||
|
|
||||||
const adapter = new SQLiteAdapter({
|
const adapter = new SQLiteAdapter({
|
||||||
dbName,
|
dbName,
|
||||||
|
|
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 8.7 KiB |
Before Width: | Height: | Size: 424 KiB After Width: | Height: | Size: 424 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
Before Width: | Height: | Size: 981 B After Width: | Height: | Size: 981 B |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.4 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.1 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 7.5 KiB After Width: | Height: | Size: 7.5 KiB |
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.0 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -0,0 +1,59 @@
|
||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "extended-srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.945",
|
||||||
|
"green" : "0.937",
|
||||||
|
"red" : "0.933"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "light"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "extended-srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.961",
|
||||||
|
"green" : "0.455",
|
||||||
|
"red" : "0.114"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"color" : {
|
||||||
|
"color-space" : "srgb",
|
||||||
|
"components" : {
|
||||||
|
"alpha" : "1.000",
|
||||||
|
"blue" : "0.000",
|
||||||
|
"green" : "0.000",
|
||||||
|
"red" : "0.000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
},
|
||||||
|
"properties" : {
|
||||||
|
"localizable" : true
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,9 +1,9 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16097.3" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Dtp-p8-LvN">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Dtp-p8-LvN">
|
||||||
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
<device id="retina6_1" orientation="portrait" appearance="light"/>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17505"/>
|
||||||
<capability name="Named colors" minToolsVersion="9.0"/>
|
<capability name="Named colors" minToolsVersion="9.0"/>
|
||||||
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
|
||||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
|
@ -24,6 +24,7 @@
|
||||||
</accessibility>
|
</accessibility>
|
||||||
</imageView>
|
</imageView>
|
||||||
</subviews>
|
</subviews>
|
||||||
|
<viewLayoutGuide key="safeArea" id="eg9-kz-Dhh"/>
|
||||||
<color key="backgroundColor" name="splashBackgroundColor"/>
|
<color key="backgroundColor" name="splashBackgroundColor"/>
|
||||||
<accessibility key="accessibilityConfiguration">
|
<accessibility key="accessibilityConfiguration">
|
||||||
<accessibilityTraits key="traits" notEnabled="YES"/>
|
<accessibilityTraits key="traits" notEnabled="YES"/>
|
||||||
|
@ -32,7 +33,6 @@
|
||||||
<constraint firstItem="3lX-Ut-9ad" firstAttribute="centerX" secondItem="eg9-kz-Dhh" secondAttribute="centerX" id="Fh9-Fy-1nT"/>
|
<constraint firstItem="3lX-Ut-9ad" firstAttribute="centerX" secondItem="eg9-kz-Dhh" secondAttribute="centerX" id="Fh9-Fy-1nT"/>
|
||||||
<constraint firstItem="3lX-Ut-9ad" firstAttribute="centerY" secondItem="guO-oA-Nhw" secondAttribute="centerY" id="nvB-Ic-PnI"/>
|
<constraint firstItem="3lX-Ut-9ad" firstAttribute="centerY" secondItem="guO-oA-Nhw" secondAttribute="centerY" id="nvB-Ic-PnI"/>
|
||||||
</constraints>
|
</constraints>
|
||||||
<viewLayoutGuide key="safeArea" id="eg9-kz-Dhh"/>
|
|
||||||
</view>
|
</view>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="Lvb-Jr-bCV" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="Lvb-Jr-bCV" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
|
||||||
|
@ -43,7 +43,7 @@
|
||||||
<resources>
|
<resources>
|
||||||
<image name="Launch Screen Icon" width="148" height="148"/>
|
<image name="Launch Screen Icon" width="148" height="148"/>
|
||||||
<namedColor name="splashBackgroundColor">
|
<namedColor name="splashBackgroundColor">
|
||||||
<color red="0.11372549086809158" green="0.45490196347236633" blue="0.96078431606292725" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color red="0.96078431606292725" green="0.27058824896812439" blue="0.36078432202339172" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</namedColor>
|
</namedColor>
|
||||||
</resources>
|
</resources>
|
||||||
</document>
|
</document>
|
||||||
|
|
|
@ -2,8 +2,6 @@
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
<plist version="1.0">
|
<plist version="1.0">
|
||||||
<dict>
|
<dict>
|
||||||
<key>KeychainGroup</key>
|
|
||||||
<string>$(AppIdentifierPrefix)chat.rocket.reactnative</string>
|
|
||||||
<key>AppGroup</key>
|
<key>AppGroup</key>
|
||||||
<string>group.ios.chat.rocket</string>
|
<string>group.ios.chat.rocket</string>
|
||||||
<key>CFBundleDevelopmentRegion</key>
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
@ -24,6 +22,8 @@
|
||||||
<string>$(MARKETING_VERSION)</string>
|
<string>$(MARKETING_VERSION)</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
<string>1</string>
|
<string>1</string>
|
||||||
|
<key>KeychainGroup</key>
|
||||||
|
<string>$(AppIdentifierPrefix)chat.rocket.reactnative</string>
|
||||||
<key>NSExtension</key>
|
<key>NSExtension</key>
|
||||||
<dict>
|
<dict>
|
||||||
<key>NSExtensionPointIdentifier</key>
|
<key>NSExtensionPointIdentifier</key>
|
||||||
|
|
After Width: | Height: | Size: 5.4 KiB |
After Width: | Height: | Size: 56 KiB |
After Width: | Height: | Size: 6.2 KiB |
After Width: | Height: | Size: 6.7 KiB |
After Width: | Height: | Size: 7.9 KiB |
After Width: | Height: | Size: 8.4 KiB |
After Width: | Height: | Size: 9.3 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 853 B |
After Width: | Height: | Size: 1.3 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 2.9 KiB |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 3.8 KiB |
After Width: | Height: | Size: 4.0 KiB |
After Width: | Height: | Size: 4.3 KiB |
After Width: | Height: | Size: 4.6 KiB |
|
@ -0,0 +1,158 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "40.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "20x20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "60.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "3x",
|
||||||
|
"size" : "20x20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "29.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "29x29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "58.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "29x29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "87.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "3x",
|
||||||
|
"size" : "29x29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "80.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "40x40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "120.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "3x",
|
||||||
|
"size" : "40x40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "57.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "57x57"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "114.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "57x57"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "120.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "60x60"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "180.png",
|
||||||
|
"idiom" : "iphone",
|
||||||
|
"scale" : "3x",
|
||||||
|
"size" : "60x60"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "20.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "20x20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "40.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "20x20"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "29.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "29x29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "58.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "29x29"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "40.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "40x40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "80.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "40x40"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "50.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "50x50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "100.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "50x50"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "72.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "72x72"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "144.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "72x72"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "76.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "76x76"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "152.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "76x76"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "167.png",
|
||||||
|
"idiom" : "ipad",
|
||||||
|
"scale" : "2x",
|
||||||
|
"size" : "83.5x83.5"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "1024.png",
|
||||||
|
"idiom" : "ios-marketing",
|
||||||
|
"scale" : "1x",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"filename" : "Icon.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Icon@2x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"filename" : "Icon@3x.png",
|
||||||
|
"idiom" : "universal",
|
||||||
|
"scale" : "3x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
After Width: | Height: | Size: 2.1 KiB |