diff --git a/.circleci/config.yml b/.circleci/config.yml
index 9cfbb84ef..9b1814410 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,13 +1,13 @@
version: 2.1
orbs:
owasp: entur/owasp@0.0.10
- node: circleci/node@4.5.1
+ node: circleci/node@5.0.3
executors:
android:
parameters:
resource_class:
- default: large
+ default: xlarge
type: string
environment:
NODE_OPTIONS: --max_old_space_size=12000
@@ -93,8 +93,7 @@ commands:
description: "Get JavaScript dependencies"
steps:
- node/install:
- node-version: '16.2.0'
- install-npm: false
+ node-version: '16.15.0'
- restore_cache:
name: Restore npm cache
key: v2-npm-{{ checksum "package.json" }}-{{ arch }}
diff --git a/.eslintrc.json b/.eslintrc.json
index 4c90e5998..2e8835ccf 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -1,13 +1,13 @@
{
"extends": [
- "plugin:mattermost/react",
+ "./eslint/eslint-mattermost",
+ "./eslint/eslint-react",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
- "mattermost",
"import"
],
"settings": {
diff --git a/.flowconfig b/.flowconfig
index 53ab6fb5c..baad119d2 100644
--- a/.flowconfig
+++ b/.flowconfig
@@ -11,6 +11,8 @@ node_modules/react-native/Libraries/polyfills/.*
; Flow doesn't support platforms
.*/Libraries/Utilities/LoadingView.js
+.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
+
[untyped]
.*/node_modules/@react-native-community/cli/.*/.*
@@ -63,4 +65,4 @@ untyped-import
untyped-type-import
[version]
-^0.162.0
+^0.176.3
diff --git a/.gitignore b/.gitignore
index 0f8fa3058..5392a043e 100644
--- a/.gitignore
+++ b/.gitignore
@@ -32,8 +32,10 @@ DerivedData
*.apk
*.aab
*.xcuserstate
+ios/.xcode.env.local
project.xcworkspace
ios/Pods
+/vendor/bundle/
.podinstall
# Android/IntelliJ
@@ -79,11 +81,11 @@ tags
# For more information about the recommended setup visit:
# https://docs.fastlane.tools/best-practices/source-control/
-*/fastlane/report.xml
-*/fastlane/Preview.html
-*/fastlane/screenshots
+**/fastlane/report.xml
+**/fastlane/Preview.html
+**/fastlane/screenshots
+**/fastlane/test_output
fastlane/.env
-fastlane/report.xml
# Sentry
android/sentry.properties
diff --git a/android/app/build.gradle b/android/app/build.gradle
index ec5900125..bb1e5e15f 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -120,9 +120,12 @@ def jscFlavor = 'org.webkit:android-jsc-intl:+'
def enableHermes = project.ext.react.get("enableHermes", false);
/**
- * Architectures to build native code for in debug.
+ * Architectures to build native code for.
*/
-def nativeArchitectures = project.getProperties().get("reactNativeDebugArchitectures")
+def reactNativeArchitectures() {
+ def value = project.getProperties().get("reactNativeArchitectures")
+ return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"]
+}
android {
compileSdkVersion rootProject.ext.compileSdkVersion
@@ -136,6 +139,78 @@ android {
multiDexEnabled = true
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
+ buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
+
+ if (isNewArchitectureEnabled()) {
+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
+ externalNativeBuild {
+ ndkBuild {
+ arguments "APP_PLATFORM=android-21",
+ "APP_STL=c++_shared",
+ "NDK_TOOLCHAIN_VERSION=clang",
+ "GENERATED_SRC_DIR=$buildDir/generated/source",
+ "PROJECT_BUILD_DIR=$buildDir",
+ "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
+ "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
+ "NODE_MODULES_DIR=$rootDir/../node_modules"
+ cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1"
+ cppFlags "-std=c++17"
+ // Make sure this target name is the same you specify inside the
+ // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable.
+ targets "rndiffapp_appmodules"
+ // Fix for windows limit on number of character in file paths and in command lines
+ if (Os.isFamily(Os.FAMILY_WINDOWS)) {
+ arguments "NDK_APP_SHORT_COMMANDS=true"
+ }
+ }
+ }
+ if (!enableSeparateBuildPerCPUArchitecture) {
+ ndk {
+ abiFilters (*reactNativeArchitectures())
+ }
+ }
+ }
+ }
+
+ if (isNewArchitectureEnabled()) {
+ // We configure the NDK build only if you decide to opt-in for the New Architecture.
+ externalNativeBuild {
+ ndkBuild {
+ path "$projectDir/src/main/jni/Android.mk"
+ }
+ }
+ def reactAndroidProjectDir = project(':ReactAndroid').projectDir
+ def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) {
+ dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck")
+ from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
+ into("$buildDir/react-ndk/exported")
+ }
+ def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) {
+ dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck")
+ from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib")
+ into("$buildDir/react-ndk/exported")
+ }
+ afterEvaluate {
+ // If you wish to add a custom TurboModule or component locally,
+ // you should uncomment this line.
+ // preBuild.dependsOn("generateCodegenArtifactsFromSchema")
+ preDebugBuild.dependsOn(packageReactNdkDebugLibs)
+ preReleaseBuild.dependsOn(packageReactNdkReleaseLibs)
+
+ // Due to a bug inside AGP, we have to explicitly set a dependency
+ // between configureNdkBuild* tasks and the preBuild tasks.
+ // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
+ configureNdkBuildRelease.dependsOn(preReleaseBuild)
+ configureNdkBuildDebug.dependsOn(preDebugBuild)
+ reactNativeArchitectures().each { architecture ->
+ tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure {
+ dependsOn("preDebugBuild")
+ }
+ tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure {
+ dependsOn("preReleaseBuild")
+ }
+ }
+ }
}
signingConfigs {
release {
@@ -152,22 +227,25 @@ android {
reset()
enable enableSeparateBuildPerCPUArchitecture
universalApk enableSeparateBuildPerCPUArchitecture // If true, also generate a universal APK
- include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
+ include (*reactNativeArchitectures())
}
}
buildTypes {
+ def useReleaseKey = project.hasProperty('MATTERMOST_RELEASE_STORE_FILE')
release {
minifyEnabled enableProguardInReleaseBuilds
proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
- signingConfig signingConfigs.release
+ if (useReleaseKey) {
+ signingConfig signingConfigs.release
+ } else {
+ signingConfig signingConfigs.debug
+ }
}
debug {
- minifyEnabled enableProguardInReleaseBuilds
- proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
- if (nativeArchitectures) {
- ndk {
- abiFilters nativeArchitectures.split(',')
- }
+ if (useReleaseKey) {
+ signingConfig signingConfigs.release
+ } else {
+ signingConfig signingConfigs.debug
}
}
unsigned.initWith(buildTypes.release)
@@ -212,25 +290,6 @@ repositories {
}
}
-configurations.all {
- resolutionStrategy {
- eachDependency { DependencyResolveDetails details ->
- if (details.requested.name == 'play-services-base') {
- details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
- }
- if (details.requested.name == 'play-services-tasks') {
- details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
- }
- if (details.requested.name == 'play-services-stats') {
- details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
- }
- if (details.requested.name == 'play-services-basement') {
- details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
- }
- }
- }
-}
-
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
@@ -250,10 +309,10 @@ dependencies {
if (enableHermes) {
- def hermesPath = "../../node_modules/hermes-engine/android/";
- debugImplementation files(hermesPath + "hermes-debug.aar")
- releaseImplementation files(hermesPath + "hermes-release.aar")
- unsignedImplementation files(hermesPath + "hermes-release.aar")
+ //noinspection GradleDynamicVersion
+ implementation("com.facebook.react:hermes-engine:+") { // From node_modules
+ exclude group:'com.facebook.fbjni'
+ }
} else {
implementation jscFlavor
}
@@ -275,6 +334,39 @@ dependencies {
androidTestImplementation('com.wix:detox:+')
}
+configurations.all {
+ if (isNewArchitectureEnabled()) {
+ // If new architecture is enabled, we let you build RN from source
+ // Otherwise we fallback to a prebuilt .aar bundled in the NPM package.
+ // This will be applied to all the imported transtitive dependency.
+ resolutionStrategy.dependencySubstitution {
+ substitute(module("com.facebook.react:react-native"))
+ .using(project(":ReactAndroid"))
+ .because("On New Architecture we're building React Native from source")
+ substitute(module("com.facebook.react:hermes-engine"))
+ .using(project(":ReactAndroid:hermes-engine"))
+ .because("On New Architecture we're building Hermes from source")
+ }
+ }
+
+ resolutionStrategy {
+ eachDependency { DependencyResolveDetails details ->
+ if (details.requested.name == 'play-services-base') {
+ details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
+ }
+ if (details.requested.name == 'play-services-tasks') {
+ details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
+ }
+ if (details.requested.name == 'play-services-stats') {
+ details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
+ }
+ if (details.requested.name == 'play-services-basement') {
+ details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
+ }
+ }
+ }
+}
+
// Run this once to be able to run the application with BUCK
// puts all compile dependencies into folder libs for BUCK to use
task copyDownloadableDepsToLibs(type: Copy) {
@@ -284,3 +376,11 @@ task copyDownloadableDepsToLibs(type: Copy) {
apply plugin: 'com.google.gms.google-services'
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
+
+def isNewArchitectureEnabled() {
+ // To opt-in for the New Architecture, you can either:
+ // - Set `newArchEnabled` to true inside the `gradle.properties` file
+ // - Invoke gradle with `-newArchEnabled=true`
+ // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true`
+ return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true"
+}
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml
index 0063cf4f3..180b076f5 100644
--- a/android/app/src/debug/AndroidManifest.xml
+++ b/android/app/src/debug/AndroidManifest.xml
@@ -8,6 +8,6 @@
android:usesCleartextTraffic="true"
tools:targetApi="28"
tools:ignore="GoogleAppIndexingWarning">
-
+
diff --git a/android/app/src/debug/java/com/rn/ReactNativeFlipper.java b/android/app/src/debug/java/com/rn/ReactNativeFlipper.java
index f6fb760e5..1197406be 100644
--- a/android/app/src/debug/java/com/rn/ReactNativeFlipper.java
+++ b/android/app/src/debug/java/com/rn/ReactNativeFlipper.java
@@ -1,5 +1,5 @@
/**
- * Copyright (c) Facebook, Inc. and its affiliates.
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
*
*
This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
@@ -19,6 +19,7 @@ import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor;
import com.facebook.flipper.plugins.network.NetworkFlipperPlugin;
import com.facebook.flipper.plugins.react.ReactFlipperPlugin;
import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin;
+import com.facebook.react.ReactInstanceEventListener;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.modules.network.NetworkingModule;
@@ -47,7 +48,7 @@ public class ReactNativeFlipper {
ReactContext reactContext = reactInstanceManager.getCurrentReactContext();
if (reactContext == null) {
reactInstanceManager.addReactInstanceEventListener(
- new ReactInstanceManager.ReactInstanceEventListener() {
+ new ReactInstanceEventListener() {
@Override
public void onReactContextInitialized(ReactContext reactContext) {
reactInstanceManager.removeReactInstanceEventListener(this);
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 6fce38562..351221352 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -33,10 +33,12 @@
+ android:taskAffinity=""
+ android:exported="true"
+ >
@@ -72,7 +74,9 @@
android:screenOrientation="portrait"
android:theme="@style/AppTheme"
android:taskAffinity="com.mattermost.share"
- android:launchMode="singleInstance">
+ android:launchMode="singleInstance"
+ android:exported="true"
+ >
diff --git a/android/app/src/main/java/com/mattermost/newarchitecture/MainApplicationReactNativeHost.java b/android/app/src/main/java/com/mattermost/newarchitecture/MainApplicationReactNativeHost.java
new file mode 100644
index 000000000..5a5d736bf
--- /dev/null
+++ b/android/app/src/main/java/com/mattermost/newarchitecture/MainApplicationReactNativeHost.java
@@ -0,0 +1,116 @@
+package com.mattermost.newarchitecture;
+
+import android.app.Application;
+import androidx.annotation.NonNull;
+import com.facebook.react.PackageList;
+import com.facebook.react.ReactInstanceManager;
+import com.facebook.react.ReactNativeHost;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
+import com.facebook.react.bridge.JSIModulePackage;
+import com.facebook.react.bridge.JSIModuleProvider;
+import com.facebook.react.bridge.JSIModuleSpec;
+import com.facebook.react.bridge.JSIModuleType;
+import com.facebook.react.bridge.JavaScriptContextHolder;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.UIManager;
+import com.facebook.react.fabric.ComponentFactory;
+import com.facebook.react.fabric.CoreComponentsRegistry;
+import com.facebook.react.fabric.FabricJSIModuleProvider;
+import com.facebook.react.fabric.ReactNativeConfig;
+import com.facebook.react.uimanager.ViewManagerRegistry;
+import com.mattermost.rnbeta.BuildConfig;
+import com.mattermost.newarchitecture.components.MainComponentsRegistry;
+import com.mattermost.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both
+ * TurboModule delegates and the Fabric Renderer.
+ *
+ * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+public class MainApplicationReactNativeHost extends ReactNativeHost {
+ public MainApplicationReactNativeHost(Application application) {
+ super(application);
+ }
+
+ @Override
+ public boolean getUseDeveloperSupport() {
+ return BuildConfig.DEBUG;
+ }
+
+ @Override
+ protected List getPackages() {
+ List packages = new PackageList(this).getPackages();
+ // Packages that cannot be autolinked yet can be added manually here, for example:
+ // packages.add(new MyReactNativePackage());
+ // TurboModules must also be loaded here providing a valid TurboReactPackage implementation:
+ // packages.add(new TurboReactPackage() { ... });
+ // If you have custom Fabric Components, their ViewManagers should also be loaded here
+ // inside a ReactPackage.
+ return packages;
+ }
+
+ @Override
+ protected String getJSMainModuleName() {
+ return "index";
+ }
+
+ @NonNull
+ @Override
+ protected ReactPackageTurboModuleManagerDelegate.Builder
+ getReactPackageTurboModuleManagerDelegateBuilder() {
+ // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary
+ // for the new architecture and to use TurboModules correctly.
+ return new MainApplicationTurboModuleManagerDelegate.Builder();
+ }
+
+ @Override
+ protected JSIModulePackage getJSIModulePackage() {
+ return new JSIModulePackage() {
+ @Override
+ public List getJSIModules(
+ final ReactApplicationContext reactApplicationContext,
+ final JavaScriptContextHolder jsContext) {
+ final List specs = new ArrayList<>();
+
+ // Here we provide a new JSIModuleSpec that will be responsible of providing the
+ // custom Fabric Components.
+ specs.add(
+ new JSIModuleSpec() {
+ @Override
+ public JSIModuleType getJSIModuleType() {
+ return JSIModuleType.UIManager;
+ }
+
+ @Override
+ public JSIModuleProvider getJSIModuleProvider() {
+ final ComponentFactory componentFactory = new ComponentFactory();
+ CoreComponentsRegistry.register(componentFactory);
+
+ // Here we register a Components Registry.
+ // The one that is generated with the template contains no components
+ // and just provides you the one from React Native core.
+ MainComponentsRegistry.register(componentFactory);
+
+ final ReactInstanceManager reactInstanceManager = getReactInstanceManager();
+
+ ViewManagerRegistry viewManagerRegistry =
+ new ViewManagerRegistry(
+ reactInstanceManager.getOrCreateViewManagers(reactApplicationContext));
+
+ return new FabricJSIModuleProvider(
+ reactApplicationContext,
+ componentFactory,
+ ReactNativeConfig.DEFAULT_CONFIG,
+ viewManagerRegistry);
+ }
+ });
+ return specs;
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/mattermost/newarchitecture/components/MainComponentsRegistry.java b/android/app/src/main/java/com/mattermost/newarchitecture/components/MainComponentsRegistry.java
new file mode 100644
index 000000000..4168988bd
--- /dev/null
+++ b/android/app/src/main/java/com/mattermost/newarchitecture/components/MainComponentsRegistry.java
@@ -0,0 +1,36 @@
+package com.mattermost.newarchitecture.components;
+
+import com.facebook.jni.HybridData;
+import com.facebook.proguard.annotations.DoNotStrip;
+import com.facebook.react.fabric.ComponentFactory;
+import com.facebook.soloader.SoLoader;
+
+/**
+ * Class responsible to load the custom Fabric Components. This class has native methods and needs a
+ * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
+ * folder for you).
+ *
+ * Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+@DoNotStrip
+public class MainComponentsRegistry {
+ static {
+ SoLoader.loadLibrary("fabricjni");
+ }
+
+ @DoNotStrip private final HybridData mHybridData;
+
+ @DoNotStrip
+ private native HybridData initHybrid(ComponentFactory componentFactory);
+
+ @DoNotStrip
+ private MainComponentsRegistry(ComponentFactory componentFactory) {
+ mHybridData = initHybrid(componentFactory);
+ }
+
+ @DoNotStrip
+ public static MainComponentsRegistry register(ComponentFactory componentFactory) {
+ return new MainComponentsRegistry(componentFactory);
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/mattermost/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java b/android/app/src/main/java/com/mattermost/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
new file mode 100644
index 000000000..a5e317674
--- /dev/null
+++ b/android/app/src/main/java/com/mattermost/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
@@ -0,0 +1,48 @@
+package com.mattermost.newarchitecture.modules;
+
+import com.facebook.jni.HybridData;
+import com.facebook.react.ReactPackage;
+import com.facebook.react.ReactPackageTurboModuleManagerDelegate;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.soloader.SoLoader;
+import java.util.List;
+
+/**
+ * Class responsible to load the TurboModules. This class has native methods and needs a
+ * corresponding C++ implementation/header file to work correctly (already placed inside the jni/
+ * folder for you).
+ *
+ *
Please note that this class is used ONLY if you opt-in for the New Architecture (see the
+ * `newArchEnabled` property). Is ignored otherwise.
+ */
+public class MainApplicationTurboModuleManagerDelegate
+ extends ReactPackageTurboModuleManagerDelegate {
+
+ private static volatile boolean sIsSoLibraryLoaded;
+
+ protected MainApplicationTurboModuleManagerDelegate(
+ ReactApplicationContext reactApplicationContext, List packages) {
+ super(reactApplicationContext, packages);
+ }
+
+ protected native HybridData initHybrid();
+
+ native boolean canCreateTurboModule(String moduleName);
+
+ public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder {
+ protected MainApplicationTurboModuleManagerDelegate build(
+ ReactApplicationContext context, List packages) {
+ return new MainApplicationTurboModuleManagerDelegate(context, packages);
+ }
+ }
+
+ @Override
+ protected synchronized void maybeLoadOtherSoLibraries() {
+ if (!sIsSoLibraryLoaded) {
+ // If you change the name of your application .so file in the Android.mk file,
+ // make sure you update the name here as well.
+ SoLoader.loadLibrary("rndiffapp_appmodules");
+ sIsSoLibraryLoaded = true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotification.java b/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotification.java
index 73468cb50..e084b1efa 100644
--- a/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotification.java
+++ b/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotification.java
@@ -22,6 +22,7 @@ import java.util.List;
import java.util.Map;
import com.wix.reactnativenotifications.core.notification.PushNotification;
+import com.wix.reactnativenotifications.core.NotificationIntentAdapter;
import com.wix.reactnativenotifications.core.AppLaunchHelper;
import com.wix.reactnativenotifications.core.AppLifecycleFacade;
import com.wix.reactnativenotifications.core.JsIOHelper;
@@ -246,7 +247,7 @@ public class CustomPushNotification extends PushNotification {
}
private void buildNotification(Integer notificationId, boolean createSummary) {
- final PendingIntent pendingIntent = super.getCTAPendingIntent();
+ final PendingIntent pendingIntent = NotificationIntentAdapter.createPendingNotificationIntent(mContext, mNotificationProps);
final Notification notification = buildNotification(pendingIntent);
if (createSummary) {
final Notification summary = getNotificationSummaryBuilder(pendingIntent).build();
diff --git a/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotificationHelper.java b/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotificationHelper.java
index 1fbaff01f..5f89c5092 100644
--- a/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotificationHelper.java
+++ b/android/app/src/main/java/com/mattermost/rnbeta/CustomPushNotificationHelper.java
@@ -1,5 +1,6 @@
package com.mattermost.rnbeta;
+import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -128,11 +129,20 @@ public class CustomPushNotificationHelper {
replyIntent.putExtra(NOTIFICATION_ID, notificationId);
replyIntent.putExtra("pushNotification", bundle);
- PendingIntent replyPendingIntent = PendingIntent.getBroadcast(
- context,
- notificationId,
- replyIntent,
- PendingIntent.FLAG_UPDATE_CURRENT);
+ PendingIntent replyPendingIntent;
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ replyPendingIntent = PendingIntent.getBroadcast(
+ context,
+ notificationId,
+ replyIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
+ } else {
+ replyPendingIntent = PendingIntent.getBroadcast(
+ context,
+ notificationId,
+ replyIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT);
+ }
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY)
.setLabel("Reply")
@@ -381,10 +391,12 @@ public class CustomPushNotificationHelper {
private static void setNotificationDeleteIntent(Context context, NotificationCompat.Builder notification, Bundle bundle, int notificationId) {
// Let's add a delete intent when the notification is dismissed
+ final String PUSH_NOTIFICATION_EXTRA_NAME = "pushNotification";
Intent delIntent = new Intent(context, NotificationDismissService.class);
- PushNotificationProps notificationProps = new PushNotificationProps(bundle);
delIntent.putExtra(NOTIFICATION_ID, notificationId);
- PendingIntent deleteIntent = NotificationIntentAdapter.createPendingNotificationIntent(context, delIntent, notificationProps);
+ delIntent.putExtra(PUSH_NOTIFICATION_EXTRA_NAME, bundle);
+ @SuppressLint("UnspecifiedImmutableFlag")
+ PendingIntent deleteIntent = PendingIntent.getService(context, (int) System.currentTimeMillis(), delIntent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
notification.setDeleteIntent(deleteIntent);
}
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 537e76fcc..fe1b6fc4c 100644
--- a/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java
+++ b/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java
@@ -1,18 +1,44 @@
package com.mattermost.rnbeta;
import android.os.Bundle;
-
-import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
+
import android.view.KeyEvent;
import android.content.res.Configuration;
+import com.facebook.react.bridge.Arguments;
+import com.facebook.react.bridge.ReactApplicationContext;
+import com.facebook.react.bridge.ReactMethod;
+import com.facebook.react.bridge.WritableMap;
+import com.facebook.react.ReactActivityDelegate;
+import com.facebook.react.ReactRootView;
import com.reactnativenavigation.NavigationActivity;
import com.github.emilioicai.hwkeyboardevent.HWKeyboardEventModule;
public class MainActivity extends NavigationActivity {
private boolean HWKeyboardConnected = false;
+ public static class MainActivityDelegate extends ReactActivityDelegate {
+ public MainActivityDelegate(NavigationActivity activity, String mainComponentName) {
+ super(activity, mainComponentName);
+ }
+
+ @Override
+ protected ReactRootView createRootView() {
+ ReactRootView reactRootView = new ReactRootView(getContext());
+ // If you opted-in for the New Architecture, we enable the Fabric Renderer.
+ reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED);
+ return reactRootView;
+ }
+
+ @Override
+ protected boolean isConcurrentRootEnabled() {
+ // If you opted-in for the New Architecture, we enable Concurrent Root (i.e. React 18).
+ // More on this on https://reactjs.org/blog/2022/03/29/react-v18.html
+ return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
+ }
+ }
+
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -21,7 +47,7 @@ public class MainActivity extends NavigationActivity {
}
@Override
- public void onConfigurationChanged(@NonNull Configuration newConfig) {
+ public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
@@ -31,6 +57,12 @@ public class MainActivity extends NavigationActivity {
}
}
+ @Override
+ public void onWindowFocusChanged(boolean hasFocus) {
+ super.onWindowFocusChanged(hasFocus);
+ getReactGateway().onWindowFocusChanged(hasFocus);
+ }
+
/*
https://mattermost.atlassian.net/browse/MM-10601
Required by react-native-hw-keyboard-event
@@ -38,15 +70,24 @@ public class MainActivity extends NavigationActivity {
*/
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
- if (HWKeyboardConnected && event.getKeyCode() == KeyEvent.KEYCODE_ENTER && event.getAction() == KeyEvent.ACTION_UP) {
- String keyPressed = event.isShiftPressed() ? "shift-enter" : "enter";
- HWKeyboardEventModule.getInstance().keyPressed(keyPressed);
- return true;
+ if (HWKeyboardConnected) {
+ int keyCode = event.getKeyCode();
+ int keyAction = event.getAction();
+ if (keyAction == KeyEvent.ACTION_UP) {
+ if (keyCode == KeyEvent.KEYCODE_ENTER) {
+ String keyPressed = event.isShiftPressed() ? "shift-enter" : "enter";
+ HWKeyboardEventModule.getInstance().keyPressed(keyPressed);
+ return true;
+ } else if (keyCode == KeyEvent.KEYCODE_K && event.isCtrlPressed()) {
+ HWKeyboardEventModule.getInstance().keyPressed("find-channels");
+ return true;
+ }
+ }
}
return super.dispatchKeyEvent(event);
- }
+ };
private void setHWKeyboardConnected() {
HWKeyboardConnected = getResources().getConfiguration().keyboard == Configuration.KEYBOARD_QWERTY;
}
-}
+}
\ No newline at end of file
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 9316646dd..088af821d 100644
--- a/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java
+++ b/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java
@@ -25,16 +25,19 @@ import com.wix.reactnativenotifications.core.JsIOHelper;
import com.facebook.react.PackageList;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactPackage;
+import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.TurboReactPackage;
+import com.facebook.react.bridge.JSIModulePackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.module.model.ReactModuleInfo;
import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.soloader.SoLoader;
+import com.facebook.react.config.ReactFeatureFlags;
-import com.facebook.react.bridge.JSIModulePackage;
+import com.mattermost.newarchitecture.MainApplicationReactNativeHost;
public class MainApplication extends NavigationApplication implements INotificationsApplication, INotificationsDrawerApplication {
@@ -44,68 +47,75 @@ public class MainApplication extends NavigationApplication implements INotificat
private Bundle mManagedConfig = null;
-private final ReactNativeHost mReactNativeHost =
- new ReactNativeHost(this) {
- @Override
- public boolean getUseDeveloperSupport() {
- return BuildConfig.DEBUG;
- }
+ private final ReactNativeHost mReactNativeHost =
+ new ReactNativeHost(this) {
+ @Override
+ public boolean getUseDeveloperSupport() {
+ return BuildConfig.DEBUG;
+ }
- @Override
- protected List getPackages() {
- List packages = new PackageList(this).getPackages();
- // Packages that cannot be auto linked yet can be added manually here, for example:
- // packages.add(new MyReactNativePackage());
- packages.add(new RNNotificationsPackage(MainApplication.this));
- packages.add(
- new TurboReactPackage() {
- @Override
- public NativeModule getModule(String name, ReactApplicationContext reactContext) {
- switch (name) {
- case "MattermostManaged":
- return MattermostManagedModule.getInstance(reactContext);
- case "MattermostShare":
- return new ShareModule(instance, reactContext);
- case "NotificationPreferences":
- return NotificationPreferencesModule.getInstance(instance, reactContext);
- case "RNTextInputReset":
- return new RNTextInputResetModule(reactContext);
- default:
- throw new IllegalArgumentException("Could not find module " + name);
+ @Override
+ protected List getPackages() {
+ List packages = new PackageList(this).getPackages();
+ // Packages that cannot be auto linked yet can be added manually here, for example:
+ // packages.add(new MyReactNativePackage());
+ packages.add(new RNNotificationsPackage(MainApplication.this));
+ packages.add(
+ new TurboReactPackage() {
+ @Override
+ public NativeModule getModule(String name, ReactApplicationContext reactContext) {
+ switch (name) {
+ case "MattermostManaged":
+ return MattermostManagedModule.getInstance(reactContext);
+ case "MattermostShare":
+ return new ShareModule(instance, reactContext);
+ case "NotificationPreferences":
+ return NotificationPreferencesModule.getInstance(instance, reactContext);
+ case "RNTextInputReset":
+ return new RNTextInputResetModule(reactContext);
+ default:
+ throw new IllegalArgumentException("Could not find module " + name);
+ }
+ }
+
+ @Override
+ public ReactModuleInfoProvider getReactModuleInfoProvider() {
+ return () -> {
+ Map map = new HashMap<>();
+ map.put("MattermostManaged", new ReactModuleInfo("MattermostManaged", "com.mattermost.rnbeta.MattermostManagedModule", false, false, false, false, false));
+ map.put("MattermostShare", new ReactModuleInfo("MattermostShare", "com.mattermost.share.ShareModule", false, false, true, false, false));
+ map.put("NotificationPreferences", new ReactModuleInfo("NotificationPreferences", "com.mattermost.rnbeta.NotificationPreferencesModule", false, false, false, false, false));
+ map.put("RNTextInputReset", new ReactModuleInfo("RNTextInputReset", "com.mattermost.rnbeta.RNTextInputResetModule", false, false, false, false, false));
+ return map;
+ };
}
}
+ );
- @Override
- public ReactModuleInfoProvider getReactModuleInfoProvider() {
- return () -> {
- Map map = new HashMap<>();
- map.put("MattermostManaged", new ReactModuleInfo("MattermostManaged", "com.mattermost.rnbeta.MattermostManagedModule", false, false, false, false, false));
- map.put("MattermostShare", new ReactModuleInfo("MattermostShare", "com.mattermost.share.ShareModule", false, false, true, false, false));
- map.put("NotificationPreferences", new ReactModuleInfo("NotificationPreferences", "com.mattermost.rnbeta.NotificationPreferencesModule", false, false, false, false, false));
- map.put("RNTextInputReset", new ReactModuleInfo("RNTextInputReset", "com.mattermost.rnbeta.RNTextInputResetModule", false, false, false, false, false));
- return map;
- };
- }
- }
- );
+ return packages;
+ }
- return packages;
- }
+ @Override
+ protected String getJSMainModuleName() {
+ return "index";
+ }
- @Override
- protected String getJSMainModuleName() {
- return "index";
- }
-
- @Override
- protected JSIModulePackage getJSIModulePackage() {
- return (JSIModulePackage) new CustomMMKVJSIModulePackage();
- }
+ @Override
+ protected JSIModulePackage getJSIModulePackage() {
+ return (JSIModulePackage) new CustomMMKVJSIModulePackage();
+ }
};
+ private final ReactNativeHost mNewArchitectureNativeHost =
+ new MainApplicationReactNativeHost(this);
+
@Override
public ReactNativeHost getReactNativeHost() {
- return mReactNativeHost;
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ return mNewArchitectureNativeHost;
+ } else {
+ return mReactNativeHost;
+ }
}
@Override
@@ -118,6 +128,8 @@ private final ReactNativeHost mReactNativeHost =
RealPathUtil.deleteTempFiles(tempFolder);
Log.i("ReactNative", "Cleaning temp cache " + tempFolder.getAbsolutePath());
+ // If you opted-in for the New Architecture, we enable the TurboModule system
+ ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
diff --git a/android/app/src/main/java/com/mattermost/rnbeta/NotificationReplyBroadcastReceiver.java b/android/app/src/main/java/com/mattermost/rnbeta/NotificationReplyBroadcastReceiver.java
index c345222d0..754fd8476 100644
--- a/android/app/src/main/java/com/mattermost/rnbeta/NotificationReplyBroadcastReceiver.java
+++ b/android/app/src/main/java/com/mattermost/rnbeta/NotificationReplyBroadcastReceiver.java
@@ -129,9 +129,8 @@ public class NotificationReplyBroadcastReceiver extends BroadcastReceiver {
}
private void recreateNotification(int notificationId, final CharSequence message) {
- final Intent cta = new Intent(mContext, ProxyService.class);
final PushNotificationProps notificationProps = new PushNotificationProps(bundle);
- final PendingIntent pendingIntent = NotificationIntentAdapter.createPendingNotificationIntent(mContext, cta, notificationProps);
+ final PendingIntent pendingIntent = NotificationIntentAdapter.createPendingNotificationIntent(mContext, notificationProps);
NotificationCompat.Builder builder = CustomPushNotificationHelper.createNotificationBuilder(mContext, pendingIntent, bundle, false);
Notification notification = builder.build();
NotificationCompat.MessagingStyle messagingStyle = NotificationCompat.MessagingStyle.extractMessagingStyleFromNotification(notification);
diff --git a/android/app/src/main/jni/Android.mk b/android/app/src/main/jni/Android.mk
new file mode 100644
index 000000000..710541138
--- /dev/null
+++ b/android/app/src/main/jni/Android.mk
@@ -0,0 +1,48 @@
+THIS_DIR := $(call my-dir)
+
+include $(REACT_ANDROID_DIR)/Android-prebuilt.mk
+
+# If you wish to add a custom TurboModule or Fabric component in your app you
+# will have to include the following autogenerated makefile.
+# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk
+include $(CLEAR_VARS)
+
+LOCAL_PATH := $(THIS_DIR)
+
+# You can customize the name of your application .so file here.
+LOCAL_MODULE := mattermost_appmodules
+
+LOCAL_C_INCLUDES := $(LOCAL_PATH)
+LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp)
+LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
+
+# If you wish to add a custom TurboModule or Fabric component in your app you
+# will have to uncomment those lines to include the generated source
+# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni)
+#
+# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
+# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp)
+# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni
+
+# Here you should add any native library you wish to depend on.
+LOCAL_SHARED_LIBRARIES := \
+ libfabricjni \
+ libfbjni \
+ libfolly_runtime \
+ libglog \
+ libjsi \
+ libreact_codegen_rncore \
+ libreact_debug \
+ libreact_nativemodule_core \
+ libreact_render_componentregistry \
+ libreact_render_core \
+ libreact_render_debug \
+ libreact_render_graphics \
+ librrc_view \
+ libruntimeexecutor \
+ libturbomodulejsijni \
+ libyoga
+
+LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall
+
+include $(BUILD_SHARED_LIBRARY)
\ No newline at end of file
diff --git a/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/android/app/src/main/jni/MainApplicationModuleProvider.cpp
new file mode 100644
index 000000000..39de093d1
--- /dev/null
+++ b/android/app/src/main/jni/MainApplicationModuleProvider.cpp
@@ -0,0 +1,24 @@
+#include "MainApplicationModuleProvider.h"
+
+#include
+
+namespace facebook {
+namespace react {
+
+std::shared_ptr MainApplicationModuleProvider(
+ const std::string moduleName,
+ const JavaTurboModule::InitParams ¶ms) {
+ // Here you can provide your own module provider for TurboModules coming from
+ // either your application or from external libraries. The approach to follow
+ // is similar to the following (for a library called `samplelibrary`:
+ //
+ // auto module = samplelibrary_ModuleProvider(moduleName, params);
+ // if (module != nullptr) {
+ // return module;
+ // }
+ // return rncore_ModuleProvider(moduleName, params);
+ return rncore_ModuleProvider(moduleName, params);
+}
+
+} // namespace react
+} // namespace facebook
\ No newline at end of file
diff --git a/android/app/src/main/jni/MainApplicationModuleProvider.h b/android/app/src/main/jni/MainApplicationModuleProvider.h
new file mode 100644
index 000000000..2f2fb24a3
--- /dev/null
+++ b/android/app/src/main/jni/MainApplicationModuleProvider.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include
+#include
+
+#include
+
+namespace facebook {
+namespace react {
+
+std::shared_ptr MainApplicationModuleProvider(
+ const std::string moduleName,
+ const JavaTurboModule::InitParams ¶ms);
+
+} // namespace react
+} // namespace facebook
\ No newline at end of file
diff --git a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
new file mode 100644
index 000000000..f2e4714dc
--- /dev/null
+++ b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
@@ -0,0 +1,45 @@
+#include "MainApplicationTurboModuleManagerDelegate.h"
+#include "MainApplicationModuleProvider.h"
+
+namespace facebook {
+namespace react {
+
+jni::local_ref
+MainApplicationTurboModuleManagerDelegate::initHybrid(
+ jni::alias_ref) {
+ return makeCxxInstance();
+}
+
+void MainApplicationTurboModuleManagerDelegate::registerNatives() {
+ registerHybrid({
+ makeNativeMethod(
+ "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid),
+ makeNativeMethod(
+ "canCreateTurboModule",
+ MainApplicationTurboModuleManagerDelegate::canCreateTurboModule),
+ });
+}
+
+std::shared_ptr
+MainApplicationTurboModuleManagerDelegate::getTurboModule(
+ const std::string name,
+ const std::shared_ptr jsInvoker) {
+ // Not implemented yet: provide pure-C++ NativeModules here.
+ return nullptr;
+}
+
+std::shared_ptr
+MainApplicationTurboModuleManagerDelegate::getTurboModule(
+ const std::string name,
+ const JavaTurboModule::InitParams ¶ms) {
+ return MainApplicationModuleProvider(name, params);
+}
+
+bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule(
+ std::string name) {
+ return getTurboModule(name, nullptr) != nullptr ||
+ getTurboModule(name, {.moduleName = name}) != nullptr;
+}
+
+} // namespace react
+} // namespace facebook
\ No newline at end of file
diff --git a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
new file mode 100644
index 000000000..ea4a0fc98
--- /dev/null
+++ b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
@@ -0,0 +1,38 @@
+#include
+#include
+
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+class MainApplicationTurboModuleManagerDelegate
+ : public jni::HybridClass<
+ MainApplicationTurboModuleManagerDelegate,
+ TurboModuleManagerDelegate> {
+ public:
+ // Adapt it to the package you used for your Java class.
+ static constexpr auto kJavaDescriptor =
+ "Lcom/mattermost/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;";
+
+ static jni::local_ref initHybrid(jni::alias_ref);
+
+ static void registerNatives();
+
+ std::shared_ptr getTurboModule(
+ const std::string name,
+ const std::shared_ptr jsInvoker) override;
+ std::shared_ptr getTurboModule(
+ const std::string name,
+ const JavaTurboModule::InitParams ¶ms) override;
+
+ /**
+ * Test-only method. Allows user to verify whether a TurboModule can be
+ * created by instances of this class.
+ */
+ bool canCreateTurboModule(std::string name);
+};
+
+} // namespace react
+} // namespace facebook
\ No newline at end of file
diff --git a/android/app/src/main/jni/MainComponentsRegistry.cpp b/android/app/src/main/jni/MainComponentsRegistry.cpp
new file mode 100644
index 000000000..c5188f4dc
--- /dev/null
+++ b/android/app/src/main/jni/MainComponentsRegistry.cpp
@@ -0,0 +1,61 @@
+#include "MainComponentsRegistry.h"
+
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
+
+std::shared_ptr
+MainComponentsRegistry::sharedProviderRegistry() {
+ auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
+
+ // Custom Fabric Components go here. You can register custom
+ // components coming from your App or from 3rd party libraries here.
+ //
+ // providerRegistry->add(concreteComponentDescriptorProvider<
+ // AocViewerComponentDescriptor>());
+ return providerRegistry;
+}
+
+jni::local_ref
+MainComponentsRegistry::initHybrid(
+ jni::alias_ref,
+ ComponentFactory *delegate) {
+ auto instance = makeCxxInstance(delegate);
+
+ auto buildRegistryFunction =
+ [](EventDispatcher::Weak const &eventDispatcher,
+ ContextContainer::Shared const &contextContainer)
+ -> ComponentDescriptorRegistry::Shared {
+ auto registry = MainComponentsRegistry::sharedProviderRegistry()
+ ->createComponentDescriptorRegistry(
+ {eventDispatcher, contextContainer});
+
+ auto mutableRegistry =
+ std::const_pointer_cast(registry);
+
+ mutableRegistry->setFallbackComponentDescriptor(
+ std::make_shared(
+ ComponentDescriptorParameters{
+ eventDispatcher, contextContainer, nullptr}));
+
+ return registry;
+ };
+
+ delegate->buildRegistryFunction = buildRegistryFunction;
+ return instance;
+}
+
+void MainComponentsRegistry::registerNatives() {
+ registerHybrid({
+ makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid),
+ });
+}
+
+} // namespace react
+} // namespace facebook
\ No newline at end of file
diff --git a/android/app/src/main/jni/MainComponentsRegistry.h b/android/app/src/main/jni/MainComponentsRegistry.h
new file mode 100644
index 000000000..07af8980b
--- /dev/null
+++ b/android/app/src/main/jni/MainComponentsRegistry.h
@@ -0,0 +1,32 @@
+#pragma once
+
+#include
+#include
+#include
+#include
+
+namespace facebook {
+namespace react {
+
+class MainComponentsRegistry
+ : public facebook::jni::HybridClass {
+ public:
+ // Adapt it to the package you used for your Java class.
+ constexpr static auto kJavaDescriptor =
+ "Lcom/mattermost/newarchitecture/components/MainComponentsRegistry;";
+
+ static void registerNatives();
+
+ MainComponentsRegistry(ComponentFactory *delegate);
+
+ private:
+ static std::shared_ptr
+ sharedProviderRegistry();
+
+ static jni::local_ref initHybrid(
+ jni::alias_ref,
+ ComponentFactory *delegate);
+};
+
+} // namespace react
+} // namespace facebook
\ No newline at end of file
diff --git a/android/app/src/main/jni/OnLoad.cpp b/android/app/src/main/jni/OnLoad.cpp
new file mode 100644
index 000000000..ae1ef007d
--- /dev/null
+++ b/android/app/src/main/jni/OnLoad.cpp
@@ -0,0 +1,11 @@
+#include
+#include "MainApplicationTurboModuleManagerDelegate.h"
+#include "MainComponentsRegistry.h"
+
+JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) {
+ return facebook::jni::initialize(vm, [] {
+ facebook::react::MainApplicationTurboModuleManagerDelegate::
+ registerNatives();
+ facebook::react::MainComponentsRegistry::registerNatives();
+ });
+}
\ No newline at end of file
diff --git a/android/build.gradle b/android/build.gradle
index 6296de78b..f6af98fdf 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -2,16 +2,21 @@
buildscript {
ext {
- buildToolsVersion = "30.0.2"
+ buildToolsVersion = "31.0.0"
minSdkVersion = 24
- compileSdkVersion = 30
- targetSdkVersion = 30
- supportLibVersion = "28.0.0"
+ compileSdkVersion = 31
+ targetSdkVersion = 31
+ supportLibVersion = "31.0.0"
kotlinVersion = "1.5.30"
firebaseVersion = "21.0.0"
RNNKotlinVersion = kotlinVersion
- ndkVersion = "21.4.7075529"
-
+ if (System.properties['os.arch'] == "aarch64") {
+ // For M1 Users we need to use the NDK 24 which added support for aarch64
+ ndkVersion = "24.0.8215888"
+ } else {
+ // Otherwise we default to the side-by-side NDK version from AGP.
+ ndkVersion = "21.4.7075529"
+ }
}
repositories {
google()
@@ -19,7 +24,9 @@ buildscript {
mavenLocal()
}
dependencies {
- classpath 'com.android.tools.build:gradle:4.2.2'
+ classpath 'com.android.tools.build:gradle:7.1.1'
+ classpath("com.facebook.react:react-native-gradle-plugin")
+ classpath("de.undercouch:gradle-download-task:5.0.1")
classpath 'com.google.gms:google-services:4.3.10'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
diff --git a/android/gradle.properties b/android/gradle.properties
index c88cd69c4..5bb2974a3 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -9,9 +9,8 @@
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx1024m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-org.gradle.jvmargs=-Xmx2048M
+# Default value: -Xmx512m -XX:MaxMetaspaceSize=256m
+org.gradle.jvmargs=-Xmx1024m -XX:MaxMetaspaceSize=512m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
@@ -30,4 +29,15 @@ android.useAndroidX=true
android.enableJetifier=true
# Version of flipper SDK to use with React Native
-FLIPPER_VERSION=0.99.0
+FLIPPER_VERSION=0.125.0
+
+# Use this property to specify which architecture you want to build.
+# You can also override it from the CLI using
+# ./gradlew -PreactNativeArchitectures=x86_64
+reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
+# Use this property to enable support to the new architecture.
+# This will allow you to use TurboModules and the Fabric render in
+# your application. You should enable this flag either if you want
+# to write custom TurboModules/Fabric components OR use libraries that
+# are providing them.
+newArchEnabled=false
\ No newline at end of file
diff --git a/android/gradle/wrapper/gradle-wrapper.jar b/android/gradle/wrapper/gradle-wrapper.jar
index e708b1c02..7454180f2 100644
Binary files a/android/gradle/wrapper/gradle-wrapper.jar and b/android/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index 966aa8e62..f338a8808 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-all.zip
diff --git a/android/gradlew b/android/gradlew
index 645f6ca31..a58591e97 100755
--- a/android/gradlew
+++ b/android/gradlew
@@ -1,7 +1,7 @@
-#!/usr/bin/env sh
+#!/bin/sh
#
-# Copyright 2015 the original author or authors.
+# Copyright © 2015-2021 the original authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -17,78 +17,113 @@
#
##############################################################################
-##
-## Gradle start up script for UN*X
-##
+#
+# Gradle start up script for POSIX generated by Gradle.
+#
+# Important for running:
+#
+# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is
+# noncompliant, but you have some other compliant shell such as ksh or
+# bash, then to run this script, type that shell name before the whole
+# command line, like:
+#
+# ksh Gradle
+#
+# Busybox and similar reduced shells will NOT work, because this script
+# requires all of these POSIX shell features:
+# * functions;
+# * expansions «$var», «${var}», «${var:-default}», «${var+SET}»,
+# «${var#prefix}», «${var%suffix}», and «$( cmd )»;
+# * compound commands having a testable exit status, especially «case»;
+# * various built-in commands including «command», «set», and «ulimit».
+#
+# Important for patching:
+#
+# (2) This script targets any POSIX shell, so it avoids extensions provided
+# by Bash, Ksh, etc; in particular arrays are avoided.
+#
+# The "traditional" practice of packing multiple parameters into a
+# space-separated string is a well documented source of bugs and security
+# problems, so this is (mostly) avoided, by progressively accumulating
+# options in "$@", and eventually passing that to Java.
+#
+# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS,
+# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly;
+# see the in-line comments for details.
+#
+# There are tweaks for specific operating systems such as AIX, CygWin,
+# Darwin, MinGW, and NonStop.
+#
+# (3) This script is generated from the Groovy template
+# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
+# within the Gradle project.
+#
+# You can find Gradle at https://github.com/gradle/gradle/.
+#
##############################################################################
# Attempt to set APP_HOME
+
# Resolve links: $0 may be a link
-PRG="$0"
-# Need this for relative symlinks.
-while [ -h "$PRG" ] ; do
- ls=`ls -ld "$PRG"`
- link=`expr "$ls" : '.*-> \(.*\)$'`
- if expr "$link" : '/.*' > /dev/null; then
- PRG="$link"
- else
- PRG=`dirname "$PRG"`"/$link"
- fi
+app_path=$0
+
+# Need this for daisy-chained symlinks.
+while
+ APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path
+ [ -h "$app_path" ]
+do
+ ls=$( ls -ld "$app_path" )
+ link=${ls#*' -> '}
+ case $link in #(
+ /*) app_path=$link ;; #(
+ *) app_path=$APP_HOME$link ;;
+ esac
done
-SAVED="`pwd`"
-cd "`dirname \"$PRG\"`/" >/dev/null
-APP_HOME="`pwd -P`"
-cd "$SAVED" >/dev/null
+
+APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit
APP_NAME="Gradle"
-APP_BASE_NAME=`basename "$0"`
+APP_BASE_NAME=${0##*/}
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
-MAX_FD="maximum"
+MAX_FD=maximum
warn () {
echo "$*"
-}
+} >&2
die () {
echo
echo "$*"
echo
exit 1
-}
+} >&2
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
-case "`uname`" in
- CYGWIN* )
- cygwin=true
- ;;
- Darwin* )
- darwin=true
- ;;
- MINGW* )
- msys=true
- ;;
- NONSTOP* )
- nonstop=true
- ;;
+case "$( uname )" in #(
+ CYGWIN* ) cygwin=true ;; #(
+ Darwin* ) darwin=true ;; #(
+ MSYS* | MINGW* ) msys=true ;; #(
+ NONSTOP* ) nonstop=true ;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
- JAVACMD="$JAVA_HOME/jre/sh/java"
+ JAVACMD=$JAVA_HOME/jre/sh/java
else
- JAVACMD="$JAVA_HOME/bin/java"
+ JAVACMD=$JAVA_HOME/bin/java
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
@@ -97,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
- JAVACMD="java"
+ JAVACMD=java
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
@@ -105,79 +140,95 @@ location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
-if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
- MAX_FD_LIMIT=`ulimit -H -n`
- if [ $? -eq 0 ] ; then
- if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
- MAX_FD="$MAX_FD_LIMIT"
- fi
- ulimit -n $MAX_FD
- if [ $? -ne 0 ] ; then
- warn "Could not set maximum file descriptor limit: $MAX_FD"
- fi
- else
- warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
- fi
-fi
-
-# For Darwin, add options to specify how the application appears in the dock
-if $darwin; then
- GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
-fi
-
-# For Cygwin or MSYS, switch paths to Windows format before running java
-if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
- APP_HOME=`cygpath --path --mixed "$APP_HOME"`
- CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
- JAVACMD=`cygpath --unix "$JAVACMD"`
-
- # We build the pattern for arguments to be converted via cygpath
- ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
- SEP=""
- for dir in $ROOTDIRSRAW ; do
- ROOTDIRS="$ROOTDIRS$SEP$dir"
- SEP="|"
- done
- OURCYGPATTERN="(^($ROOTDIRS))"
- # Add a user-defined pattern to the cygpath arguments
- if [ "$GRADLE_CYGPATTERN" != "" ] ; then
- OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
- fi
- # Now convert the arguments - kludge to limit ourselves to /bin/sh
- i=0
- for arg in "$@" ; do
- CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
- CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
-
- if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
- eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
- else
- eval `echo args$i`="\"$arg\""
- fi
- i=`expr $i + 1`
- done
- case $i in
- 0) set -- ;;
- 1) set -- "$args0" ;;
- 2) set -- "$args0" "$args1" ;;
- 3) set -- "$args0" "$args1" "$args2" ;;
- 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
- 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
- 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
- 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
- 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
- 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then
+ case $MAX_FD in #(
+ max*)
+ MAX_FD=$( ulimit -H -n ) ||
+ warn "Could not query maximum file descriptor limit"
+ esac
+ case $MAX_FD in #(
+ '' | soft) :;; #(
+ *)
+ ulimit -n "$MAX_FD" ||
+ warn "Could not set maximum file descriptor limit to $MAX_FD"
esac
fi
-# Escape application args
-save () {
- for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
- echo " "
-}
-APP_ARGS=`save "$@"`
+# Collect all arguments for the java command, stacking in reverse order:
+# * args from the command line
+# * the main class name
+# * -classpath
+# * -D...appname settings
+# * --module-path (only if needed)
+# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables.
-# Collect all arguments for the java command, following the shell quoting and substitution rules
-eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if "$cygwin" || "$msys" ; then
+ APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
+ CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
+
+ JAVACMD=$( cygpath --unix "$JAVACMD" )
+
+ # Now convert the arguments - kludge to limit ourselves to /bin/sh
+ for arg do
+ if
+ case $arg in #(
+ -*) false ;; # don't mess with options #(
+ /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath
+ [ -e "$t" ] ;; #(
+ *) false ;;
+ esac
+ then
+ arg=$( cygpath --path --ignore --mixed "$arg" )
+ fi
+ # Roll the args list around exactly as many times as the number of
+ # args, so each arg winds up back in the position where it started, but
+ # possibly modified.
+ #
+ # NB: a `for` loop captures its iteration list before it begins, so
+ # changing the positional parameters here affects neither the number of
+ # iterations, nor the values presented in `arg`.
+ shift # remove old arg
+ set -- "$@" "$arg" # push replacement arg
+ done
+fi
+
+# Collect all arguments for the java command;
+# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of
+# shell script including quotes and variable substitutions, so put them in
+# double quotes to make sure that they get re-expanded; and
+# * put everything else in single quotes, so that it's not re-expanded.
+
+set -- \
+ "-Dorg.gradle.appname=$APP_BASE_NAME" \
+ -classpath "$CLASSPATH" \
+ org.gradle.wrapper.GradleWrapperMain \
+ "$@"
+
+# Use "xargs" to parse quoted args.
+#
+# With -n1 it outputs one arg per line, with the quotes and backslashes removed.
+#
+# In Bash we could simply go:
+#
+# readarray ARGS < <( xargs -n1 <<<"$var" ) &&
+# set -- "${ARGS[@]}" "$@"
+#
+# but POSIX shell has neither arrays nor command substitution, so instead we
+# post-process each arg (as a line of input to sed) to backslash-escape any
+# character that might be a shell metacharacter, then use eval to reverse
+# that process (while maintaining the separation between arguments), and wrap
+# the whole thing up as a single "set" statement.
+#
+# This will of course break if any of these variables contains a newline or
+# an unmatched quote.
+#
+
+eval "set -- $(
+ printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" |
+ xargs -n1 |
+ sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' |
+ tr '\n' ' '
+ )" '"$@"'
exec "$JAVACMD" "$@"
\ No newline at end of file
diff --git a/android/settings.gradle b/android/settings.gradle
index 9369160c6..dc0b28055 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -3,3 +3,10 @@ include ':reactnativenotifications'
project(':reactnativenotifications').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-notifications/lib/android/app')
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
include ':app'
+includeBuild('../node_modules/react-native-gradle-plugin')
+if (settings.hasProperty("newArchEnabled") && settings.newArchEnabled == "true") {
+ include(":ReactAndroid")
+ project(":ReactAndroid").projectDir = file('../node_modules/react-native/ReactAndroid')
+ include(":ReactAndroid:hermes-engine")
+ project(":ReactAndroid:hermes-engine").projectDir = file('../node_modules/react-native/ReactAndroid/hermes-engine')
+}
\ No newline at end of file
diff --git a/app/components/__snapshots__/badge.test.js.snap b/app/components/__snapshots__/badge.test.js.snap
index bf77c93db..efa6975da 100644
--- a/app/components/__snapshots__/badge.test.js.snap
+++ b/app/components/__snapshots__/badge.test.js.snap
@@ -3,14 +3,14 @@
exports[`Badge should match snapshot 1`] = `
`;
diff --git a/app/components/__snapshots__/swiper.test.js.snap b/app/components/__snapshots__/swiper.test.js.snap
index 9545911fb..7cdb8e044 100644
--- a/app/components/__snapshots__/swiper.test.js.snap
+++ b/app/components/__snapshots__/swiper.test.js.snap
@@ -4,8 +4,8 @@ exports[`Swiper should match snapshot 1`] = `
@John.Smith
@@ -21,18 +21,18 @@ exports[`AtMention should match snapshot, with highlight 1`] = `
onLongPress={[Function]}
onPress={[Function]}
style={
- Object {
+ {
"backgroundColor": "yellow",
}
}
>
{
iconColor: {
tintColor: theme.centerChannelColor,
},
+ iconSize: {
+ width: 10,
+ height: 16,
+ },
container: {
flexDirection: 'row',
alignItems: 'center',
@@ -100,18 +104,14 @@ const SlashSuggestionItem = (props: Props) => {
let image = (
);
if (props.icon === COMMAND_SUGGESTION_ERROR) {
image = (
);
diff --git a/app/components/autocomplete_selector/autocomplete_selector.tsx b/app/components/autocomplete_selector/autocomplete_selector.tsx
index 08283494f..5300bb787 100644
--- a/app/components/autocomplete_selector/autocomplete_selector.tsx
+++ b/app/components/autocomplete_selector/autocomplete_selector.tsx
@@ -204,6 +204,7 @@ export default class AutocompleteSelector extends PureComponent {
goToSelectorScreen = preventDoubleTap(async () => {
const closeButton = await CompassIcon.getImageSource(Platform.select({ios: 'arrow-back-ios', default: 'arrow-left'}), 24, this.props.theme.sidebarHeaderTextColor);
+ // @ts-expect-error context type definition
const {formatMessage} = this.context.intl;
const {actions, dataSource, options, placeholder, getDynamicOptions, theme} = this.props;
const screen = 'SelectorScreen';
@@ -233,6 +234,7 @@ export default class AutocompleteSelector extends PureComponent {
});
render() {
+ // @ts-expect-error context type definition
const {intl} = this.context;
const {
placeholder,
diff --git a/app/components/avatars/__snapshots__/avatars.test.tsx.snap b/app/components/avatars/__snapshots__/avatars.test.tsx.snap
index 585590876..d63045143 100644
--- a/app/components/avatars/__snapshots__/avatars.test.tsx.snap
+++ b/app/components/avatars/__snapshots__/avatars.test.tsx.snap
@@ -7,14 +7,14 @@ exports[`Avatars should match snapshot for overflow 1`] = `
>
`;
exports[`CustomList should match snapshot, renderSectionHeader 1`] = `
-
+
`;
diff --git a/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap b/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap
index f159da5c4..c018dab55 100644
--- a/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap
+++ b/app/components/emoji_picker/__snapshots__/emoji_picker.test.js.snap
@@ -1,15 +1,15 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`components/emoji_picker/emoji_picker.ios should match snapshot 1`] = `
-
-
+
`;
diff --git a/app/components/error_text/__snapshots__/error_text.test.js.snap b/app/components/error_text/__snapshots__/error_text.test.js.snap
index 4171a0af9..2dbb436db 100644
--- a/app/components/error_text/__snapshots__/error_text.test.js.snap
+++ b/app/components/error_text/__snapshots__/error_text.test.js.snap
@@ -3,18 +3,18 @@
exports[`ErrorText should match snapshot 1`] = `
item, []);
+ const keyExtractor = React.useCallback((item: string) => item, []);
- const renderPost = React.useCallback(({item}) => {
+ const renderPost = React.useCallback(({item}: ListRenderItemInfo) => {
return (
@@ -40,7 +40,7 @@ exports[`Global Thread List Header Should render threads with functional tabs &
>
diff --git a/app/components/markdown/transform.test.js b/app/components/markdown/transform.test.js
index fdedab7a9..80189a680 100644
--- a/app/components/markdown/transform.test.js
+++ b/app/components/markdown/transform.test.js
@@ -3100,50 +3100,6 @@ function nodeToString(node) {
return out;
}
-const ignoredKeys = {_sourcepos: true, _lastLineBlank: true, _open: true, _string_content: true, _info: true, _isFenced: true, _fenceChar: true, _fenceLength: true, _fenceOffset: true, _onEnter: true, _onExit: true};
-function astToJson(node, visited = [], indent = '') {
- let out = '{';
-
- const myVisited = [...visited];
- myVisited.push(node);
-
- const keys = Object.keys(node).filter((key) => !ignoredKeys[key]);
- if (keys.length > 0) {
- out += '\n';
- }
-
- for (const [i, key] of keys.entries()) {
- out += indent + ' "' + key + '":';
-
- const value = node[key];
- if (myVisited.indexOf(value) !== -1) {
- out += '[Circular]';
- } else if (value === null) {
- out += 'null';
- } else if (typeof value === 'number') {
- out += value;
- } else if (typeof value === 'string') {
- out += '"' + value + '"';
- } else if (typeof value === 'boolean') {
- out += String(value);
- } else if (typeof value === 'object') {
- out += astToJson(value, myVisited, indent + ' '); // eslint-disable-line @typescript-eslint/no-unused-vars
- }
-
- if (i !== keys.length - 1) {
- out += ',\n';
- }
- }
-
- if (keys.length > 0) {
- out += '\n' + indent;
- }
-
- out += '}';
-
- return out;
-}
-
// Converts an AST represented as a JavaScript object into a full Commonmark-compatitle AST.
// This function is intended for use while testing. An example of input would be:
// {
diff --git a/app/components/post_draft/__snapshots__/post_draft.test.js.snap b/app/components/post_draft/__snapshots__/post_draft.test.js.snap
index b2fce7be7..e8056f863 100644
--- a/app/components/post_draft/__snapshots__/post_draft.test.js.snap
+++ b/app/components/post_draft/__snapshots__/post_draft.test.js.snap
@@ -3,7 +3,7 @@
exports[`PostDraft Should render the Archived for channelIsArchived 1`] = `
-
+
`;
diff --git a/app/components/post_draft/send_action/__snapshots__/send.test.js.snap b/app/components/post_draft/send_action/__snapshots__/send.test.js.snap
index d940e01e0..069592290 100644
--- a/app/components/post_draft/send_action/__snapshots__/send.test.js.snap
+++ b/app/components/post_draft/send_action/__snapshots__/send.test.js.snap
@@ -3,7 +3,7 @@
exports[`SendAction should change theme backgroundColor to 0.3 opacity 1`] = `
{
const {unreadCount} = this.props;
+
+ // @ts-expect-error context type definition
const {formatMessage} = this.context.intl;
const isInitialMessage = unreadCount === count;
diff --git a/app/components/post_list/post/body/content/message_attachments/__snapshots__/attachment_footer.test.tsx.snap b/app/components/post_list/post/body/content/message_attachments/__snapshots__/attachment_footer.test.tsx.snap
index bee08d2fe..b30051ee7 100644
--- a/app/components/post_list/post/body/content/message_attachments/__snapshots__/attachment_footer.test.tsx.snap
+++ b/app/components/post_list/post/body/content/message_attachments/__snapshots__/attachment_footer.test.tsx.snap
@@ -3,7 +3,7 @@
exports[`AttachmentFooter it matches snapshot when both footer and footer_icon are provided 1`] = `
@username
@username
@username
@other.user
@username.
@@ -233,8 +233,8 @@ exports[`renderSystemMessage uses renderer for Guest added and join to channel 2
exports[`renderSystemMessage uses renderer for OLD archived channel without a username 1`] = `
@username
@username
{
+ const registerViewableItemsListener = useCallback((listener: any) => {
onViewableItemsChangedListener.current = listener;
const removeListener = () => {
onViewableItemsChangedListener.current = undefined;
@@ -113,7 +113,7 @@ const PostList = ({
return removeListener;
}, []);
- const registerScrollEndIndexListener = useCallback((listener) => {
+ const registerScrollEndIndexListener = useCallback((listener: any) => {
onScrollEndIndexListener.current = listener;
const removeListener = () => {
onScrollEndIndexListener.current = undefined;
@@ -122,7 +122,7 @@ const PostList = ({
return removeListener;
}, []);
- const keyExtractor = useCallback((item) => {
+ const keyExtractor = useCallback((item: string) => {
// All keys are strings (either post IDs or special keys)
return item;
}, []);
@@ -173,7 +173,7 @@ const PostList = ({
}
}, []);
- const renderItem = useCallback(({item, index}) => {
+ const renderItem = useCallback(({item, index}: ListRenderItemInfo) => {
if (isStartOfNewMessages(item)) {
// postIds includes a date item after the new message indicator so 2
// needs to be added to the index for the length check to be correct.
diff --git a/app/components/progressive_image/__snapshots__/progressive_image.test.js.snap b/app/components/progressive_image/__snapshots__/progressive_image.test.js.snap
index 1ca1fdf6b..c22f90784 100644
--- a/app/components/progressive_image/__snapshots__/progressive_image.test.js.snap
+++ b/app/components/progressive_image/__snapshots__/progressive_image.test.js.snap
@@ -3,26 +3,26 @@
exports[`ProgressiveImage should match snapshot for BackgroundImage 1`] = `
@@ -56,8 +56,8 @@ exports[`ProgressiveImage should match snapshot for Default Image 1`] = `
resizeMode="contain"
source="https://images.com/image.png"
style={
- Array [
- Object {
+ [
+ {
"bottom": 0,
"left": 0,
"position": "absolute",
@@ -75,14 +75,14 @@ exports[`ProgressiveImage should match snapshot for Default Image 1`] = `
exports[`ProgressiveImage should match snapshot for Image 1`] = `
}
containerStyle={
- Object {
+ {
"backgroundColor": "#ffffff",
"flex": 1,
"paddingBottom": 0,
@@ -73,14 +73,14 @@ exports[`SearchBar should match snapshot 1`] = `
editable={true}
enablesReturnKeyAutomatically={true}
inputContainerStyle={
- Object {
+ {
"backgroundColor": undefined,
"borderRadius": 2,
"height": 10,
}
}
inputStyle={
- Object {
+ {
"backgroundColor": "transparent",
"color": "#fff",
"fontSize": 14,
@@ -93,7 +93,7 @@ exports[`SearchBar should match snapshot 1`] = `
keyboardAppearance="keyboard-appearance"
keyboardType="keyboard-type"
leftIconContainerStyle={
- Object {
+ {
"marginLeft": 4,
"width": 30,
}
@@ -114,11 +114,11 @@ exports[`SearchBar should match snapshot 1`] = `
name="magnify"
size={24}
style={
- Array [
- Object {
+ [
+ {
"flex": 1,
},
- Object {
+ {
"color": "#bbbbbb",
"top": 8,
},
diff --git a/app/components/sidebars/main/__snapshots__/main_sidebar.test.js.snap b/app/components/sidebars/main/__snapshots__/main_sidebar.test.js.snap
index d955b64b8..40c1c0015 100644
--- a/app/components/sidebars/main/__snapshots__/main_sidebar.test.js.snap
+++ b/app/components/sidebars/main/__snapshots__/main_sidebar.test.js.snap
@@ -4,7 +4,7 @@ exports[`MainSidebar should match, full snapshot 1`] = `
diff --git a/app/components/sidebars/settings/__snapshots__/settings_sidebar.test.js.snap b/app/components/sidebars/settings/__snapshots__/settings_sidebar.test.js.snap
index f56a457a1..eac01aae4 100644
--- a/app/components/sidebars/settings/__snapshots__/settings_sidebar.test.js.snap
+++ b/app/components/sidebars/settings/__snapshots__/settings_sidebar.test.js.snap
@@ -5,7 +5,7 @@ exports[`SettingsSidebar Custom Status should close sidebar when update custom s
drawerPosition="right"
drawerWidth={710}
forwardRef={
- Object {
+ {
"current": null,
}
}
@@ -21,7 +21,7 @@ exports[`SettingsSidebar Custom Status should keep sidebar open when update cust
drawerPosition="right"
drawerWidth={710}
forwardRef={
- Object {
+ {
"current": null,
}
}
@@ -37,7 +37,7 @@ exports[`SettingsSidebar should match snapshot 1`] = `
drawerPosition="right"
drawerWidth={710}
forwardRef={
- Object {
+ {
"current": null,
}
}
@@ -53,7 +53,7 @@ exports[`SettingsSidebar should match snapshot with custom status enabled 1`] =
drawerPosition="right"
drawerWidth={710}
forwardRef={
- Object {
+ {
"current": null,
}
}
@@ -69,7 +69,7 @@ exports[`SettingsSidebar should match snapshot with custom status expiry 1`] = `
drawerPosition="right"
drawerWidth={710}
forwardRef={
- Object {
+ {
"current": null,
}
}
diff --git a/app/components/slide_up_panel/__snapshots__/slide_up_panel_indicator.test.js.snap b/app/components/slide_up_panel/__snapshots__/slide_up_panel_indicator.test.js.snap
index e2e49dd9b..253701c84 100644
--- a/app/components/slide_up_panel/__snapshots__/slide_up_panel_indicator.test.js.snap
+++ b/app/components/slide_up_panel/__snapshots__/slide_up_panel_indicator.test.js.snap
@@ -3,7 +3,7 @@
exports[`SlideUpPanelIndicator should match snapshot 1`] = `
00:15
diff --git a/app/products/calls/components/__snapshots__/floating_call_container.test.js.snap b/app/products/calls/components/__snapshots__/floating_call_container.test.js.snap
index 31e9b18d9..ca28a87f8 100644
--- a/app/products/calls/components/__snapshots__/floating_call_container.test.js.snap
+++ b/app/products/calls/components/__snapshots__/floating_call_container.test.js.snap
@@ -4,8 +4,8 @@ exports[`FloatingCallContainer should match snapshot 1`] = `
{
diff --git a/app/products/calls/components/join_call/__snapshots__/join_call.test.js.snap b/app/products/calls/components/join_call/__snapshots__/join_call.test.js.snap
index 4df265679..a79cab84c 100644
--- a/app/products/calls/components/join_call/__snapshots__/join_call.test.js.snap
+++ b/app/products/calls/components/join_call/__snapshots__/join_call.test.js.snap
@@ -3,7 +3,7 @@
exports[`JoinCall should match snapshot 1`] = `
}
userIds={
- Array [
+ [
"user-1-id",
"user-2-id",
]
diff --git a/app/products/calls/hooks.ts b/app/products/calls/hooks.ts
index d6911a7e1..4b09d545c 100644
--- a/app/products/calls/hooks.ts
+++ b/app/products/calls/hooks.ts
@@ -57,6 +57,7 @@ export const useCallsChannelSettings = () => {
useEffect(() => {
if (pluginEnabled) {
+ // @ts-expect-error ActionFunc
dispatch(loadConfig());
}
}, []);
diff --git a/app/products/calls/screens/call/__snapshots__/call_screen.test.js.snap b/app/products/calls/screens/call/__snapshots__/call_screen.test.js.snap
index 4bc3e1d4b..2456a2d2c 100644
--- a/app/products/calls/screens/call/__snapshots__/call_screen.test.js.snap
+++ b/app/products/calls/screens/call/__snapshots__/call_screen.test.js.snap
@@ -3,14 +3,14 @@
exports[`CallScreen Landscape should match snapshot 1`] = `