From cbe0c719ac82705aade331aa713899734ef9b7a2 Mon Sep 17 00:00:00 2001 From: Miguel Alatzar Date: Wed, 12 Jun 2019 12:26:03 -0700 Subject: [PATCH] [MM-15874] Add native code to support RNN v2 on Android (#2855) * Remove fix for MM-9233 * MM-15774 Add native code to support RNN v2 on iOS * Android changes for RNN v2 upgrade The activity visibility handling of NotificationsLifecycleFacade is no longer needed in RNN v2. I've moved the lifecycle callbacks we use for handling managed config into ManagedActivityLifecycleCallbacks.java and registered them in MainApplication's onCreate. Also, I've moved and updated the loading and getting of the managed config into MainApplication * Update moduleNames and modulePaths * Use TAG in restrictionsReceiver * Set launch screen onCreate * Comment out registerActivityLifecycleCallbacks for now * Remove setSoftInputMode call as it's handled in the manifest * Remove clearHostOnActivityDestroy as that fix is no longer needed * Rename to canLaunchEntry * Remove replacement of super.onBackPressed() * Remove react-navigation from packager files --- Makefile | 12 +- android/app/build.gradle | 1 + .../com/mattermost/rnbeta/MainActivity.java | 11 +- .../mattermost/rnbeta/MainApplication.java | 118 +++++--- .../ManagedActivityLifecycleCallbacks.java | 141 ++++++++++ .../rnbeta/MattermostManagedModule.java | 2 +- .../rnbeta/NotificationsLifecycleFacade.java | 251 ------------------ android/build.gradle | 6 + android/settings.gradle | 2 +- app/app.js | 4 +- app/mattermost.js | 6 +- fastlane/Fastfile | 4 +- package.json | 3 +- packager/README.md | 1 + packager/moduleNames.js | 34 ++- packager/modulePaths.js | 32 ++- 16 files changed, 294 insertions(+), 334 deletions(-) create mode 100644 android/app/src/main/java/com/mattermost/rnbeta/ManagedActivityLifecycleCallbacks.java delete mode 100644 android/app/src/main/java/com/mattermost/rnbeta/NotificationsLifecycleFacade.java diff --git a/Makefile b/Makefile index db3d6cf52..186cca33d 100644 --- a/Makefile +++ b/Makefile @@ -160,19 +160,11 @@ run-android: | check-device-android pre-run prepare-android-build ## Runs the ap @if [ $(shell ps -ef | grep -i "cli.js start" | grep -civ grep) -eq 0 ]; then \ echo Starting React Native packager server; \ npm start & echo Running Android app in development; \ - if [ ! -z ${VARIANT} ]; then \ - react-native run-android --no-packager --variant=${VARIANT}; \ - else \ - react-native run-android --no-packager; \ - fi; \ + npm run android; \ wait; \ else \ echo Running Android app in development; \ - if [ ! -z ${VARIANT} ]; then \ - react-native run-android --no-packager --variant=${VARIANT}; \ - else \ - react-native run-android --no-packager; \ - fi; \ + npm run android; \ fi build: | stop pre-build check-style i18n-extract-ci ## Builds the app for Android & iOS diff --git a/android/app/build.gradle b/android/app/build.gradle index 148f8a12a..2a7cd6794 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -122,6 +122,7 @@ android { applicationId "com.mattermost.rnbeta" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion + missingDimensionStrategy "RNN.reactNativeVersion", "reactNative57_5" versionCode 196 versionName "1.20.0" multiDexEnabled = true diff --git a/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java b/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java index b190dad0c..023da9c70 100644 --- a/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java +++ b/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java @@ -2,12 +2,14 @@ package com.mattermost.rnbeta; import android.os.Bundle; import android.support.annotation.Nullable; -import com.reactnativenavigation.controllers.SplashActivity; -public class MainActivity extends SplashActivity { +import com.reactnativenavigation.NavigationActivity; + +public class MainActivity extends NavigationActivity { @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); + setContentView(R.layout.launch_screen); /** * Reference: https://stackoverflow.com/questions/7944338/resume-last-activity-when-launcher-icon-is-clicked @@ -23,9 +25,4 @@ public class MainActivity extends SplashActivity { return; } } - - @Override - public int getSplashLayout() { - return R.layout.launch_screen; - } } diff --git a/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java b/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java index 0fabde91c..8521c9efb 100644 --- a/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java +++ b/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java @@ -5,12 +5,26 @@ import com.mattermost.share.RealPathUtil; import android.app.Activity; import android.support.annotation.NonNull; +import android.support.annotation.Nullable; import android.content.Context; +import android.content.RestrictionsManager; import android.os.Bundle; +import android.util.Log; + import java.io.File; import java.util.Arrays; import java.util.List; +import com.facebook.soloader.SoLoader; +import com.facebook.react.ReactPackage; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.bridge.ReactMarker; +import com.facebook.react.bridge.ReactMarkerConstants; +import com.facebook.react.bridge.WritableMap; +import com.facebook.react.modules.core.DeviceEventManagerModule; + import com.reactnativedocumentpicker.ReactNativeDocumentPicker; import com.oblador.keychain.KeychainPackage; import com.reactlibrary.RNReactNativeDocViewerPackage; @@ -26,10 +40,6 @@ import com.reactnativecommunity.asyncstorage.AsyncStoragePackage; import com.reactnativecommunity.netinfo.NetInfoPackage; import com.reactnativecommunity.webview.RNCWebViewPackage; import com.swmansion.gesturehandler.react.RNGestureHandlerPackage; - -import com.facebook.react.ReactPackage; -import com.facebook.soloader.SoLoader; - import com.imagepicker.ImagePickerPackage; import com.gnet.bottomsheet.RNBottomSheetPackage; import com.learnium.RNDeviceInfo.RNDeviceInfo; @@ -37,6 +47,8 @@ import com.psykar.cookiemanager.CookieManagerPackage; import com.oblador.vectoricons.VectorIconsPackage; import com.BV.LinearGradient.LinearGradientPackage; import com.reactnativenavigation.NavigationApplication; +import com.reactnativenavigation.react.NavigationReactNativeHost; +import com.reactnativenavigation.react.ReactGateway; import com.wix.reactnativenotifications.RNNotificationsPackage; import com.wix.reactnativenotifications.core.notification.INotificationsApplication; import com.wix.reactnativenotifications.core.notification.IPushNotification; @@ -46,19 +58,9 @@ import com.wix.reactnativenotifications.core.AppLaunchHelper; import com.wix.reactnativenotifications.core.AppLifecycleFacade; import com.wix.reactnativenotifications.core.JsIOHelper; -import com.facebook.react.ReactPackage; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.bridge.ReactMarker; -import com.facebook.react.bridge.ReactMarkerConstants; -import com.facebook.react.bridge.WritableMap; -import com.facebook.react.modules.core.DeviceEventManagerModule; -import android.support.annotation.Nullable; - -import android.util.Log; - public class MainApplication extends NavigationApplication implements INotificationsApplication, INotificationsDrawerApplication { - public NotificationsLifecycleFacade notificationsLifecycleFacade; + public static MainApplication instance; + public Boolean sharedExtensionIsOpened = false; public Boolean replyFromPushNotification = false; @@ -70,6 +72,19 @@ public class MainApplication extends NavigationApplication implements INotificat public long PROCESS_PACKAGES_START; public long PROCESS_PACKAGES_END; + private Bundle mManagedConfig = null; + + @Override + protected ReactGateway createReactGateway() { + ReactNativeHost host = new NavigationReactNativeHost(this, isDebug(), createAdditionalReactPackages()) { + @Override + protected String getJSMainModuleName() { + return "index"; + } + }; + return new ReactGateway(this, isDebug(), host); + } + @Override public boolean isDebug() { return BuildConfig.DEBUG; @@ -109,45 +124,33 @@ public class MainApplication extends NavigationApplication implements INotificat ); } - @Override - public String getJSMainModuleName() { - return "index"; - } - @Override public void onCreate() { super.onCreate(); instance = this; + // TODO: Right now I get a black screen when resuming the app from the + // background if these callbacks are registered. I'm commenting this out + // to move forward and will come back to this at a later date. + //registerActivityLifecycleCallbacks(new ManagedActivityLifecycleCallbacks()); + // Delete any previous temp files created by the app File tempFolder = new File(getApplicationContext().getCacheDir(), "mmShare"); RealPathUtil.deleteTempFiles(tempFolder); Log.i("ReactNative", "Cleaning temp cache " + tempFolder.getAbsolutePath()); - // Create an object of the custom facade impl - notificationsLifecycleFacade = NotificationsLifecycleFacade.getInstance(); - // Attach it to react-native-navigation - setActivityCallbacks(notificationsLifecycleFacade); - SoLoader.init(this, /* native exopackage */ false); // Uncomment to listen to react markers for build that has telemetry enabled // addReactMarkerListener(); } - @Override - public boolean clearHostOnActivityDestroy(Activity activity) { - // This solves the issue where the splash screen does not go away - // after the app is killed by the OS cause of memory or a long time in the background - return false; - } - @Override public IPushNotification getPushNotification(Context context, Bundle bundle, AppLifecycleFacade defaultFacade, AppLaunchHelper defaultAppLaunchHelper) { return new CustomPushNotification( context, bundle, - notificationsLifecycleFacade, // Instead of defaultFacade!!! + defaultFacade, defaultAppLaunchHelper, new JsIOHelper() ); @@ -158,6 +161,51 @@ public class MainApplication extends NavigationApplication implements INotificat return new CustomPushNotificationDrawer(context, defaultAppLaunchHelper); } + public ReactContext getRunningReactContext() { + final ReactGateway reactGateway = getReactGateway(); + + if (reactGateway == null) { + return null; + } + + return reactGateway + .getReactNativeHost() + .getReactInstanceManager() + .getCurrentReactContext(); + } + + public synchronized Bundle loadManagedConfig(Context ctx) { + if (ctx != null) { + RestrictionsManager myRestrictionsMgr = + (RestrictionsManager) ctx.getSystemService(Context.RESTRICTIONS_SERVICE); + + mManagedConfig = myRestrictionsMgr.getApplicationRestrictions(); + myRestrictionsMgr = null; + + if (mManagedConfig!= null && mManagedConfig.size() > 0) { + return mManagedConfig; + } + + return null; + } + + return null; + } + + public synchronized Bundle getManagedConfig() { + if (mManagedConfig!= null && mManagedConfig.size() > 0) { + return mManagedConfig; + } + + ReactContext ctx = getRunningReactContext(); + + if (ctx != null) { + return loadManagedConfig(ctx); + } + + return null; + } + private void addReactMarkerListener() { ReactMarker.addListener(new ReactMarker.MarkerListener() { @Override @@ -171,7 +219,7 @@ public class MainApplication extends NavigationApplication implements INotificat PROCESS_PACKAGES_END = System.currentTimeMillis(); } else if (name.toString() == ReactMarkerConstants.CONTENT_APPEARED.toString()) { CONTENT_APPEARED = System.currentTimeMillis(); - ReactContext ctx = getReactGateway().getReactContext(); + ReactContext ctx = getRunningReactContext(); if (ctx != null) { WritableMap map = Arguments.createMap(); diff --git a/android/app/src/main/java/com/mattermost/rnbeta/ManagedActivityLifecycleCallbacks.java b/android/app/src/main/java/com/mattermost/rnbeta/ManagedActivityLifecycleCallbacks.java new file mode 100644 index 000000000..a3fdfe59f --- /dev/null +++ b/android/app/src/main/java/com/mattermost/rnbeta/ManagedActivityLifecycleCallbacks.java @@ -0,0 +1,141 @@ +package com.mattermost.rnbeta; + +import android.os.Bundle; +import android.app.Activity; +import android.app.Application.ActivityLifecycleCallbacks; +import android.content.Context; +import android.content.RestrictionsManager; +import android.content.BroadcastReceiver; +import android.content.Intent; +import android.content.IntentFilter; +import android.view.WindowManager; +import android.view.WindowManager.LayoutParams; +import android.util.ArraySet; +import android.util.Log; + +import java.util.Set; + +import com.facebook.react.bridge.Arguments; +import com.facebook.react.bridge.ReactContext; +import com.facebook.react.modules.core.DeviceEventManagerModule; + +public class ManagedActivityLifecycleCallbacks implements ActivityLifecycleCallbacks { + private static final String TAG = ManagedActivityLifecycleCallbacks.class.getSimpleName(); + + private final IntentFilter restrictionsFilter = + new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); + + private final BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() { + @Override public void onReceive(Context ctx, Intent intent) { + if (ctx != null) { + Bundle managedConfig = MainApplication.instance.loadManagedConfig(ctx); + + // Check current configuration settings, change your app's UI and + // functionality as necessary. + Log.i(TAG, "Managed Configuration Changed"); + sendConfigChanged(managedConfig); + } + } + }; + + @Override + public void onActivityCreated(Activity activity, Bundle savedInstanceState) { + MattermostManagedModule managedModule = MattermostManagedModule.getInstance(); + if (managedModule != null && managedModule.isBlurAppScreenEnabled() && activity != null) { + activity.getWindow().setFlags(LayoutParams.FLAG_SECURE, + LayoutParams.FLAG_SECURE); + } + + Bundle managedConfig = MainApplication.instance.getManagedConfig(); + if (managedConfig != null && activity != null) { + activity.registerReceiver(restrictionsReceiver, restrictionsFilter); + } + } + + @Override + public void onActivityResumed(Activity activity) { + ReactContext ctx = MainApplication.instance.getRunningReactContext(); + Bundle managedConfig = MainApplication.instance.getManagedConfig(); + + if (ctx != null) { + Bundle newConfig = MainApplication.instance.loadManagedConfig(ctx); + if (!equalBundles(newConfig, managedConfig)) { + Log.i(TAG, "onResumed Managed Configuration Changed"); + sendConfigChanged(newConfig); + } + } + } + + @Override + public void onActivityStopped(Activity activity) { + Bundle managedConfig = MainApplication.instance.getManagedConfig(); + + if (managedConfig != null) { + try { + activity.unregisterReceiver(restrictionsReceiver); + } catch (IllegalArgumentException e) { + // Just ignore this cause the receiver wasn't registered for this activity + } + } + } + + @Override + public void onActivityStarted(Activity activity) { + } + + @Override + public void onActivityPaused(Activity activity) { + } + + @Override + public void onActivitySaveInstanceState(Activity activity, Bundle outState) { + } + + @Override + public void onActivityDestroyed(Activity activity) { + } + + private void sendConfigChanged(Bundle config) { + Object result = Arguments.fromBundle(config); + ReactContext ctx = MainApplication.instance.getRunningReactContext(); + + if (ctx != null) { + ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class) + .emit("managedConfigDidChange", result); + } + } + + private boolean equalBundles(Bundle one, Bundle two) { + if (one == null || two == null) + return false; + + if(one.size() != two.size()) + return false; + + Set setOne = new ArraySet(); + setOne.addAll(one.keySet()); + setOne.addAll(two.keySet()); + Object valueOne; + Object valueTwo; + + for(String key : setOne) { + if (!one.containsKey(key) || !two.containsKey(key)) + return false; + + valueOne = one.get(key); + valueTwo = two.get(key); + if(valueOne instanceof Bundle && valueTwo instanceof Bundle && + !equalBundles((Bundle) valueOne, (Bundle) valueTwo)) { + return false; + } + else if(valueOne == null) { + if(valueTwo != null) + return false; + } + else if(!valueOne.equals(valueTwo)) + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/android/app/src/main/java/com/mattermost/rnbeta/MattermostManagedModule.java b/android/app/src/main/java/com/mattermost/rnbeta/MattermostManagedModule.java index affdb1fc5..1e73f5e9c 100644 --- a/android/app/src/main/java/com/mattermost/rnbeta/MattermostManagedModule.java +++ b/android/app/src/main/java/com/mattermost/rnbeta/MattermostManagedModule.java @@ -52,7 +52,7 @@ public class MattermostManagedModule extends ReactContextBaseJavaModule { @ReactMethod public void getConfig(final Promise promise) { try { - Bundle config = NotificationsLifecycleFacade.getInstance().getManagedConfig(); + Bundle config = MainApplication.instance.getManagedConfig(); if (config != null) { Object result = Arguments.fromBundle(config); diff --git a/android/app/src/main/java/com/mattermost/rnbeta/NotificationsLifecycleFacade.java b/android/app/src/main/java/com/mattermost/rnbeta/NotificationsLifecycleFacade.java deleted file mode 100644 index f6177a2d9..000000000 --- a/android/app/src/main/java/com/mattermost/rnbeta/NotificationsLifecycleFacade.java +++ /dev/null @@ -1,251 +0,0 @@ -package com.mattermost.rnbeta; - -import android.app.Activity; -import android.content.pm.ActivityInfo; -import android.content.BroadcastReceiver; -import android.content.Context; -import android.content.RestrictionsManager; -import android.content.Intent; -import android.content.IntentFilter; -import android.os.Bundle; -import android.util.Log; -import android.util.ArraySet; -import android.view.WindowManager; -import android.view.WindowManager.LayoutParams; -import android.content.res.Configuration; - -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.ReactContext; -import com.facebook.react.modules.core.DeviceEventManagerModule; - -import com.reactnativenavigation.NavigationApplication; -import com.reactnativenavigation.controllers.ActivityCallbacks; -import com.reactnativenavigation.react.ReactGateway; -import com.wix.reactnativenotifications.core.AppLifecycleFacade; - -import java.util.Set; -import java.util.concurrent.CopyOnWriteArraySet; - - -public class NotificationsLifecycleFacade extends ActivityCallbacks implements AppLifecycleFacade { - private static final String TAG = NotificationsLifecycleFacade.class.getSimpleName(); - private static NotificationsLifecycleFacade instance; - - private Bundle managedConfig = null; - private Activity mVisibleActivity; - private Set mListeners = new CopyOnWriteArraySet<>(); - - private final IntentFilter restrictionsFilter = - new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED); - - private final BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() { - @Override public void onReceive(Context context, Intent intent) { - if (context != null) { - // Get the current configuration bundle - RestrictionsManager myRestrictionsMgr = - (RestrictionsManager) context - .getSystemService(Context.RESTRICTIONS_SERVICE); - managedConfig = myRestrictionsMgr.getApplicationRestrictions(); - - // Check current configuration settings, change your app's UI and - // functionality as necessary. - Log.i("ReactNative", "Managed Configuration Changed"); - sendConfigChanged(managedConfig); - } - } - }; - - public static NotificationsLifecycleFacade getInstance() { - if (instance == null) { - instance = new NotificationsLifecycleFacade(); - } - - return instance; - } - - @Override - public void onActivityCreated(Activity activity, Bundle savedInstanceState) { - MattermostManagedModule managedModule = MattermostManagedModule.getInstance(); - if (managedModule != null && managedModule.isBlurAppScreenEnabled() && activity != null) { - activity.getWindow().setFlags(LayoutParams.FLAG_SECURE, - LayoutParams.FLAG_SECURE); - } - if (managedConfig != null && managedConfig.size() > 0 && activity != null) { - activity.registerReceiver(restrictionsReceiver, restrictionsFilter); - } - - if (activity != null) { - activity.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); - } - } - - @Override - public void onActivityResumed(Activity activity) { - switchToVisible(activity); - - ReactContext ctx = getRunningReactContext(); - if (managedConfig != null && managedConfig.size() > 0 && ctx != null) { - - RestrictionsManager myRestrictionsMgr = - (RestrictionsManager) ctx - .getSystemService(Context.RESTRICTIONS_SERVICE); - - Bundle newConfig = myRestrictionsMgr.getApplicationRestrictions(); - if (!equalBundles(newConfig ,managedConfig)) { - Log.i("ReactNative", "onResumed Managed Configuration Changed"); - managedConfig = newConfig; - sendConfigChanged(managedConfig); - } - } - } - - @Override - public void onActivityPaused(Activity activity) { - switchToInvisible(activity); - } - - @Override - public void onActivityStopped(Activity activity) { - switchToInvisible(activity); - if (managedConfig != null && managedConfig.size() > 0) { - try { - activity.unregisterReceiver(restrictionsReceiver); - } catch (IllegalArgumentException e) { - // Just ignore this cause the receiver wasn't registered for this activity - } - } - } - - @Override - public void onActivityDestroyed(Activity activity) { - switchToInvisible(activity); - } - - @Override - public boolean isReactInitialized() { - return NavigationApplication.instance.isReactContextInitialized(); - } - - @Override - public ReactContext getRunningReactContext() { - final ReactGateway reactGateway = NavigationApplication.instance.getReactGateway(); - if (reactGateway == null || !reactGateway.isInitialized()) { - return null; - } - - return reactGateway.getReactContext(); - } - - @Override - public boolean isAppVisible() { - return mVisibleActivity != null; - } - - @Override - public synchronized void addVisibilityListener(AppVisibilityListener listener) { - mListeners.add(listener); - } - - @Override - public synchronized void removeVisibilityListener(AppVisibilityListener listener) { - mListeners.remove(listener); - } - - @Override - public void onConfigurationChanged(Configuration newConfig) { - if (mVisibleActivity != null) { - Intent intent = new Intent("onConfigurationChanged"); - intent.putExtra("newConfig", newConfig); - mVisibleActivity.sendBroadcast(intent); - } - } - - private synchronized void switchToVisible(Activity activity) { - if (mVisibleActivity == null) { - mVisibleActivity = activity; - Log.v(TAG, "Activity is now visible ("+activity+")"); - for (AppVisibilityListener listener : mListeners) { - listener.onAppVisible(); - } - } - } - - private synchronized void switchToInvisible(Activity activity) { - if (mVisibleActivity == activity) { - mVisibleActivity = null; - Log.v(TAG, "Activity is now NOT visible ("+activity+")"); - for (AppVisibilityListener listener : mListeners) { - listener.onAppNotVisible(); - } - } - } - - public synchronized void LoadManagedConfig(ReactContext ctx) { - if (ctx != null) { - RestrictionsManager myRestrictionsMgr = - (RestrictionsManager) ctx - .getSystemService(Context.RESTRICTIONS_SERVICE); - - managedConfig = myRestrictionsMgr.getApplicationRestrictions(); - myRestrictionsMgr = null; - } - } - - public synchronized Bundle getManagedConfig() { - if (managedConfig!= null && managedConfig.size() > 0) { - return managedConfig; - } - - ReactContext ctx = getRunningReactContext(); - - if (ctx != null) { - LoadManagedConfig(ctx); - return managedConfig; - } - - return null; - } - - public void sendConfigChanged(Bundle config) { - Object result = Arguments.fromBundle(config); - ReactContext ctx = getRunningReactContext(); - if (ctx != null) { - ctx.getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class). - emit("managedConfigDidChange", result); - } - } - - private boolean equalBundles(Bundle one, Bundle two) { - if (one == null || two == null) - return false; - - if(one.size() != two.size()) - return false; - - Set setOne = new ArraySet(); - setOne.addAll(one.keySet()); - setOne.addAll(two.keySet()); - Object valueOne; - Object valueTwo; - - for(String key : setOne) { - if (!one.containsKey(key) || !two.containsKey(key)) - return false; - - valueOne = one.get(key); - valueTwo = two.get(key); - if(valueOne instanceof Bundle && valueTwo instanceof Bundle && - !equalBundles((Bundle) valueOne, (Bundle) valueTwo)) { - return false; - } - else if(valueOne == null) { - if(valueTwo != null) - return false; - } - else if(!valueOne.equals(valueTwo)) - return false; - } - - return true; - } -} diff --git a/android/build.gradle b/android/build.gradle index 3c826c44c..c4991bc58 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -11,6 +11,8 @@ buildscript { repositories { jcenter() google() + mavenLocal() + mavenCentral() } dependencies { classpath 'com.android.tools.build:gradle:3.3.1' @@ -37,6 +39,7 @@ subprojects { allprojects { repositories { google() + mavenCentral() mavenLocal() jcenter() maven { @@ -47,5 +50,8 @@ allprojects { // Local Maven repo containing AARs with JSC library built for Android url "$rootDir/../node_modules/jsc-android/dist" } + maven { + url "https://jitpack.io" + } } } diff --git a/android/settings.gradle b/android/settings.gradle index 185f7b892..a07602e25 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -22,7 +22,7 @@ project(':jail-monkey').projectDir = new File(rootProject.projectDir, '../node_m include ':react-native-local-auth' project(':react-native-local-auth').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-local-auth/android') include ':react-native-navigation' -project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/android/app/') +project(':react-native-navigation').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-navigation/lib/android/app/') include ':react-native-image-picker' project(':react-native-image-picker').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-image-picker/android') include ':react-native-bottom-sheet' diff --git a/app/app.js b/app/app.js index 36baf2a1a..ff4769114 100644 --- a/app/app.js +++ b/app/app.js @@ -35,7 +35,7 @@ export default class App { this.startAppFromPushNotification = false; this.isNotificationsConfigured = false; this.allowOtherServers = true; - this.appStarted = false; + this.canLaunchEntry = true; this.emmEnabled = false; this.performingEMMAuthentication = false; this.translations = null; @@ -276,7 +276,7 @@ export default class App { }; startApp = () => { - if (this.appStarted || this.waitForRehydration) { + if (this.waitForRehydration) { return; } diff --git a/app/mattermost.js b/app/mattermost.js index a92049115..4446484bf 100644 --- a/app/mattermost.js +++ b/app/mattermost.js @@ -481,15 +481,15 @@ const fromPushNotification = Platform.OS === 'android' && Initialization.replyFr if (startedSharedExtension || fromPushNotification) { // Hold on launching Entry screen - app.setAppStarted(true); + app.canLaunchEntry(false); // Listen for when the user opens the app new NativeEventsReceiver().appLaunched(() => { - app.setAppStarted(false); + app.canLaunchEntry(true); launchEntry(); }); } -if (!app.appStarted) { +if (app.canLaunchEntry) { launchEntry(); } diff --git a/fastlane/Fastfile b/fastlane/Fastfile index 7f8cbd8c3..b6d910302 100644 --- a/fastlane/Fastfile +++ b/fastlane/Fastfile @@ -183,7 +183,7 @@ lane :build do |options| build end -desc 'Buid the app for Android and iOS unsigned' +desc 'Build the app for Android and iOS unsigned' lane :unsigned do configure @@ -507,7 +507,7 @@ platform :android do config_mode = ENV['BUILD_FOR_RELEASE'] == 'true' ? 'Release' : 'Debug' gradle( - task: 'assemble', + task: 'app:assemble', build_type: config_mode, project_dir: 'android/' ) diff --git a/package.json b/package.json index 6f4becfd7..665301b3d 100644 --- a/package.json +++ b/package.json @@ -115,7 +115,8 @@ "test:watch": "jest --watch", "test:coverage": "jest --coverage", "updatesnapshot": "jest --updateSnapshot", - "mmjstool": "mmjstool" + "mmjstool": "mmjstool", + "android": "cd ./android && ./gradlew app:assembleDebug && ./gradlew installDebug" }, "rnpm": { "assets": [ diff --git a/packager/README.md b/packager/README.md index 3df9d58f1..dd03ad15c 100644 --- a/packager/README.md +++ b/packager/README.md @@ -27,6 +27,7 @@ - remotedev-utils - socketcluster-client - stacktrace-parser + - react-navigation 8. Change development versions of certain files to production ones: - configureStore.dev.js -> configureStore.prod.js - react/cjs/react.development.js -> react/cjs/react.production.min.js diff --git a/packager/moduleNames.js b/packager/moduleNames.js index 2b780a989..a19dc859d 100644 --- a/packager/moduleNames.js +++ b/packager/moduleNames.js @@ -524,16 +524,28 @@ module.exports = [ 'node_modules/react-native-linear-gradient/index.android.js', 'node_modules/react-native-local-auth/LocalAuth.android.js', 'node_modules/react-native-local-auth/index.js', - 'node_modules/react-native-navigation/src/NativeEventsReceiver.js', - 'node_modules/react-native-navigation/src/Navigation.js', - 'node_modules/react-native-navigation/src/PropRegistry.js', - 'node_modules/react-native-navigation/src/Screen.js', - 'node_modules/react-native-navigation/src/ScreenVisibilityListener.js', - 'node_modules/react-native-navigation/src/deprecated/indexDeprecated.android.js', - 'node_modules/react-native-navigation/src/deprecated/platformSpecificDeprecated.android.js', - 'node_modules/react-native-navigation/src/index.js', - 'node_modules/react-native-navigation/src/platformSpecific.android.js', - 'node_modules/react-native-navigation/src/views/sharedElementTransition.android.js', + 'node_modules/react-native-navigation/lib/dist/Navigation.js', + 'node_modules/react-native-navigation/lib/dist/adapters/AppRegistryService.js', + 'node_modules/react-native-navigation/lib/dist/adapters/AssetResolver.js', + 'node_modules/react-native-navigation/lib/dist/adapters/ColorService.js', + 'node_modules/react-native-navigation/lib/dist/adapters/Constants.js', + 'node_modules/react-native-navigation/lib/dist/adapters/NativeCommandsSender.js', + 'node_modules/react-native-navigation/lib/dist/adapters/NativeEventsReceiver.js', + 'node_modules/react-native-navigation/lib/dist/adapters/SharedElement.js', + 'node_modules/react-native-navigation/lib/dist/adapters/TouchablePreview.js', + 'node_modules/react-native-navigation/lib/dist/adapters/UniqueIdProvider.js', + 'node_modules/react-native-navigation/lib/dist/commands/Commands.js', + 'node_modules/react-native-navigation/lib/dist/commands/LayoutTreeCrawler.js', + 'node_modules/react-native-navigation/lib/dist/commands/LayoutTreeParser.js', + 'node_modules/react-native-navigation/lib/dist/commands/OptionsProcessor.js', + 'node_modules/react-native-navigation/lib/dist/components/ComponentRegistry.js', + 'node_modules/react-native-navigation/lib/dist/components/ComponentWrapper.js', + 'node_modules/react-native-navigation/lib/dist/components/Store.js', + 'node_modules/react-native-navigation/lib/dist/events/CommandsObserver.js', + 'node_modules/react-native-navigation/lib/dist/events/ComponentEventsObserver.js', + 'node_modules/react-native-navigation/lib/dist/events/EventsRegistry.js', + 'node_modules/react-native-navigation/lib/dist/index.js', + 'node_modules/react-native-navigation/lib/dist/interfaces/Options.js', 'node_modules/react-native-notifications/index.android.js', 'node_modules/react-native-notifications/notification.android.js', 'node_modules/react-native/Libraries/Animated/src/Animated.js', @@ -742,4 +754,4 @@ module.exports = [ 'node_modules/symbol-observable/lib/ponyfill.js', 'node_modules/tinycolor2/tinycolor.js', 'node_modules/url-parse/index.js', -]; +]; \ No newline at end of file diff --git a/packager/modulePaths.js b/packager/modulePaths.js index 0f657849a..6c18ad900 100644 --- a/packager/modulePaths.js +++ b/packager/modulePaths.js @@ -500,16 +500,28 @@ module.exports = ['./node_modules/app/app.js', './node_modules/node_modules/react-native-linear-gradient/index.android.js', './node_modules/node_modules/react-native-local-auth/LocalAuth.android.js', './node_modules/node_modules/react-native-local-auth/index.js', - './node_modules/node_modules/react-native-navigation/src/NativeEventsReceiver.js', - './node_modules/node_modules/react-native-navigation/src/Navigation.js', - './node_modules/node_modules/react-native-navigation/src/PropRegistry.js', - './node_modules/node_modules/react-native-navigation/src/Screen.js', - './node_modules/node_modules/react-native-navigation/src/ScreenVisibilityListener.js', - './node_modules/node_modules/react-native-navigation/src/deprecated/indexDeprecated.android.js', - './node_modules/node_modules/react-native-navigation/src/deprecated/platformSpecificDeprecated.android.js', - './node_modules/node_modules/react-native-navigation/src/index.js', - './node_modules/node_modules/react-native-navigation/src/platformSpecific.android.js', - './node_modules/node_modules/react-native-navigation/src/views/sharedElementTransition.android.js', + './node_modules/node_modules/react-native-navigation/lib/dist/Navigation.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/AppRegistryService.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/AssetResolver.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/ColorService.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/Constants.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/NativeCommandsSender.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/NativeEventsReceiver.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/SharedElement.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/TouchablePreview.js', + './node_modules/node_modules/react-native-navigation/lib/dist/adapters/UniqueIdProvider.js', + './node_modules/node_modules/react-native-navigation/lib/dist/commands/Commands.js', + './node_modules/node_modules/react-native-navigation/lib/dist/commands/LayoutTreeCrawler.js', + './node_modules/node_modules/react-native-navigation/lib/dist/commands/LayoutTreeParser.js', + './node_modules/node_modules/react-native-navigation/lib/dist/commands/OptionsProcessor.js', + './node_modules/node_modules/react-native-navigation/lib/dist/components/ComponentRegistry.js', + './node_modules/node_modules/react-native-navigation/lib/dist/components/ComponentWrapper.js', + './node_modules/node_modules/react-native-navigation/lib/dist/components/Store.js', + './node_modules/node_modules/react-native-navigation/lib/dist/events/CommandsObserver.js', + './node_modules/node_modules/react-native-navigation/lib/dist/events/ComponentEventsObserver.js', + './node_modules/node_modules/react-native-navigation/lib/dist/events/EventsRegistry.js', + './node_modules/node_modules/react-native-navigation/lib/dist/index.js', + './node_modules/node_modules/react-native-navigation/lib/dist/interfaces/Options.js', './node_modules/node_modules/react-native-notifications/index.android.js', './node_modules/node_modules/react-native-notifications/notification.android.js', './node_modules/node_modules/react-native/Libraries/Animated/src/Animated.js',