diff --git a/.circleci/config.yml b/.circleci/config.yml
index fc1961f59..a1cf5ced5 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -119,7 +119,7 @@ jobs:
- save_cache: *save-npm-cache-linux
# Android builds
- android-build:
+ android-play-build:
<<: *defaults
docker:
- image: circleci/android:api-28-node
@@ -178,12 +178,12 @@ jobs:
echo -e "export default { BUGSNAG_API_KEY: '$BUGSNAG_KEY' };" > ./config.js
- run:
- name: Build Android App
+ name: Build Android Play App
command: |
if [[ $KEYSTORE ]]; then
- bundle exec fastlane android release
+ bundle exec fastlane android playRelease
else
- bundle exec fastlane android build
+ bundle exec fastlane android playBuild
fi
working_directory: android
@@ -194,8 +194,8 @@ jobs:
yarn generate-source-maps-android upload \
--api-key=$BUGSNAG_KEY \
--app-version=$CIRCLE_BUILD_NUM \
- --minifiedFile=android/app/build/generated/assets/react/release/app.bundle \
- --source-map=android/app/build/generated/sourcemaps/react/release/app.bundle.map \
+ --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
@@ -213,6 +213,67 @@ jobs:
- android/fastlane/report.xml
- android/app/build/outputs
+ android-foss-build:
+ <<: *defaults
+ docker:
+ - image: circleci/android:api-28-node
+
+ environment:
+ JAVA_OPTS: '-Xms512m -Xmx2g'
+ GRADLE_OPTS: '-Xmx3g -Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-Xmx2g -XX:+HeapDumpOnOutOfMemoryError"'
+ TERM: dumb
+ <<: *bash-env
+
+ steps:
+ - checkout
+
+ - run: *install-node
+
+ - 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
+
+ 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
docker:
@@ -341,13 +402,20 @@ workflows:
requires:
- ios-hold-testflight
- - android-build:
+ - android-play-build:
requires:
- lint-testunit
- android-hold-google-play-beta:
type: approval
requires:
- - android-build
+ - android-play-build
- android-google-play-beta:
requires:
- android-hold-google-play-beta
+ - android-hold-foss-build:
+ type: approval
+ requires:
+ - lint-testunit
+ - android-foss-build:
+ requires:
+ - android-hold-foss-build
diff --git a/__mocks__/react-native-config-reader.js b/__mocks__/react-native-config-reader.js
new file mode 100644
index 000000000..2286d3cb6
--- /dev/null
+++ b/__mocks__/react-native-config-reader.js
@@ -0,0 +1,3 @@
+export default {
+ BuildConfigs: null
+};
diff --git a/android/Gemfile.lock b/android/Gemfile.lock
index 0c51b23fc..5488439fc 100644
--- a/android/Gemfile.lock
+++ b/android/Gemfile.lock
@@ -81,7 +81,6 @@ GEM
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
- fastlane-plugin-appcenter (1.8.0)
gh_inspector (1.1.3)
google-api-client (0.36.4)
addressable (~> 2.5, >= 2.5.1)
@@ -156,6 +155,7 @@ GEM
uber (0.1.0)
unf (0.1.4)
unf_ext
+ unf_ext (0.0.7.7)
unf_ext (0.0.7.7-x64-mingw32)
unicode-display_width (1.7.0)
word_wrap (1.0.0)
@@ -171,11 +171,11 @@ GEM
xcpretty (~> 0.2, >= 0.0.7)
PLATFORMS
+ ruby
x64-mingw32
DEPENDENCIES
fastlane
- fastlane-plugin-appcenter
BUNDLED WITH
2.0.2
diff --git a/android/app/build.gradle b/android/app/build.gradle
index c202892ab..566f17dd4 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,8 +1,13 @@
+def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
+def isPlay = !taskRequests.contains("foss")
+
apply plugin: "com.android.application"
-apply plugin: 'com.google.gms.google-services'
-apply plugin: 'com.google.firebase.crashlytics'
apply plugin: 'kotlin-android'
-apply plugin: 'com.bugsnag.android.gradle'
+
+if (isPlay) {
+ apply plugin: 'com.google.firebase.crashlytics'
+ apply plugin: 'com.bugsnag.android.gradle'
+}
import com.android.build.OutputFile
@@ -141,7 +146,9 @@ android {
versionCode VERSIONCODE as Integer
versionName "4.11.0"
vectorDrawables.useSupportLibrary = true
- manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
+ if (isPlay) {
+ manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String]
+ }
missingDimensionStrategy "RNNotifications.reactNativeVersion", "reactNative60" // See note below!
}
@@ -168,8 +175,10 @@ android {
minifyEnabled enableProguardInReleaseBuilds
setProguardFiles([getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'])
signingConfig signingConfigs.release
- firebaseCrashlytics {
- nativeSymbolUploadEnabled true
+ if (isPlay) {
+ firebaseCrashlytics {
+ nativeSymbolUploadEnabled true
+ }
}
}
}
@@ -182,6 +191,19 @@ android {
// }
// applicationVariants are e.g. debug, release
+
+ flavorDimensions "type"
+ productFlavors {
+ foss {
+ dimension = "type"
+ buildConfigField "boolean", "FDROID_BUILD", "true"
+ }
+ play {
+ dimension = "type"
+ buildConfigField "boolean", "FDROID_BUILD", "false"
+ }
+ }
+
applicationVariants.all { variant ->
variant.outputs.each { output ->
// For each separate APK per architecture, set a unique version code as described here:
@@ -217,7 +239,7 @@ dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDynamicVersion
implementation "com.facebook.react:react-native:+" // From node_modules
- implementation "com.google.firebase:firebase-messaging:18.0.0"
+ playImplementation "com.google.firebase:firebase-messaging:18.0.0"
implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
exclude group:'com.facebook.fbjni'
@@ -250,4 +272,7 @@ task copyDownloadableDepsToLibs(type: Copy) {
into 'libs'
}
-apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
\ No newline at end of file
+apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+if (isPlay) {
+ apply plugin: 'com.google.gms.google-services'
+}
diff --git a/android/app/src/foss/java/chat/rocket/reactnative/CustomPushNotification.java b/android/app/src/foss/java/chat/rocket/reactnative/CustomPushNotification.java
new file mode 100644
index 000000000..d8c0502eb
--- /dev/null
+++ b/android/app/src/foss/java/chat/rocket/reactnative/CustomPushNotification.java
@@ -0,0 +1,20 @@
+package chat.rocket.reactnative;
+
+import android.content.Context;
+import android.os.Bundle;
+
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.wix.reactnativenotifications.core.AppLaunchHelper;
+import com.wix.reactnativenotifications.core.AppLifecycleFacade;
+import com.wix.reactnativenotifications.core.JsIOHelper;
+import com.wix.reactnativenotifications.core.notification.PushNotification;
+
+public class CustomPushNotification extends PushNotification {
+ public static ReactApplicationContext reactApplicationContext;
+
+ public CustomPushNotification(Context context, Bundle bundle, AppLifecycleFacade appLifecycleFacade, AppLaunchHelper appLaunchHelper, JsIOHelper jsIoHelper) {
+ super(context, bundle, appLifecycleFacade, appLaunchHelper, jsIoHelper);
+ reactApplicationContext = new ReactApplicationContext(context);
+ }
+
+}
diff --git a/android/app/src/foss/java/chat/rocket/reactnative/DismissNotification.java b/android/app/src/foss/java/chat/rocket/reactnative/DismissNotification.java
new file mode 100644
index 000000000..48350be51
--- /dev/null
+++ b/android/app/src/foss/java/chat/rocket/reactnative/DismissNotification.java
@@ -0,0 +1,12 @@
+package chat.rocket.reactnative;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class DismissNotification extends BroadcastReceiver {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ }
+}
diff --git a/android/app/src/main/java/chat/rocket/reactnative/Ejson.java b/android/app/src/foss/java/chat/rocket/reactnative/Ejson.java
similarity index 100%
rename from android/app/src/main/java/chat/rocket/reactnative/Ejson.java
rename to android/app/src/foss/java/chat/rocket/reactnative/Ejson.java
diff --git a/android/app/src/foss/java/chat/rocket/reactnative/ReplyBroadcast.java b/android/app/src/foss/java/chat/rocket/reactnative/ReplyBroadcast.java
new file mode 100644
index 000000000..5203495b8
--- /dev/null
+++ b/android/app/src/foss/java/chat/rocket/reactnative/ReplyBroadcast.java
@@ -0,0 +1,13 @@
+package chat.rocket.reactnative;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+
+public class ReplyBroadcast extends BroadcastReceiver {
+
+ @Override
+ public void onReceive(Context context, Intent intent) {
+
+ }
+}
diff --git a/android/app/src/foss/res/drawable/ic_launcher_background.xml b/android/app/src/foss/res/drawable/ic_launcher_background.xml
new file mode 100644
index 000000000..1369c4c71
--- /dev/null
+++ b/android/app/src/foss/res/drawable/ic_launcher_background.xml
@@ -0,0 +1,9 @@
+
+
+
diff --git a/android/app/src/foss/res/drawable/ic_launcher_foreground.xml b/android/app/src/foss/res/drawable/ic_launcher_foreground.xml
new file mode 100644
index 000000000..4fb25367c
--- /dev/null
+++ b/android/app/src/foss/res/drawable/ic_launcher_foreground.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
diff --git a/android/app/src/foss/res/drawable/launch_screen.xml b/android/app/src/foss/res/drawable/launch_screen.xml
new file mode 100644
index 000000000..d4015d97e
--- /dev/null
+++ b/android/app/src/foss/res/drawable/launch_screen.xml
@@ -0,0 +1,12 @@
+
+
+
+
+
+ -
+
+
+
+
diff --git a/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher.xml
new file mode 100644
index 000000000..b3ee0dad1
--- /dev/null
+++ b/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher_round.xml
new file mode 100644
index 000000000..b3ee0dad1
--- /dev/null
+++ b/android/app/src/foss/res/mipmap-anydpi-v26/ic_launcher_round.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
diff --git a/android/app/src/foss/res/mipmap-hdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-hdpi/ic_launcher.png
new file mode 100644
index 000000000..f1878e47b
Binary files /dev/null and b/android/app/src/foss/res/mipmap-hdpi/ic_launcher.png differ
diff --git a/android/app/src/foss/res/mipmap-hdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-hdpi/ic_launcher_background.png
new file mode 100644
index 000000000..8538bed39
Binary files /dev/null and b/android/app/src/foss/res/mipmap-hdpi/ic_launcher_background.png differ
diff --git a/android/app/src/foss/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-hdpi/ic_launcher_round.png
new file mode 100644
index 000000000..bd72cd260
Binary files /dev/null and b/android/app/src/foss/res/mipmap-hdpi/ic_launcher_round.png differ
diff --git a/android/app/src/foss/res/mipmap-mdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-mdpi/ic_launcher.png
new file mode 100644
index 000000000..1e3da8a39
Binary files /dev/null and b/android/app/src/foss/res/mipmap-mdpi/ic_launcher.png differ
diff --git a/android/app/src/foss/res/mipmap-mdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-mdpi/ic_launcher_background.png
new file mode 100644
index 000000000..a92ccfafb
Binary files /dev/null and b/android/app/src/foss/res/mipmap-mdpi/ic_launcher_background.png differ
diff --git a/android/app/src/foss/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-mdpi/ic_launcher_round.png
new file mode 100644
index 000000000..dfb390737
Binary files /dev/null and b/android/app/src/foss/res/mipmap-mdpi/ic_launcher_round.png differ
diff --git a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher.png
new file mode 100644
index 000000000..ce6abf0d6
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher.png differ
diff --git a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_background.png
new file mode 100644
index 000000000..3ba37c9e9
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_background.png differ
diff --git a/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..710fac56a
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xhdpi/ic_launcher_round.png differ
diff --git a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher.png
new file mode 100644
index 000000000..1ba89143e
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher.png differ
diff --git a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_background.png
new file mode 100644
index 000000000..07f6de5a9
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_background.png differ
diff --git a/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..86822fdd2
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xxhdpi/ic_launcher_round.png differ
diff --git a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher.png
new file mode 100644
index 000000000..2830a1249
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher.png differ
diff --git a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_background.png b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_background.png
new file mode 100644
index 000000000..5ae3008fe
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_background.png differ
diff --git a/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_round.png
new file mode 100644
index 000000000..a17913dc1
Binary files /dev/null and b/android/app/src/foss/res/mipmap-xxxhdpi/ic_launcher_round.png differ
diff --git a/android/app/src/foss/res/values-night/colors.xml b/android/app/src/foss/res/values-night/colors.xml
new file mode 100644
index 000000000..3c1a14f89
--- /dev/null
+++ b/android/app/src/foss/res/values-night/colors.xml
@@ -0,0 +1,4 @@
+
+
+ - #000000
+
diff --git a/android/app/src/foss/res/values/colors.xml b/android/app/src/foss/res/values/colors.xml
new file mode 100644
index 000000000..35e0dfb6d
--- /dev/null
+++ b/android/app/src/foss/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #660B0B0B
+ - #eeeff1
+ - #CC3333
+
diff --git a/android/app/src/foss/res/values/strings.xml b/android/app/src/foss/res/values/strings.xml
new file mode 100644
index 000000000..22a0b201d
--- /dev/null
+++ b/android/app/src/foss/res/values/strings.xml
@@ -0,0 +1,4 @@
+
+ Rocket.Chat
+ Rocket.Chat
+
diff --git a/android/app/src/foss/res/values/styles.xml b/android/app/src/foss/res/values/styles.xml
new file mode 100644
index 000000000..50861d8e0
--- /dev/null
+++ b/android/app/src/foss/res/values/styles.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index ebfb8c74d..f95275dfe 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -67,9 +67,6 @@
-
diff --git a/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java b/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java
index 6bcc62be8..12d7c0184 100644
--- a/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java
+++ b/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java
@@ -49,8 +49,10 @@ public class MainApplication extends Application implements ReactApplication, IN
protected List getPackages() {
@SuppressWarnings("UnnecessaryLocalVariable")
List packages = new PackageList(this).getPackages();
+ if (!BuildConfig.FDROID_BUILD) {
+ packages.add(new RNNotificationsPackage(MainApplication.this));
+ }
packages.add(new KeyboardInputPackage(MainApplication.this));
- packages.add(new RNNotificationsPackage(MainApplication.this));
packages.add(new WatermelonDBPackage());
packages.add(new RNCViewPagerPackage());
// packages.add(new ModuleRegistryAdapter(mModuleRegistryProvider));
diff --git a/android/app/src/play/AndroidManifest.xml b/android/app/src/play/AndroidManifest.xml
new file mode 100644
index 000000000..ebfb8c74d
--- /dev/null
+++ b/android/app/src/play/AndroidManifest.xml
@@ -0,0 +1,75 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/android/app/google-services.json b/android/app/src/play/google-services.json
similarity index 100%
rename from android/app/google-services.json
rename to android/app/src/play/google-services.json
diff --git a/android/app/src/main/java/chat/rocket/reactnative/Callback.java b/android/app/src/play/java/chat/rocket/reactnative/Callback.java
similarity index 100%
rename from android/app/src/main/java/chat/rocket/reactnative/Callback.java
rename to android/app/src/play/java/chat/rocket/reactnative/Callback.java
diff --git a/android/app/src/main/java/chat/rocket/reactnative/CustomPushNotification.java b/android/app/src/play/java/chat/rocket/reactnative/CustomPushNotification.java
similarity index 99%
rename from android/app/src/main/java/chat/rocket/reactnative/CustomPushNotification.java
rename to android/app/src/play/java/chat/rocket/reactnative/CustomPushNotification.java
index 46c086eae..ebc3fb7ce 100644
--- a/android/app/src/main/java/chat/rocket/reactnative/CustomPushNotification.java
+++ b/android/app/src/play/java/chat/rocket/reactnative/CustomPushNotification.java
@@ -114,7 +114,7 @@ public class CustomPushNotification extends PushNotification {
Ejson ejson = new Gson().fromJson(bundle.getString("ejson", "{}"), Ejson.class);
notification
- .setContentTitle(title)
+ .setContentTitle(title)
.setContentText(message)
.setContentIntent(intent)
.setPriority(Notification.PRIORITY_HIGH)
@@ -336,7 +336,7 @@ public class CustomPushNotification extends PushNotification {
intent.putExtra(NOTIFICATION_ID, notificationId);
PendingIntent dismissPendingIntent = PendingIntent.getBroadcast(mContext, notificationId, intent, 0);
-
+
notification.setDeleteIntent(dismissPendingIntent);
}
diff --git a/android/app/src/main/java/chat/rocket/reactnative/DismissNotification.java b/android/app/src/play/java/chat/rocket/reactnative/DismissNotification.java
similarity index 100%
rename from android/app/src/main/java/chat/rocket/reactnative/DismissNotification.java
rename to android/app/src/play/java/chat/rocket/reactnative/DismissNotification.java
diff --git a/android/app/src/play/java/chat/rocket/reactnative/Ejson.java b/android/app/src/play/java/chat/rocket/reactnative/Ejson.java
new file mode 100644
index 000000000..499ddf6c1
--- /dev/null
+++ b/android/app/src/play/java/chat/rocket/reactnative/Ejson.java
@@ -0,0 +1,97 @@
+package chat.rocket.reactnative;
+
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.Callback;
+
+import com.ammarahmed.mmkv.SecureKeystore;
+import com.tencent.mmkv.MMKV;
+
+import java.math.BigInteger;
+
+class RNCallback implements Callback {
+ public void invoke(Object... args) {
+
+ }
+}
+
+class Utils {
+ static public String toHex(String arg) {
+ try {
+ return String.format("%x", new BigInteger(1, arg.getBytes("UTF-8")));
+ } catch (Exception e) {
+ return "";
+ }
+ }
+}
+
+public class Ejson {
+ String host;
+ String rid;
+ String type;
+ Sender sender;
+ String messageId;
+ String notificationType;
+
+ private MMKV mmkv;
+
+ private String TOKEN_KEY = "reactnativemeteor_usertoken-";
+
+ public Ejson() {
+ ReactApplicationContext reactApplicationContext = CustomPushNotification.reactApplicationContext;
+
+ // Start MMKV container
+ MMKV.initialize(reactApplicationContext);
+ SecureKeystore secureKeystore = new SecureKeystore(reactApplicationContext);
+
+ // https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/src/loader.js#L31
+ String alias = Utils.toHex("com.MMKV.default");
+
+ // Retrieve container password
+ secureKeystore.getSecureKey(alias, new RNCallback() {
+ @Override
+ public void invoke(Object... args) {
+ String error = (String) args[0];
+ if (error == null) {
+ String password = (String) args[1];
+ mmkv = MMKV.mmkvWithID("default", MMKV.SINGLE_PROCESS_MODE, password);
+ }
+ }
+ });
+ }
+
+ public String getAvatarUri() {
+ if (type == null) {
+ return null;
+ }
+ return serverURL() + "/avatar/" + this.sender.username + "?rc_token=" + token() + "&rc_uid=" + userId();
+ }
+
+ public String token() {
+ String userId = userId();
+ if (mmkv != null && userId != null) {
+ return mmkv.decodeString(TOKEN_KEY.concat(userId));
+ }
+ return "";
+ }
+
+ public String userId() {
+ String serverURL = serverURL();
+ if (mmkv != null && serverURL != null) {
+ return mmkv.decodeString(TOKEN_KEY.concat(serverURL));
+ }
+ return "";
+ }
+
+ public String serverURL() {
+ String url = this.host;
+ if (url != null && url.endsWith("/")) {
+ url = url.substring(0, url.length() - 1);
+ }
+ return url;
+ }
+
+ public class Sender {
+ String username;
+ String _id;
+ }
+}
diff --git a/android/app/src/main/java/chat/rocket/reactnative/LoadNotification.java b/android/app/src/play/java/chat/rocket/reactnative/LoadNotification.java
similarity index 100%
rename from android/app/src/main/java/chat/rocket/reactnative/LoadNotification.java
rename to android/app/src/play/java/chat/rocket/reactnative/LoadNotification.java
diff --git a/android/app/src/main/java/chat/rocket/reactnative/ReplyBroadcast.java b/android/app/src/play/java/chat/rocket/reactnative/ReplyBroadcast.java
similarity index 100%
rename from android/app/src/main/java/chat/rocket/reactnative/ReplyBroadcast.java
rename to android/app/src/play/java/chat/rocket/reactnative/ReplyBroadcast.java
diff --git a/android/build.gradle b/android/build.gradle
index 52f6ff0f0..13ea8c1ee 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -17,15 +17,18 @@ buildscript {
url 'https://maven.fabric.io/public'
}
}
- dependencies {
- classpath 'com.android.tools.build:gradle:3.5.3'
- classpath 'com.google.gms:google-services:4.2.0'
- classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0'
- classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
- classpath 'com.bugsnag:bugsnag-android-gradle-plugin:4.+'
- // NOTE: Do not place your application dependencies here; they belong
- // in the individual module build.gradle files
+ def taskRequests = getGradle().getStartParameter().getTaskRequests().toString().toLowerCase()
+ def isPlay = !taskRequests.contains("foss")
+
+ dependencies {
+ if (isPlay) {
+ classpath 'com.google.gms:google-services:4.2.0'
+ classpath 'com.google.firebase:firebase-crashlytics-gradle:2.0.0'
+ classpath 'com.bugsnag:bugsnag-android-gradle-plugin:4.+'
+ }
+ classpath 'com.android.tools.build:gradle:3.5.3'
+ classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile
index d574e24d0..023db49f7 100644
--- a/android/fastlane/Fastfile
+++ b/android/fastlane/Fastfile
@@ -16,20 +16,25 @@
default_platform(:android)
platform :android do
- desc "Build App for development"
- lane :build do
- gradle(task: "assembleDebug")
+ desc "Play build for development"
+ lane :playBuild do
+ gradle(task: "assemblePlayDebug")
end
- desc "Build App for release"
- lane :release do
- gradle(task: "bundleRelease")
+ 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"
lane :beta do
upload_to_play_store(
- track: 'internal',
+ track: 'internal',
aab: 'android/app/build/outputs/bundle/release/app-release.aab'
)
end
diff --git a/android/fastlane/README.md b/android/fastlane/README.md
index 3031222f9..32a0f12c2 100644
--- a/android/fastlane/README.md
+++ b/android/fastlane/README.md
@@ -16,19 +16,24 @@ or alternatively using `brew cask install fastlane`
# Available Actions
## Android
-### android build
+### android playBuild
```
-fastlane android build
+fastlane android playBuild
```
-Build App for development
-### android release
+Play build for development
+### android fossRelease
```
-fastlane android release
+fastlane android fossRelease
```
-Build App for release
-### android alpha
+Foss build for release
+### android playRelease
```
-fastlane android alpha
+fastlane android playRelease
+```
+Play build for release
+### android playAlpha
+```
+fastlane android playAlpha
```
Upload App to Play store
diff --git a/app/constants/environment.js b/app/constants/environment.js
new file mode 100644
index 000000000..099d27d1c
--- /dev/null
+++ b/app/constants/environment.js
@@ -0,0 +1,3 @@
+import RNConfigReader from 'react-native-config-reader';
+
+export const isFDroidBuild = RNConfigReader.FDROID_BUILD;
diff --git a/app/constants/links.js b/app/constants/links.js
index f676ded9a..71b6cc07b 100644
--- a/app/constants/links.js
+++ b/app/constants/links.js
@@ -3,6 +3,7 @@ import { getBundleId, isIOS } from '../utils/deviceInfo';
const APP_STORE_ID = '1272915472';
export const PLAY_MARKET_LINK = `https://play.google.com/store/apps/details?id=${ getBundleId }`;
+export const FDROID_MARKET_LINK = 'https://f-droid.org/en/packages/chat.rocket.android';
export const APP_STORE_LINK = `https://itunes.apple.com/app/id${ APP_STORE_ID }`;
export const LICENSE_LINK = 'https://github.com/RocketChat/Rocket.Chat.ReactNative/blob/develop/LICENSE';
export const STORE_REVIEW_LINK = isIOS ? `itms-apps://itunes.apple.com/app/id${ APP_STORE_ID }?action=write-review` : `market://details?id=${ getBundleId }`;
diff --git a/app/index.js b/app/index.js
index 60fd2c934..4455a2f14 100644
--- a/app/index.js
+++ b/app/index.js
@@ -36,6 +36,7 @@ import Toast from './containers/Toast';
import InAppNotification from './containers/InAppNotification';
import { ActionSheetProvider } from './containers/ActionSheet';
import debounce from './utils/debounce';
+import { isFDroidBuild } from './constants/environment';
RNScreens.enableScreens();
@@ -64,7 +65,9 @@ export default class Root extends React.Component {
constructor(props) {
super(props);
this.init();
- this.initCrashReport();
+ if (!isFDroidBuild) {
+ this.initCrashReport();
+ }
const { width, height, scale } = Dimensions.get('window');
this.state = {
theme: defaultTheme(),
diff --git a/app/notifications/push/index.js b/app/notifications/push/index.js
index 40ccbea16..df4ac152d 100644
--- a/app/notifications/push/index.js
+++ b/app/notifications/push/index.js
@@ -1,8 +1,8 @@
import EJSON from 'ejson';
-
import PushNotification from './push';
import store from '../../lib/createStore';
import { deepLinkingOpen } from '../../actions/deepLinking';
+import { isFDroidBuild } from '../../constants/environment';
export const onNotification = (notification) => {
if (notification) {
@@ -38,8 +38,10 @@ export const onNotification = (notification) => {
export const getDeviceToken = () => PushNotification.getDeviceToken();
export const setBadgeCount = count => PushNotification.setBadgeCount(count);
export const initializePushNotifications = () => {
- setBadgeCount();
- return PushNotification.configure({
- onNotification
- });
+ if (!isFDroidBuild) {
+ setBadgeCount();
+ return PushNotification.configure({
+ onNotification
+ });
+ }
};
diff --git a/app/utils/log/index.js b/app/utils/log/index.js
index ea00ca325..0b67bf575 100644
--- a/app/utils/log/index.js
+++ b/app/utils/log/index.js
@@ -1,10 +1,17 @@
-import { Client } from 'bugsnag-react-native';
-import analytics from '@react-native-firebase/analytics';
-import crashlytics from '@react-native-firebase/crashlytics';
+import firebaseAnalytics from '@react-native-firebase/analytics';
+import { isFDroidBuild } from '../../constants/environment';
import config from '../../../config';
import events from './events';
-const bugsnag = new Client(config.BUGSNAG_API_KEY);
+const analytics = firebaseAnalytics || '';
+let bugsnag = '';
+let crashlytics;
+
+if (!isFDroidBuild) {
+ const { Client } = require('bugsnag-react-native');
+ crashlytics = require('@react-native-firebase/crashlytics');
+ bugsnag = new Client(config.BUGSNAG_API_KEY);
+}
export { analytics };
export const loggerConfig = bugsnag.config;
@@ -21,20 +28,24 @@ export const logServerVersion = (serverVersion) => {
export const logEvent = (eventName, payload) => {
try {
- analytics().logEvent(eventName, payload);
- leaveBreadcrumb(eventName, payload);
+ if (!isFDroidBuild) {
+ analytics().logEvent(eventName, payload);
+ leaveBreadcrumb(eventName, payload);
+ }
} catch {
// Do nothing
}
};
export const setCurrentScreen = (currentScreen) => {
- analytics().setCurrentScreen(currentScreen);
- leaveBreadcrumb(currentScreen, { type: 'navigation' });
+ if (!isFDroidBuild) {
+ analytics().setCurrentScreen(currentScreen);
+ leaveBreadcrumb(currentScreen, { type: 'navigation' });
+ }
};
export default (e) => {
- if (e instanceof Error && e.message !== 'Aborted' && !__DEV__) {
+ if (e instanceof Error && bugsnag && e.message !== 'Aborted' && !__DEV__) {
bugsnag.notify(e, (report) => {
report.metadata = {
details: {
@@ -42,7 +53,9 @@ export default (e) => {
}
};
});
- crashlytics().recordError(e);
+ if (!isFDroidBuild) {
+ crashlytics().recordError(e);
+ }
} else {
console.log(e);
}
diff --git a/app/utils/review.js b/app/utils/review.js
index 17ba73c90..98d673631 100644
--- a/app/utils/review.js
+++ b/app/utils/review.js
@@ -5,6 +5,7 @@ import { isIOS } from './deviceInfo';
import I18n from '../i18n';
import { showErrorAlert } from './info';
import { STORE_REVIEW_LINK } from '../constants/links';
+import { isFDroidBuild } from '../constants/environment';
import { logEvent, events } from './log';
const store = isIOS ? 'App Store' : 'Play Store';
@@ -87,12 +88,14 @@ class ReviewApp {
positiveEventCount = 0;
pushPositiveEvent = () => {
- if (this.positiveEventCount >= numberOfPositiveEvent) {
- return;
- }
- this.positiveEventCount += 1;
- if (this.positiveEventCount === numberOfPositiveEvent) {
- tryReview();
+ if (!isFDroidBuild) {
+ if (this.positiveEventCount >= numberOfPositiveEvent) {
+ return;
+ }
+ this.positiveEventCount += 1;
+ if (this.positiveEventCount === numberOfPositiveEvent) {
+ tryReview();
+ }
}
}
}
diff --git a/app/views/SettingsView/index.js b/app/views/SettingsView/index.js
index 83e265461..5f14d09c7 100644
--- a/app/views/SettingsView/index.js
+++ b/app/views/SettingsView/index.js
@@ -29,7 +29,9 @@ import styles from './styles';
import {
loggerConfig, analytics, logEvent, events
} from '../../utils/log';
-import { PLAY_MARKET_LINK, APP_STORE_LINK, LICENSE_LINK } from '../../constants/links';
+import {
+ PLAY_MARKET_LINK, FDROID_MARKET_LINK, APP_STORE_LINK, LICENSE_LINK
+} from '../../constants/links';
import { withTheme } from '../../theme';
import SidebarView from '../SidebarView';
import { LISTENER } from '../../containers/Toast';
@@ -37,6 +39,8 @@ import EventEmitter from '../../utils/events';
import { appStart as appStartAction, ROOT_LOADING } from '../../actions/app';
import { onReviewPress } from '../../utils/review';
import SafeAreaView from '../../containers/SafeAreaView';
+import { isFDroidBuild } from '../../constants/environment';
+
const SectionSeparator = React.memo(({ theme }) => (
false);
+ if (!isFDroidBuild) {
+ loggerConfig.autoNotify = value;
+ analytics().setAnalyticsCollectionEnabled(value);
+ if (value) {
+ loggerConfig.clearBeforeSendCallbacks();
+ } else {
+ loggerConfig.registerBeforeSendCallback(() => false);
+ }
}
}
@@ -142,8 +148,16 @@ class SettingsView extends React.Component {
}
shareApp = () => {
- logEvent(events.SE_SHARE_THIS_APP);
- Share.share({ message: isAndroid ? PLAY_MARKET_LINK : APP_STORE_LINK });
+ let message;
+ if (isAndroid) {
+ message = PLAY_MARKET_LINK;
+ if (isFDroidBuild) {
+ message = FDROID_MARKET_LINK;
+ }
+ } else {
+ message = APP_STORE_LINK;
+ }
+ Share.share({ message });
}
copyServerVersion = () => {
@@ -230,14 +244,18 @@ class SettingsView extends React.Component {
theme={theme}
/>
-
+ {!isFDroidBuild ? (
+ <>
+
+ >
+ ) : null}
- this.renderCrashReportSwitch()}
- theme={theme}
- />
-
-
+ {this.showLivechat ? (
+ <>
+ this.renderLivechatSwitch()}
+ theme={theme}
+ />
+
+ >
+ ) : null}
+
+ {!isFDroidBuild ? (
+ <>
+ this.renderCrashReportSwitch()}
+ theme={theme}
+ />
+
+
+ >
+ ) : null}