diff --git a/.gitignore b/.gitignore
index a597d9eb59..2fa17c24c3 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,6 +46,8 @@ local.properties
*.iml
*.hprof
.cxx/
+*.keystore
+!debug.keystore
android/app/bin
android/app/build
android/build
@@ -61,12 +63,6 @@ npm-debug.log
yarn-error.log
.yarninstall
-# BUCK
-buck-out/
-\.buckd/
-android/app/libs
-*.keystore
-
# Vim
[._]*.s[a-w][a-z]
[._]s[a-w][a-z]
@@ -114,3 +110,6 @@ launch.json
# Notice.txt generation
!build/notice-file
+
+# Temporary files created by Metro to check the health of the file watcher
+.metro-health-check*
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
index 3065d8f3d1..275b5cc36d 100644
--- a/ISSUE_TEMPLATE.md
+++ b/ISSUE_TEMPLATE.md
@@ -1,4 +1,4 @@
-Submit feature requests to http://www.mattermost.org/feature-requests/. File non-security related bugs here in the following format:
+Submit feature requests to https://portal.productboard.com/mattermost/33-what-matters-to-you. File non-security related bugs here in the following format:
#### Summary
Issue in one concise sentence.
diff --git a/android/app/BUCK b/android/app/BUCK
deleted file mode 100644
index 5aec4b5916..0000000000
--- a/android/app/BUCK
+++ /dev/null
@@ -1,65 +0,0 @@
-# To learn about Buck see [Docs](https://buckbuild.com/).
-# To run your application with Buck:
-# - install Buck
-# - `npm start` - to start the packager
-# - `cd android`
-# - `keytool -genkey -v -keystore keystores/debug.keystore -storepass android -alias androiddebugkey -keypass android -dname "CN=Android Debug,O=Android,C=US"`
-# - `./gradlew :app:copyDownloadableDepsToLibs` - make all Gradle compile dependencies available to Buck
-# - `buck install -r android/app` - compile, install and run application
-#
-
-lib_deps = []
-
-for jarfile in glob(['libs/*.jar']):
- name = 'jars__' + jarfile[jarfile.rindex('/') + 1: jarfile.rindex('.jar')]
- lib_deps.append(':' + name)
- prebuilt_jar(
- name = name,
- binary_jar = jarfile,
- )
-
-for aarfile in glob(['libs/*.aar']):
- name = 'aars__' + aarfile[aarfile.rindex('/') + 1: aarfile.rindex('.aar')]
- lib_deps.append(':' + name)
- android_prebuilt_aar(
- name = name,
- aar = aarfile,
- )
-
-android_library(
- name = "all-libs",
- exported_deps = lib_deps,
-)
-
-android_library(
- name = "app-code",
- srcs = glob([
- "src/main/java/**/*.java",
- ]),
- deps = [
- ":all-libs",
- ":build_config",
- ":res",
- ],
-)
-
-android_build_config(
- name = "build_config",
- package = "com.mattermost.rnbeta",
-)
-
-android_resource(
- name = "res",
- package = "com.mattermost.rnbeta",
- res = "src/main/res",
-)
-
-android_binary(
- name = "app",
- keystore = "//android/keystores:debug",
- manifest = "src/main/AndroidManifest.xml",
- package_type = "debug",
- deps = [
- ":app-code",
- ],
-)
diff --git a/android/app/build.gradle b/android/app/build.gradle
index e58e62f6fb..b135678b06 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -1,88 +1,56 @@
apply plugin: "com.android.application"
+apply plugin: "com.facebook.react"
apply plugin: 'kotlin-android'
import com.android.build.OutputFile
-import org.apache.tools.ant.taskdefs.condition.Os
+
/**
- * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
- * and bundleReleaseJsAndAssets).
- * These basically call `react-native bundle` with the correct arguments during the Android build
- * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
- * bundle directly from the development server. Below you can see all the possible configurations
- * and their defaults. If you decide to add a configuration block, make sure to add it before the
- * `apply from: "../../node_modules/react-native/react.gradle"` line.
- *
- * project.ext.react = [
- * // the name of the generated asset file containing your JS bundle
- * bundleAssetName: "index.android.bundle",
- *
- * // the entry file for bundle generation. If none specified and
- * // "index.android.js" exists, it will be used. Otherwise "index.js" is
- * // default. Can be overridden with ENTRY_FILE environment variable.
- * entryFile: "index.android.js",
- *
- * // whether to bundle JS and assets in debug mode
- * bundleInDebug: false,
- *
- * // whether to bundle JS and assets in release mode
- * bundleInRelease: true,
- *
- * // whether to bundle JS and assets in another build variant (if configured).
- * // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
- * // The configuration property can be in the following formats
- * // 'bundleIn${productFlavor}${buildType}'
- * // 'bundleIn${buildType}'
- * // bundleInFreeDebug: true,
- * // bundleInPaidRelease: true,
- * // bundleInBeta: true,
- *
- * // whether to disable dev mode in custom build variants (by default only disabled in release)
- * // for example: to disable dev mode in the staging build type (if configured)
- * devDisabledInStaging: true,
- * // The configuration property can be in the following formats
- * // 'devDisabledIn${productFlavor}${buildType}'
- * // 'devDisabledIn${buildType}'
- *
- * // the root of your project, i.e. where "package.json" lives
- * root: "../../",
- *
- * // where to put the JS bundle asset in debug mode
- * jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
- *
- * // where to put the JS bundle asset in release mode
- * jsBundleDirRelease: "$buildDir/intermediates/assets/release",
- *
- * // where to put drawable resources / React Native assets, e.g. the ones you use via
- * // require('./image.png')), in debug mode
- * resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
- *
- * // where to put drawable resources / React Native assets, e.g. the ones you use via
- * // require('./image.png')), in release mode
- * resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
- *
- * // by default the gradle tasks are skipped if none of the JS files or assets change; this means
- * // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
- * // date; if you have any other folders that you want to ignore for performance reasons (gradle
- * // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
- * // for example, you might want to remove it from here.
- * inputExcludes: ["android/**", "ios/**"],
- *
- * // override which node gets called and with what additional arguments
- * nodeExecutableAndArgs: ["node"],
- *
- * // supply additional arguments to the packager
- * extraPackagerArgs: []
- * ]
+ * This is the configuration block to customize your React Native Android app.
+ * By default you don't need to apply any configuration, just uncomment the lines you need.
*/
-project.ext.react = [
- entryFile: "index.ts",
- bundleConfig: "metro.config.js",
- bundleCommand: "bundle",
- enableHermes: true,
-]
+ react {
+ /* Folders */
+ // The root of your project, i.e. where "package.json" lives. Default is '..'
+ // root = file("../")
+ // The folder where the react-native NPM package is. Default is ../node_modules/react-native
+ // reactNativeDir = file("../node_modules/react-native")
+ // The folder where the react-native Codegen package is. Default is ../node_modules/react-native-codegen
+ // codegenDir = file("../node_modules/react-native-codegen")
+ // The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
+ // cliFile = file("../node_modules/react-native/cli.js")
+ /* Variants */
+ // The list of variants to that are debuggable. For those we're going to
+ // skip the bundling of the JS bundle and the assets. By default is just 'debug'.
+ // If you add flavors like lite, prod, etc. you'll have to list your debuggableVariants.
+ // debuggableVariants = ["liteDebug", "prodDebug"]
+ /* Bundling */
+ // A list containing the node command and its flags. Default is just 'node'.
+ // nodeExecutableAndArgs = ["node"]
+ //
+ // The command to run when bundling. By default is 'bundle'
+ // bundleCommand = "ram-bundle"
+ //
+ // The path to the CLI configuration file. Default is empty.
+ // bundleConfig = file(../rn-cli.config.js)
+ //
+ // The name of the generated asset file containing your JS bundle
+ // bundleAssetName = "MyApplication.android.bundle"
+ //
+ // The entry file for bundle generation. Default is 'index.android.js' or 'index.js'
+ entryFile = file("../../index.ts")
+ //
+ // A list of extra flags to pass to the 'bundle' commands.
+ // See https://github.com/react-native-community/cli/blob/main/docs/commands.md#bundle
+ // extraPackagerArgs = []
+ /* Hermes Commands */
+ // The hermes compiler command to run. By default it is 'hermesc'
+ // hermesCommand = "$rootDir/my-custom-hermesc/bin/hermesc"
+ //
+ // The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
+ // hermesFlags = ["-O", "-output-source-map"]
+}
-apply from: "../../node_modules/react-native/react.gradle"
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
if (System.getenv("SENTRY_ENABLED") == "true") {
@@ -95,33 +63,35 @@ if (System.getenv("SENTRY_ENABLED") == "true") {
}
/**
- * Set this to true to create two separate APKs instead of one:
- * - An APK that only works on ARM devices
- * - An APK that only works on x86 devices
- * The advantage is the size of the APK is reduced by about 4MB.
- * Upload all the APKs to the Play Store and people will download
- * the correct one based on the CPU architecture of their device.
+ * Set this to true to create four separate APKs instead of one,
+ * one for each native architecture. This is useful if you don't
+ * use App Bundles (https://developer.android.com/guide/app-bundle/)
+ * and want to have separate APKs to upload to the Play Store
*/
def enableSeparateBuildPerCPUArchitecture = project.hasProperty('separateApk') ? project.property('separateApk').toBoolean() : false
/**
- * Run Proguard to shrink the Java bytecode in release builds.
+ * Set this to true to Run Proguard on Release builds to minify the Java bytecode.
*/
def enableProguardInReleaseBuilds = false
+/**
+ * The preferred build flavor of JavaScriptCore (JSC)
+ *
+ * For example, to use the international variant, you can use:
+ * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
+ *
+ * The international variant includes ICU i18n library and necessary data
+ * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
+ * give correct results when using with locales other than en-US. Note that
+ * this variant is about 6MiB larger per architecture than default.
+ */
def jscFlavor = 'org.webkit:android-jsc-intl:+'
/**
- * Whether to enable the Hermes VM.
- *
- * This should be set on project.ext.react and that value will be read here. If it is not set
- * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
- * and the benefits of using Hermes will therefore be sharply reduced.
- */
-def enableHermes = project.ext.react.get("enableHermes", false);
-
-/**
- * Architectures to build native code for.
+ * Private function to get the list of Native Architectures you want to build.
+ * This reads the value from reactNativeArchitectures in your gradle.properties
+ * file and works together with the --active-arch-only flag of react-native run-android.
*/
def reactNativeArchitectures() {
def value = project.getProperties().get("reactNativeArchitectures")
@@ -131,84 +101,21 @@ def reactNativeArchitectures() {
android {
ndkVersion rootProject.ext.ndkVersion
compileSdkVersion rootProject.ext.compileSdkVersion
+ namespace "com.mattermost.rnbeta"
lintOptions {
checkReleaseBuilds false
abortOnError false
}
- packagingOptions {
- pickFirst '**/libc++_shared.so'
- }
-
defaultConfig {
applicationId "com.mattermost.rnbeta"
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
- versionCode 452
+ versionCode 453
versionName "2.0.0"
testBuildType System.getProperty('testBuildType', 'debug')
testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
- buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString()
-
- if (isNewArchitectureEnabled()) {
- // We configure the CMake build only if you decide to opt-in for the New Architecture.
- externalNativeBuild {
- cmake {
- arguments "-DPROJECT_BUILD_DIR=$buildDir",
- "-DREACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid",
- "-DREACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build",
- "-DNODE_MODULES_DIR=$rootDir/../node_modules",
- "-DANDROID_STL=c++_shared"
- }
- }
- if (!enableSeparateBuildPerCPUArchitecture) {
- ndk {
- abiFilters (*reactNativeArchitectures())
- }
- }
- }
- }
-
- if (isNewArchitectureEnabled()) {
- // We configure the NDK build only if you decide to opt-in for the New Architecture.
- externalNativeBuild {
- cmake {
- path "$projectDir/src/main/jni/CMakeLists.txt"
- }
- }
- 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 configureCMakeDebug* tasks and the preBuild tasks.
- // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732
- configureCMakeDebugRelease.dependsOn(preReleaseBuild)
- configureCMakeDebugDebug.dependsOn(preDebugBuild)
- reactNativeArchitectures().each { architecture ->
- tasks.findByName("configureCMakeDebugDebug[${architecture}]")?.configure {
- dependsOn("preDebugBuild")
- }
- tasks.findByName("configureCMakeDebugRelease[${architecture}]")?.configure {
- dependsOn("preReleaseBuild")
- }
- }
- }
}
signingConfigs {
@@ -281,70 +188,36 @@ repositories {
}
dependencies {
- implementation fileTree(dir: "libs", include: ["*.jar"])
+ // The version of react-native is set by the React Native Gradle Plugin
+ implementation("com.facebook.react:react-android")
- //noinspection GradleDynamicVersio
- implementation "com.facebook.react:react-native:+" // From node_modules
+ implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.0.0")
- implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
-
- implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
-
- debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") {
- exclude group:'com.facebook.fbjni'
- }
+ debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}")
debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") {
- exclude group:'com.facebook.flipper'
- }
- debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") {
- exclude group:'com.facebook.flipper'
+ exclude group:'com.squareup.okhttp3', module:'okhttp'
}
-
- if (enableHermes) {
- //noinspection GradleDynamicVersion
- implementation("com.facebook.react:hermes-engine:+") { // From node_modules
- exclude group:'com.facebook.fbjni'
- }
+ debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}")
+ if (hermesEnabled.toBoolean()) {
+ implementation("com.facebook.react:hermes-android")
} else {
implementation jscFlavor
}
+ implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
-
- implementation project(':reactnativenotifications')
implementation "com.google.firebase:firebase-messaging:$firebaseVersion"
- // For animated GIF support
- implementation 'com.facebook.fresco:fresco:2.6.0'
- implementation 'com.facebook.fresco:animated-gif:2.6.0'
- // For WebP support, including animated WebP
- implementation 'com.facebook.fresco:animated-webp:2.6.0'
- implementation 'com.facebook.fresco:webpsupport:2.6.0'
-
androidTestImplementation('com.wix:detox:+')
-
+ implementation project(':reactnativenotifications')
implementation project(':watermelondb-jsi')
}
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 {
- force "com.facebook.soloader:soloader:0.10.1"
eachDependency { DependencyResolveDetails details ->
if (details.requested.name == 'play-services-base') {
details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
@@ -359,13 +232,13 @@ configurations.all {
details.useTarget group: details.requested.group, name: details.requested.name, version: '15.0.1'
}
if (details.requested.name == 'okhttp') {
- details.useTarget group: details.requested.group, name: details.requested.name, version: '4.9.2'
+ details.useTarget group: details.requested.group, name: details.requested.name, version: '4.10.0'
}
if (details.requested.name == 'okhttp-tls') {
- details.useTarget group: details.requested.group, name: details.requested.name, version: '4.9.2'
+ details.useTarget group: details.requested.group, name: details.requested.name, version: '4.10.0'
}
if (details.requested.name == 'okhttp-urlconnection') {
- details.useTarget group: details.requested.group, name: details.requested.name, version: '4.9.2'
+ details.useTarget group: details.requested.group, name: details.requested.name, version: '4.10.0'
}
}
}
@@ -380,11 +253,3 @@ 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/debug.keystore b/android/app/debug.keystore
new file mode 100644
index 0000000000..364e105ed3
Binary files /dev/null and b/android/app/debug.keystore differ
diff --git a/android/app/src/debug/java/com/rn/ReactNativeFlipper.java b/android/app/src/debug/java/com/mattermost/flipper/ReactNativeFlipper.java
similarity index 93%
rename from android/app/src/debug/java/com/rn/ReactNativeFlipper.java
rename to android/app/src/debug/java/com/mattermost/flipper/ReactNativeFlipper.java
index 1197406be4..bfffa468db 100644
--- a/android/app/src/debug/java/com/rn/ReactNativeFlipper.java
+++ b/android/app/src/debug/java/com/mattermost/flipper/ReactNativeFlipper.java
@@ -4,7 +4,7 @@
*
This source code is licensed under the MIT license found in the LICENSE file in the root
* directory of this source tree.
*/
-package com.rn;
+package com.mattermost.flipper;
import android.content.Context;
import com.facebook.flipper.android.AndroidFlipperClient;
@@ -17,19 +17,22 @@ import com.facebook.flipper.plugins.inspector.DescriptorMapping;
import com.facebook.flipper.plugins.inspector.InspectorFlipperPlugin;
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;
import okhttp3.OkHttpClient;
+
+/**
+ * Class responsible of loading Flipper inside your React Native application. This is the debug
+ * flavor of it. Here you can add your own plugins and customize the Flipper setup.
+ */
public class ReactNativeFlipper {
public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
if (FlipperUtils.shouldEnableFlipper(context)) {
final FlipperClient client = AndroidFlipperClient.getInstance(context);
client.addPlugin(new InspectorFlipperPlugin(context, DescriptorMapping.withDefaults()));
- client.addPlugin(new ReactFlipperPlugin());
client.addPlugin(new DatabasesFlipperPlugin(context));
client.addPlugin(new SharedPreferencesFlipperPlugin(context));
client.addPlugin(CrashReporterPlugin.getInstance());
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 9fb7308cc5..1dd89c48e4 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -1,10 +1,10 @@
-
+
+
diff --git a/android/app/src/main/java/com/mattermost/newarchitecture/MainApplicationReactNativeHost.java b/android/app/src/main/java/com/mattermost/newarchitecture/MainApplicationReactNativeHost.java
deleted file mode 100644
index 5a5d736bf9..0000000000
--- a/android/app/src/main/java/com/mattermost/newarchitecture/MainApplicationReactNativeHost.java
+++ /dev/null
@@ -1,116 +0,0 @@
-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
deleted file mode 100644
index 4168988bd2..0000000000
--- a/android/app/src/main/java/com/mattermost/newarchitecture/components/MainComponentsRegistry.java
+++ /dev/null
@@ -1,36 +0,0 @@
-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
deleted file mode 100644
index a5e3176747..0000000000
--- a/android/app/src/main/java/com/mattermost/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java
+++ /dev/null
@@ -1,48 +0,0 @@
-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/MainActivity.java b/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java
index a8f89866f8..1a2772b09a 100644
--- a/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java
+++ b/android/app/src/main/java/com/mattermost/rnbeta/MainActivity.java
@@ -6,37 +6,36 @@ 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;
+import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint;
+import com.facebook.react.defaults.DefaultReactActivityDelegate;
+
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 String getMainComponentName() {
+ return "Mattermost";
+ }
- @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;
- }
+ /**
+ * Returns the instance of the {@link ReactActivityDelegate}. Here we use a util class {@link
+ * DefaultReactActivityDelegate} which allows you to easily enable Fabric and Concurrent React
+ * (aka React 18) with two boolean flags.
+ */
+ @Override
+ protected ReactActivityDelegate createReactActivityDelegate() {
+ return new DefaultReactActivityDelegate(
+ this,
+ getMainComponentName(),
+ // If you opted-in for the New Architecture, we enable the Fabric Renderer.
+ DefaultNewArchitectureEntryPoint.getFabricEnabled(), // fabricEnabled
+ // If you opted-in for the New Architecture, we enable Concurrent React (i.e. React 18).
+ DefaultNewArchitectureEntryPoint.getConcurrentReactEnabled() // concurrentRootEnabled
+ );
}
@Override
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 29d030d776..6892c087f6 100644
--- a/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java
+++ b/android/app/src/main/java/com/mattermost/rnbeta/MainApplication.java
@@ -1,7 +1,4 @@
package com.mattermost.rnbeta;
-
-import com.facebook.react.bridge.JSIModuleSpec;
-
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
@@ -23,11 +20,12 @@ import com.wix.reactnativenotifications.core.AppLifecycleFacade;
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.defaults.DefaultNewArchitectureEntryPoint;
+import com.facebook.react.defaults.DefaultReactNativeHost;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.TurboReactPackage;
+import com.facebook.react.bridge.JSIModuleSpec;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.JSIModulePackage;
@@ -36,8 +34,8 @@ import com.facebook.react.module.model.ReactModuleInfoProvider;
import com.facebook.react.modules.network.OkHttpClientProvider;
import com.facebook.soloader.SoLoader;
+import com.mattermost.flipper.ReactNativeFlipper;
import com.mattermost.networkclient.RCTOkHttpClientFactory;
-import com.mattermost.newarchitecture.MainApplicationReactNativeHost;
import com.nozbe.watermelondb.jsi.WatermelonDBJSIPackage;
public class MainApplication extends NavigationApplication implements INotificationsApplication {
@@ -46,7 +44,7 @@ public class MainApplication extends NavigationApplication implements INotificat
public Boolean sharedExtensionIsOpened = false;
private final ReactNativeHost mReactNativeHost =
- new ReactNativeHost(this) {
+ new DefaultReactNativeHost(this) {
@Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
@@ -106,30 +104,26 @@ public class MainApplication extends NavigationApplication implements INotificat
protected String getJSMainModuleName() {
return "index";
}
+
+ @Override
+ protected boolean isNewArchEnabled() {
+ return BuildConfig.IS_NEW_ARCHITECTURE_ENABLED;
+ }
+ @Override
+ protected Boolean isHermesEnabled() {
+ return BuildConfig.IS_HERMES_ENABLED;
+ }
};
-
- private final ReactNativeHost mNewArchitectureNativeHost =
- new MainApplicationReactNativeHost(this);
@Override
public ReactNativeHost getReactNativeHost() {
- if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
- return mNewArchitectureNativeHost;
- } else {
- return mReactNativeHost;
- }
+ return mReactNativeHost;
}
@Override
public void onCreate() {
super.onCreate();
instance = this;
-
- // 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());
-
Context context = getApplicationContext();
// Delete any previous temp files created by the app
@@ -141,6 +135,13 @@ public class MainApplication extends NavigationApplication implements INotificat
// with a cookie jar defined in APIClientModule and an interceptor to intercept all
// requests that originate from React Native's OKHttpClient
OkHttpClientProvider.setOkHttpClientFactory(new RCTOkHttpClientFactory());
+
+ SoLoader.init(this, /* native exopackage */ false);
+ if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
+ // If you opted-in for the New Architecture, we load the native entry point for this app.
+ DefaultNewArchitectureEntryPoint.load();
+ }
+ ReactNativeFlipper.initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
@Override
@@ -153,26 +154,4 @@ public class MainApplication extends NavigationApplication implements INotificat
new JsIOHelper()
);
}
-
- /**
- * Loads Flipper in React Native templates. Call this in the onCreate method with something like
- * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
- */
- private static void initializeFlipper(
- Context context, ReactInstanceManager reactInstanceManager) {
- if (BuildConfig.DEBUG) {
- try {
- /*
- We use reflection here to pick up the class that initializes Flipper,
- since Flipper library is not available in release mode
- */
- Class> aClass = Class.forName("com.rn.ReactNativeFlipper");
- aClass
- .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
- .invoke(null, context, reactInstanceManager);
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
}
diff --git a/android/app/src/main/java/com/mattermost/share/ShareUtils.java b/android/app/src/main/java/com/mattermost/share/ShareUtils.java
index b8ca97e7ba..143326edf2 100644
--- a/android/app/src/main/java/com/mattermost/share/ShareUtils.java
+++ b/android/app/src/main/java/com/mattermost/share/ShareUtils.java
@@ -90,22 +90,26 @@ public class ShareUtils {
}
private static Bitmap getBitmapAtTime(Context context, String filePath, int time) {
- MediaMetadataRetriever retriever = new MediaMetadataRetriever();
- if (URLUtil.isFileUrl(filePath)) {
- String decodedPath;
- try {
- decodedPath = URLDecoder.decode(filePath, "UTF-8");
- } catch (UnsupportedEncodingException e) {
- decodedPath = filePath;
+ try {
+ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+ if (URLUtil.isFileUrl(filePath)) {
+ String decodedPath;
+ try {
+ decodedPath = URLDecoder.decode(filePath, "UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ decodedPath = filePath;
+ }
+
+ retriever.setDataSource(decodedPath.replace("file://", ""));
+ } else if (filePath.contains("content://")) {
+ retriever.setDataSource(context, Uri.parse(filePath));
}
- retriever.setDataSource(decodedPath.replace("file://", ""));
- } else if (filePath.contains("content://")) {
- retriever.setDataSource(context, Uri.parse(filePath));
+ Bitmap image = retriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
+ retriever.release();
+ return image;
+ } catch (Exception e) {
+ throw new IllegalStateException("File doesn't exist or not supported");
}
-
- Bitmap image = retriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
- retriever.release();
- return image;
}
}
diff --git a/android/app/src/main/jni/CMakeLists.txt b/android/app/src/main/jni/CMakeLists.txt
deleted file mode 100644
index 6e63f482b8..0000000000
--- a/android/app/src/main/jni/CMakeLists.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-cmake_minimum_required(VERSION 3.13)
-
-# Define the library name here.
-project(rndiffapp_appmodules)
-
-# This file includes all the necessary to let you build your application with the New Architecture.
-include(${REACT_ANDROID_DIR}/cmake-utils/ReactNative-application.cmake)
diff --git a/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/android/app/src/main/jni/MainApplicationModuleProvider.cpp
deleted file mode 100644
index d34a1e4989..0000000000
--- a/android/app/src/main/jni/MainApplicationModuleProvider.cpp
+++ /dev/null
@@ -1,32 +0,0 @@
-#include "MainApplicationModuleProvider.h"
-
-#include
-#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);
-
- // Module providers autolinked by RN CLI
- auto rncli_module = rncli_ModuleProvider(moduleName, params);
- if (rncli_module != nullptr) {
- return rncli_module;
- }
-
- 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
deleted file mode 100644
index 48f1d107a1..0000000000
--- a/android/app/src/main/jni/MainApplicationModuleProvider.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#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
deleted file mode 100644
index 5fd688c509..0000000000
--- a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp
+++ /dev/null
@@ -1,45 +0,0 @@
-#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(
- const std::string &name) {
- return getTurboModule(name, nullptr) != nullptr ||
- getTurboModule(name, {.moduleName = name}) != nullptr;
-}
-
-} // namespace react
-} // namespace facebook
diff --git a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
deleted file mode 100644
index 58ced33388..0000000000
--- a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h
+++ /dev/null
@@ -1,38 +0,0 @@
-#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/rndiffapp/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(const std::string &name);
-};
-
-} // namespace react
-} // namespace facebook
diff --git a/android/app/src/main/jni/MainComponentsRegistry.cpp b/android/app/src/main/jni/MainComponentsRegistry.cpp
deleted file mode 100644
index 54f598a486..0000000000
--- a/android/app/src/main/jni/MainComponentsRegistry.cpp
+++ /dev/null
@@ -1,65 +0,0 @@
-#include "MainComponentsRegistry.h"
-
-#include
-#include
-#include
-#include
-#include
-
-namespace facebook {
-namespace react {
-
-MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {}
-
-std::shared_ptr
-MainComponentsRegistry::sharedProviderRegistry() {
- auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry();
-
- // Autolinked providers registered by RN CLI
- rncli_registerProviders(providerRegistry);
-
- // 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
diff --git a/android/app/src/main/jni/MainComponentsRegistry.h b/android/app/src/main/jni/MainComponentsRegistry.h
deleted file mode 100644
index 07af8980b3..0000000000
--- a/android/app/src/main/jni/MainComponentsRegistry.h
+++ /dev/null
@@ -1,32 +0,0 @@
-#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
deleted file mode 100644
index ae1ef007d1..0000000000
--- a/android/app/src/main/jni/OnLoad.cpp
+++ /dev/null
@@ -1,11 +0,0 @@
-#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/app/src/release/java/com/mattermost/flipper/ReactNativeFlipper.java b/android/app/src/release/java/com/mattermost/flipper/ReactNativeFlipper.java
new file mode 100644
index 0000000000..ae3179b7cf
--- /dev/null
+++ b/android/app/src/release/java/com/mattermost/flipper/ReactNativeFlipper.java
@@ -0,0 +1,19 @@
+/**
+ * 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.
+ */
+package com.mattermost.flipper;
+
+import android.content.Context;
+import com.facebook.react.ReactInstanceManager;
+/**
+ * Class responsible of loading Flipper inside your React Native application. This is the release
+ * flavor of it so it's empty as we don't want to load Flipper.
+ */
+public class ReactNativeFlipper {
+ public static void initializeFlipper(Context context, ReactInstanceManager reactInstanceManager) {
+ // Do nothing as we don't want to initialize Flipper on Release.
+ }
+}
diff --git a/android/build.gradle b/android/build.gradle
index 7672f725f8..11859e8dd4 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -2,22 +2,18 @@
buildscript {
ext {
- buildToolsVersion = "31.0.0"
+ buildToolsVersion = "33.0.0"
minSdkVersion = 24
- compileSdkVersion = 31
- targetSdkVersion = 31
- supportLibVersion = "31.0.0"
+ compileSdkVersion = 33
+ targetSdkVersion = 33
+ supportLibVersion = "33.0.0"
kotlinVersion = "1.5.30"
kotlin_version = "1.5.30"
firebaseVersion = "21.0.0"
RNNKotlinVersion = kotlinVersion
- 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"
- }
+
+ // We use NDK 23 which has both M1 support and is the side-by-side NDK version from AGP.
+ ndkVersion = "23.1.7779620"
}
repositories {
mavenCentral()
@@ -25,9 +21,8 @@ buildscript {
google()
}
dependencies {
- classpath("com.android.tools.build:gradle:7.2.1")
+ classpath("com.android.tools.build:gradle:7.3.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.14')
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
@@ -38,50 +33,9 @@ buildscript {
allprojects {
repositories {
- exclusiveContent {
- // We get React Native's Android binaries exclusively through npm,
- // from a local Maven repo inside node_modules/react-native/.
- // (The use of exclusiveContent prevents looking elsewhere like Maven Central
- // and potentially getting a wrong version.)
- filter {
- includeGroup "com.facebook.react"
- }
- forRepository {
- maven {
- url "$rootDir/../node_modules/react-native/android"
- }
- }
- }
- google()
- mavenCentral()
- mavenLocal()
- maven {
- // All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
- url("$rootDir/../node_modules/react-native/android")
-
- // Replace AAR from original RN with AAR from react-native-v8
- // url("$rootDir/../node_modules/react-native-v8/dist")
- }
- maven {
- // Local Maven repo containing AARs with JSC library built for Android
- url("$rootDir/../node_modules/jsc-android/dist")
-
- // prebuilt libv8android.so
- // url("$rootDir/../node_modules/v8-android/dist")
- }
- maven {
- url "https://www.jitpack.io"
- }
maven {
url "$rootDir/../node_modules/detox/Detox-android"
}
- mavenCentral {
- // We don't want to fetch react-native from Maven Central as there are
- // older versions over there.
- content {
- excludeGroup "com.facebook.react"
- }
- }
}
}
diff --git a/android/gradle.properties b/android/gradle.properties
index 7b404d8c1e..7b2301ced7 100644
--- a/android/gradle.properties
+++ b/android/gradle.properties
@@ -40,4 +40,8 @@ reactNativeArchitectures=armeabi-v7a,arm64-v8a,x86,x86_64
# 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
+newArchEnabled=false
+
+# Use this property to enable or disable the Hermes JS engine.
+# If set to false, you will be using JSC instead.
+hermesEnabled=true
diff --git a/android/settings.gradle b/android/settings.gradle
index 25584d1873..95c1009da4 100644
--- a/android/settings.gradle
+++ b/android/settings.gradle
@@ -1,13 +1,5 @@
rootProject.name = 'Mattermost'
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')
-}
-
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)
@@ -15,3 +7,4 @@ include ':react-native-video'
project(':react-native-video').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-video/android-exoplayer')
include ':watermelondb-jsi'
project(':watermelondb-jsi').projectDir = new File(rootProject.projectDir, '../node_modules/@nozbe/watermelondb/native/android-jsi')
+includeBuild('../node_modules/react-native-gradle-plugin')
diff --git a/app/actions/local/category.ts b/app/actions/local/category.ts
index 26e8abb057..f3956dc9c0 100644
--- a/app/actions/local/category.ts
+++ b/app/actions/local/category.ts
@@ -1,8 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Model} from '@nozbe/watermelondb';
-
import {CHANNELS_CATEGORY, DMS_CATEGORY} from '@constants/categories';
import DatabaseManager from '@database/manager';
import {prepareCategoryChannels, queryCategoriesByTeamIds, getCategoryById, prepareCategoriesAndCategoriesChannels} from '@queries/servers/categories';
@@ -11,6 +9,7 @@ import {queryMyTeams} from '@queries/servers/team';
import {isDMorGM} from '@utils/channel';
import {logError} from '@utils/log';
+import type {Model} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
export const deleteCategory = async (serverUrl: string, categoryId: string) => {
diff --git a/app/actions/local/channel.test.ts b/app/actions/local/channel.test.ts
index f739337790..5fbbae508b 100644
--- a/app/actions/local/channel.test.ts
+++ b/app/actions/local/channel.test.ts
@@ -1,13 +1,11 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Database} from '@nozbe/watermelondb';
import {DeviceEventEmitter} from 'react-native';
import {Navigation} from '@constants';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
-import ServerDataOperator from '@database/operator/server_data_operator';
import {getMyChannel} from '@queries/servers/channel';
import {getCommonSystemValues, getTeamHistory} from '@queries/servers/system';
import {getTeamChannelHistory} from '@queries/servers/team';
@@ -15,6 +13,9 @@ import {dismissAllModalsAndPopToRoot, dismissAllModalsAndPopToScreen} from '@scr
import {switchToChannel} from './channel';
+import type ServerDataOperator from '@database/operator/server_data_operator';
+import type {Database} from '@nozbe/watermelondb';
+
let mockIsTablet: jest.Mock;
const now = new Date('2020-01-01').getTime();
diff --git a/app/actions/local/channel.ts b/app/actions/local/channel.ts
index be4c2e2194..f31cac9aa1 100644
--- a/app/actions/local/channel.ts
+++ b/app/actions/local/channel.ts
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Model} from '@nozbe/watermelondb';
import {DeviceEventEmitter} from 'react-native';
import {General, Navigation as NavigationConstants, Preferences, Screens} from '@constants';
@@ -24,6 +23,7 @@ import {isTablet} from '@utils/helpers';
import {logError, logInfo} from '@utils/log';
import {displayGroupMessageName, displayUsername, getUserIdFromChannelName} from '@utils/user';
+import type {Model} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
import type UserModel from '@typings/database/models/servers/user';
diff --git a/app/actions/local/post.ts b/app/actions/local/post.ts
index 98fe62ad51..5f8b99fdc1 100644
--- a/app/actions/local/post.ts
+++ b/app/actions/local/post.ts
@@ -3,6 +3,7 @@
import {fetchPostAuthors} from '@actions/remote/post';
import {ActionType, Post} from '@constants';
+import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
import {getPostById, prepareDeletePost, queryPostsById} from '@queries/servers/post';
import {getCurrentUserId} from '@queries/servers/system';
@@ -18,6 +19,8 @@ import type MyChannelModel from '@typings/database/models/servers/my_channel';
import type PostModel from '@typings/database/models/servers/post';
import type UserModel from '@typings/database/models/servers/user';
+const {SERVER: {DRAFT, FILE, POST, POSTS_IN_THREAD, REACTION, THREAD, THREAD_PARTICIPANT, THREADS_IN_TEAM}} = MM_TABLES;
+
export const sendAddToChannelEphemeralPost = async (serverUrl: string, user: UserModel, addedUsernames: string[], messages: string[], channeId: string, postRootId = '') => {
try {
const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
@@ -244,3 +247,31 @@ export async function getPosts(serverUrl: string, ids: string[]) {
return [];
}
}
+
+export async function deletePosts(serverUrl: string, postIds: string[]) {
+ try {
+ const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
+
+ const postsFormatted = `'${postIds.join("','")}'`;
+
+ await database.write(() => {
+ return database.adapter.unsafeExecute({
+ sqls: [
+ [`DELETE FROM ${POST} where id IN (${postsFormatted})`, []],
+ [`DELETE FROM ${REACTION} where post_id IN (${postsFormatted})`, []],
+ [`DELETE FROM ${FILE} where post_id IN (${postsFormatted})`, []],
+ [`DELETE FROM ${DRAFT} where root_id IN (${postsFormatted})`, []],
+
+ [`DELETE FROM ${POSTS_IN_THREAD} where root_id IN (${postsFormatted})`, []],
+
+ [`DELETE FROM ${THREAD} where id IN (${postsFormatted})`, []],
+ [`DELETE FROM ${THREAD_PARTICIPANT} where thread_id IN (${postsFormatted})`, []],
+ [`DELETE FROM ${THREADS_IN_TEAM} where thread_id IN (${postsFormatted})`, []],
+ ],
+ });
+ });
+ return {error: false};
+ } catch (error) {
+ return {error};
+ }
+}
diff --git a/app/actions/local/systems.ts b/app/actions/local/systems.ts
index 070e4c8076..a64a7f3a30 100644
--- a/app/actions/local/systems.ts
+++ b/app/actions/local/systems.ts
@@ -1,14 +1,23 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import {Q} from '@nozbe/watermelondb';
import deepEqual from 'deep-equal';
-import {SYSTEM_IDENTIFIERS} from '@constants/database';
+import {MM_TABLES, SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import {getServerCredentials} from '@init/credentials';
-import {getConfig, getLicense} from '@queries/servers/system';
+import {queryAllChannelsForTeam} from '@queries/servers/channel';
+import {getConfig, getLicense, getGlobalDataRetentionPolicy, getGranularDataRetentionPolicies, getLastGlobalDataRetentionRun, getIsDataRetentionEnabled} from '@queries/servers/system';
import {logError} from '@utils/log';
+import {deletePosts} from './post';
+
+import type {DataRetentionPoliciesRequest} from '@actions/remote/systems';
+import type PostModel from '@typings/database/models/servers/post';
+
+const {SERVER: {POST}} = MM_TABLES;
+
export async function storeConfigAndLicense(serverUrl: string, config: ClientConfig, license: ClientLicense) {
try {
// If we have credentials for this server then update the values in the database
@@ -74,6 +83,155 @@ export async function storeConfig(serverUrl: string, config: ClientConfig | unde
return [];
}
+export async function storeDataRetentionPolicies(serverUrl: string, data: DataRetentionPoliciesRequest, prepareRecordsOnly = false) {
+ try {
+ const {globalPolicy, teamPolicies, channelPolicies} = data;
+ const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
+ const systems: IdValue[] = [{
+ id: SYSTEM_IDENTIFIERS.DATA_RETENTION_POLICIES,
+ value: globalPolicy || {},
+ }, {
+ id: SYSTEM_IDENTIFIERS.GRANULAR_DATA_RETENTION_POLICIES,
+ value: {
+ team: teamPolicies || [],
+ channel: channelPolicies || [],
+ },
+ }];
+
+ return operator.handleSystem({
+ systems,
+ prepareRecordsOnly,
+ });
+ } catch {
+ return [];
+ }
+}
+
+export async function updateLastDataRetentionRun(serverUrl: string, value?: number, prepareRecordsOnly = false) {
+ try {
+ const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
+
+ const systems: IdValue[] = [{
+ id: SYSTEM_IDENTIFIERS.LAST_DATA_RETENTION_RUN,
+ value: value || Date.now(),
+ }];
+
+ return operator.handleSystem({systems, prepareRecordsOnly});
+ } catch (error) {
+ logError('Failed updateLastDataRetentionRun', error);
+ return {error};
+ }
+}
+
+export async function dataRetentionCleanup(serverUrl: string) {
+ try {
+ const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
+
+ const isDataRetentionEnabled = await getIsDataRetentionEnabled(database);
+ if (!isDataRetentionEnabled) {
+ return {error: undefined};
+ }
+
+ const lastRunAt = await getLastGlobalDataRetentionRun(database);
+ const lastCleanedToday = new Date(lastRunAt).toDateString() === new Date().toDateString();
+
+ // Do not run if clean up is already done today
+ if (lastRunAt && lastCleanedToday) {
+ return {error: undefined};
+ }
+
+ const globalPolicy = await getGlobalDataRetentionPolicy(database);
+ const granularPoliciesData = await getGranularDataRetentionPolicies(database);
+
+ // Get global data retention cutoff
+ let globalRetentionCutoff = 0;
+ if (globalPolicy?.message_deletion_enabled) {
+ globalRetentionCutoff = globalPolicy.message_retention_cutoff;
+ }
+
+ // Get Granular data retention policies
+ let teamPolicies: TeamDataRetentionPolicy[] = [];
+ let channelPolicies: ChannelDataRetentionPolicy[] = [];
+ if (granularPoliciesData) {
+ teamPolicies = granularPoliciesData.team;
+ channelPolicies = granularPoliciesData.channel;
+ }
+
+ const channelsCutoffs: {[key: string]: number} = {};
+
+ // Get channel level cutoff from team policies
+ for await (const teamPolicy of teamPolicies) {
+ const {team_id, post_duration} = teamPolicy;
+ const channelIds = await queryAllChannelsForTeam(database, team_id).fetchIds();
+ if (channelIds.length) {
+ const cutoff = getDataRetentionPolicyCutoff(post_duration);
+ channelIds.forEach((channelId) => {
+ channelsCutoffs[channelId] = cutoff;
+ });
+ }
+ }
+
+ // Get channel level cutoff from channel policies
+ channelPolicies.forEach(({channel_id, post_duration}) => {
+ channelsCutoffs[channel_id] = getDataRetentionPolicyCutoff(post_duration);
+ });
+
+ const conditions = [];
+
+ const channelIds = Object.keys(channelsCutoffs);
+ if (channelIds.length) {
+ // Fetch posts by channel level cutoff
+ for (const channelId of channelIds) {
+ const cutoff = channelsCutoffs[channelId];
+ conditions.push(`(channel_id='${channelId}' AND create_at < ${cutoff})`);
+ }
+
+ // Fetch posts by global cutoff which are not already fetched by channel level cutoff
+ conditions.push(`(channel_id NOT IN ('${channelIds.join("','")}') AND create_at < ${globalRetentionCutoff})`);
+ } else {
+ conditions.push(`create_at < ${globalRetentionCutoff}`);
+ }
+
+ const postIds = await database.get(POST).query(
+ Q.unsafeSqlQuery(`SELECT * FROM ${POST} where ${conditions.join(' OR ')}`),
+ ).fetchIds();
+
+ if (postIds.length) {
+ const batchSize = 1000;
+ const deletePromises = [];
+ for (let i = 0; i < postIds.length; i += batchSize) {
+ const batch = postIds.slice(i, batchSize);
+ deletePromises.push(
+ deletePosts(serverUrl, batch),
+ );
+ }
+ const deleteResult = await Promise.all(deletePromises);
+ for (const {error} of deleteResult) {
+ if (error) {
+ return {error};
+ }
+ }
+ }
+
+ await updateLastDataRetentionRun(serverUrl);
+
+ return {error: undefined};
+ } catch (error) {
+ logError('An error occurred while performing data retention cleanup', error);
+ return {error};
+ }
+}
+
+// Returns cutoff time based on the policy's post_duration
+function getDataRetentionPolicyCutoff(postDuration: number) {
+ const periodDate = new Date();
+ periodDate.setDate(periodDate.getDate() - postDuration);
+ periodDate.setHours(0);
+ periodDate.setMinutes(0);
+ periodDate.setSeconds(0);
+ return periodDate.getTime();
+}
+
export async function setLastServerVersionCheck(serverUrl: string, reset = false) {
try {
const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
diff --git a/app/actions/remote/apps.ts b/app/actions/remote/apps.ts
index 8333d77fea..725112e142 100644
--- a/app/actions/remote/apps.ts
+++ b/app/actions/remote/apps.ts
@@ -1,16 +1,15 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
-
import {sendEphemeralPost} from '@actions/local/post';
-import ClientError from '@client/rest/error';
import {AppCallResponseTypes} from '@constants/apps';
import NetworkManager from '@managers/network_manager';
import {cleanForm, createCallRequest, makeCallErrorResponse} from '@utils/apps';
import type {Client} from '@client/rest';
+import type ClientError from '@client/rest/error';
import type PostModel from '@typings/database/models/servers/post';
+import type {IntlShape} from 'react-intl';
export async function handleBindingClick(serverUrl: string, binding: AppBinding, context: AppContext, intl: IntlShape): Promise<{data?: AppCallResponse; error?: AppCallResponse}> {
// Fetch form
diff --git a/app/actions/remote/channel.ts b/app/actions/remote/channel.ts
index 893b33e6e5..af1fb841d7 100644
--- a/app/actions/remote/channel.ts
+++ b/app/actions/remote/channel.ts
@@ -2,8 +2,6 @@
// See LICENSE.txt for license information.
/* eslint-disable max-lines */
-import {Model} from '@nozbe/watermelondb';
-import {IntlShape} from 'react-intl';
import {DeviceEventEmitter} from 'react-native';
import {addChannelToDefaultCategory, storeCategories} from '@actions/local/category';
@@ -40,7 +38,9 @@ import {addCurrentUserToTeam, fetchTeamByName, removeCurrentUserFromTeam} from '
import {fetchProfilesInGroupChannels, fetchProfilesPerChannels, fetchUsersByIds, updateUsersNoLongerVisible} from './user';
import type {Client} from '@client/rest';
+import type {Model} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
+import type {IntlShape} from 'react-intl';
export type MyChannelsRequest = {
categories?: CategoryWithChannels[];
diff --git a/app/actions/remote/command.ts b/app/actions/remote/command.ts
index bcc7c25c19..e95576f697 100644
--- a/app/actions/remote/command.ts
+++ b/app/actions/remote/command.ts
@@ -1,11 +1,9 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
import {Alert} from 'react-native';
import {doAppSubmit, postEphemeralCallResponseForCommandArgs} from '@actions/remote/apps';
-import {Client} from '@client/rest';
import {AppCommandParser} from '@components/autocomplete/slash_suggestion/app_command_parser/app_command_parser';
import {AppCallResponseTypes} from '@constants/apps';
import DatabaseManager from '@database/manager';
@@ -18,6 +16,9 @@ import {showAppForm} from '@screens/navigation';
import {handleDeepLink, matchDeepLink} from '@utils/deep_link';
import {tryOpenURL} from '@utils/url';
+import type {Client} from '@client/rest';
+import type {IntlShape} from 'react-intl';
+
export const executeCommand = async (serverUrl: string, intl: IntlShape, message: string, channelId: string, rootId?: string): Promise<{data?: CommandResponse; error?: string | {message: string}}> => {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
if (!operator) {
diff --git a/app/actions/remote/custom_emoji.ts b/app/actions/remote/custom_emoji.ts
index cd034828b8..a2bec37a69 100644
--- a/app/actions/remote/custom_emoji.ts
+++ b/app/actions/remote/custom_emoji.ts
@@ -2,13 +2,14 @@
// See LICENSE.txt for license information.
import {forceLogoutIfNecessary} from '@actions/remote/session';
-import {Client} from '@client/rest';
import {Emoji, General} from '@constants';
import DatabaseManager from '@database/manager';
import {debounce} from '@helpers/api/general';
import NetworkManager from '@managers/network_manager';
import {queryCustomEmojisByName} from '@queries/servers/custom_emoji';
+import type {Client} from '@client/rest';
+
export const fetchCustomEmojis = async (serverUrl: string, page = 0, perPage = General.PAGE_SIZE_DEFAULT, sort = Emoji.SORT_BY_NAME) => {
let client: Client;
try {
diff --git a/app/actions/remote/entry/app.ts b/app/actions/remote/entry/app.ts
index 58d0210091..d825ea2e71 100644
--- a/app/actions/remote/entry/app.ts
+++ b/app/actions/remote/entry/app.ts
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {setLastServerVersionCheck} from '@actions/local/systems';
+import {dataRetentionCleanup, setLastServerVersionCheck} from '@actions/local/systems';
import {fetchConfigAndLicense} from '@actions/remote/systems';
import DatabaseManager from '@database/manager';
import {prepareCommonSystemValues, getCurrentTeamId, getWebSocketLastDisconnected, getCurrentChannelId, getConfig, getLicense} from '@queries/servers/system';
@@ -27,6 +27,9 @@ export async function appEntry(serverUrl: string, since = 0, isUpgrade = false)
}
}
+ // Run data retention cleanup
+ await dataRetentionCleanup(serverUrl);
+
// clear lastUnreadChannelId
const removeLastUnreadChannelId = await prepareCommonSystemValues(operator, {lastUnreadChannelId: ''});
if (removeLastUnreadChannelId) {
diff --git a/app/actions/remote/entry/common.ts b/app/actions/remote/entry/common.ts
index 35ea06cd2f..beda43898e 100644
--- a/app/actions/remote/entry/common.ts
+++ b/app/actions/remote/entry/common.ts
@@ -1,8 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Database, Model} from '@nozbe/watermelondb';
-
+import {dataRetentionCleanup} from '@actions/local/systems';
import {fetchMissingDirectChannelsInfo, fetchMyChannelsForTeam, handleKickFromChannel, MyChannelsRequest} from '@actions/remote/channel';
import {fetchGroupsForMember} from '@actions/remote/groups';
import {fetchPostsForUnreadChannels} from '@actions/remote/post';
@@ -37,6 +36,7 @@ import {logDebug} from '@utils/log';
import {processIsCRTEnabled} from '@utils/thread';
import type ClientError from '@client/rest/error';
+import type {Database, Model} from '@nozbe/watermelondb';
export type AppEntryData = {
initialTeamId: string;
@@ -378,7 +378,9 @@ export const syncOtherServers = async (serverUrl: string) => {
for (const server of servers) {
if (server.url !== serverUrl && server.lastActiveAt > 0) {
registerDeviceToken(server.url);
- syncAllChannelMembersAndThreads(server.url);
+ syncAllChannelMembersAndThreads(server.url).then(() => {
+ dataRetentionCleanup(server.url);
+ });
autoUpdateTimezone(server.url);
}
}
diff --git a/app/actions/remote/entry/gql_common.ts b/app/actions/remote/entry/gql_common.ts
index 3006f2816c..32dae476f4 100644
--- a/app/actions/remote/entry/gql_common.ts
+++ b/app/actions/remote/entry/gql_common.ts
@@ -1,12 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Database} from '@nozbe/watermelondb';
-
import {storeConfigAndLicense} from '@actions/local/systems';
-import {MyChannelsRequest} from '@actions/remote/channel';
import {fetchGroupsForMember} from '@actions/remote/groups';
import {fetchPostsForUnreadChannels} from '@actions/remote/post';
+import {fetchDataRetentionPolicy} from '@actions/remote/systems';
import {MyTeamsRequest, updateCanJoinTeams} from '@actions/remote/team';
import {syncTeamThreads} from '@actions/remote/thread';
import {autoUpdateTimezone, updateAllUsersSince} from '@actions/remote/user';
@@ -18,14 +16,16 @@ import {selectDefaultTeam} from '@helpers/api/team';
import {queryAllChannels, queryAllChannelsForTeam} from '@queries/servers/channel';
import {prepareModels, truncateCrtRelatedTables} from '@queries/servers/entry';
import {getHasCRTChanged} from '@queries/servers/preference';
-import {getConfig} from '@queries/servers/system';
+import {getConfig, getIsDataRetentionEnabled} from '@queries/servers/system';
import {filterAndTransformRoles, getMemberChannelsFromGQLQuery, getMemberTeamsFromGQLQuery, gqlToClientChannelMembership, gqlToClientPreference, gqlToClientSidebarCategory, gqlToClientTeamMembership, gqlToClientUser} from '@utils/graphql';
import {logDebug} from '@utils/log';
import {processIsCRTEnabled} from '@utils/thread';
import {teamsToRemove, FETCH_UNREADS_TIMEOUT, entryRest, EntryResponse, entryInitialChannelId, restDeferredAppEntryActions, getRemoveTeamIds} from './common';
+import type {MyChannelsRequest} from '@actions/remote/channel';
import type ClientError from '@client/rest/error';
+import type {Database} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
export async function deferredAppEntryGraphQLActions(
@@ -265,6 +265,12 @@ export const entry = async (serverUrl: string, teamId?: string, channelId?: stri
result = entryRest(serverUrl, teamId, channelId, since);
}
+ // Fetch data retention policies
+ const isDataRetentionEnabled = await getIsDataRetentionEnabled(database);
+ if (isDataRetentionEnabled) {
+ fetchDataRetentionPolicy(serverUrl);
+ }
+
return result;
};
diff --git a/app/actions/remote/file.ts b/app/actions/remote/file.ts
index feae6f6691..60fe5dd13a 100644
--- a/app/actions/remote/file.ts
+++ b/app/actions/remote/file.ts
@@ -1,20 +1,25 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {ClientResponse, ClientResponseError} from '@mattermost/react-native-network-client';
-
-import {Client} from '@client/rest';
-import ClientError from '@client/rest/error';
import {DOWNLOAD_TIMEOUT} from '@constants/network';
import NetworkManager from '@managers/network_manager';
import {forceLogoutIfNecessary} from './session';
+import type {Client} from '@client/rest';
+import type ClientError from '@client/rest/error';
+import type {ClientResponse, ClientResponseError} from '@mattermost/react-native-network-client';
+
export const downloadFile = (serverUrl: string, fileId: string, desitnation: string) => { // Let it throw and handle it accordingly
const client = NetworkManager.getClient(serverUrl);
return client.apiClient.download(client.getFileRoute(fileId), desitnation.replace('file://', ''), {timeoutInterval: DOWNLOAD_TIMEOUT});
};
+export const downloadProfileImage = (serverUrl: string, userId: string, lastPictureUpdate: number, destination: string) => { // Let it throw and handle it accordingly
+ const client = NetworkManager.getClient(serverUrl);
+ return client.apiClient.download(client.getProfilePictureUrl(userId, lastPictureUpdate), destination.replace('file://', ''), {timeoutInterval: DOWNLOAD_TIMEOUT});
+};
+
export const uploadFile = (
serverUrl: string,
file: FileInfo,
diff --git a/app/actions/remote/groups.ts b/app/actions/remote/groups.ts
index 0ea353c85b..cd6997d21e 100644
--- a/app/actions/remote/groups.ts
+++ b/app/actions/remote/groups.ts
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Client} from '@client/rest';
import DatabaseManager from '@database/manager';
import NetworkManager from '@managers/network_manager';
import {getChannelById} from '@queries/servers/channel';
@@ -9,6 +8,8 @@ import {getTeamById} from '@queries/servers/team';
import {forceLogoutIfNecessary} from './session';
+import type {Client} from '@client/rest';
+
export const fetchGroup = async (serverUrl: string, id: string, fetchOnly = false) => {
try {
const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
diff --git a/app/actions/remote/post.ts b/app/actions/remote/post.ts
index ba85a9240b..be2641b922 100644
--- a/app/actions/remote/post.ts
+++ b/app/actions/remote/post.ts
@@ -444,7 +444,7 @@ export async function fetchPostsBefore(serverUrl: string, channelId: string, pos
} catch (error) {
forceLogoutIfNecessary(serverUrl, error as ClientErrorProps);
if (activeServerUrl === serverUrl) {
- DeviceEventEmitter.emit(Events.LOADING_CHANNEL_POSTS, true);
+ DeviceEventEmitter.emit(Events.LOADING_CHANNEL_POSTS, false);
}
return {error};
}
diff --git a/app/actions/remote/reactions.ts b/app/actions/remote/reactions.ts
index 0684b7de51..5537acbf23 100644
--- a/app/actions/remote/reactions.ts
+++ b/app/actions/remote/reactions.ts
@@ -1,8 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Model} from '@nozbe/watermelondb';
-
import {addRecentReaction} from '@actions/local/reactions';
import DatabaseManager from '@database/manager';
import NetworkManager from '@managers/network_manager';
@@ -14,6 +12,7 @@ import {getEmojiFirstAlias} from '@utils/emoji/helpers';
import {forceLogoutIfNecessary} from './session';
import type {Client} from '@client/rest';
+import type {Model} from '@nozbe/watermelondb';
import type PostModel from '@typings/database/models/servers/post';
export async function addReaction(serverUrl: string, postId: string, emojiName: string) {
diff --git a/app/actions/remote/session.ts b/app/actions/remote/session.ts
index df3460b914..68108e03b0 100644
--- a/app/actions/remote/session.ts
+++ b/app/actions/remote/session.ts
@@ -21,7 +21,6 @@ import {scheduleExpiredNotification} from '@utils/notification';
import {getCSRFFromCookie} from '@utils/security';
import {loginEntry} from './entry';
-import {fetchDataRetentionPolicy} from './systems';
import type ClientError from '@client/rest/error';
import type {LoginArgs} from '@typings/database/database';
@@ -42,11 +41,6 @@ export const completeLogin = async (serverUrl: string) => {
return null;
}
- // Data retention
- if (config?.DataRetentionEnableMessageDeletion === 'true' && license?.IsLicensed === 'true' && license?.DataRetention === 'true') {
- fetchDataRetentionPolicy(serverUrl);
- }
-
await DatabaseManager.setActiveServerDatabase(serverUrl);
const systems: IdValue[] = [];
diff --git a/app/actions/remote/systems.ts b/app/actions/remote/systems.ts
index fbfbf1b52e..d8280b194b 100644
--- a/app/actions/remote/systems.ts
+++ b/app/actions/remote/systems.ts
@@ -1,12 +1,11 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {storeConfigAndLicense} from '@actions/local/systems';
+import {storeConfigAndLicense, storeDataRetentionPolicies} from '@actions/local/systems';
import {forceLogoutIfNecessary} from '@actions/remote/session';
-import {SYSTEM_IDENTIFIERS} from '@constants/database';
import DatabaseManager from '@database/manager';
import NetworkManager from '@managers/network_manager';
-import {logError} from '@utils/log';
+import {getCurrentUserId} from '@queries/servers/system';
import type ClientError from '@client/rest/error';
@@ -16,7 +15,47 @@ export type ConfigAndLicenseRequest = {
error?: unknown;
}
-export const fetchDataRetentionPolicy = async (serverUrl: string) => {
+export type DataRetentionPoliciesRequest = {
+ globalPolicy?: GlobalDataRetentionPolicy;
+ teamPolicies?: TeamDataRetentionPolicy[];
+ channelPolicies?: ChannelDataRetentionPolicy[];
+ error?: unknown;
+}
+
+export const fetchDataRetentionPolicy = async (serverUrl: string, fetchOnly = false): Promise => {
+ const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
+ if (!operator) {
+ return {error: `${serverUrl} database not found`};
+ }
+
+ try {
+ const {data: globalPolicy, error: globalPolicyError} = await fetchGlobalDataRetentionPolicy(serverUrl);
+ const {data: teamPolicies, error: teamPoliciesError} = await fetchAllGranularDataRetentionPolicies(serverUrl);
+ const {data: channelPolicies, error: channelPoliciesError} = await fetchAllGranularDataRetentionPolicies(serverUrl, true);
+
+ const hasError = globalPolicyError || teamPoliciesError || channelPoliciesError;
+ if (hasError) {
+ return hasError;
+ }
+
+ const data = {
+ globalPolicy,
+ teamPolicies: teamPolicies as TeamDataRetentionPolicy[],
+ channelPolicies: channelPolicies as ChannelDataRetentionPolicy[],
+ };
+
+ if (!fetchOnly) {
+ await storeDataRetentionPolicies(serverUrl, data);
+ }
+
+ return data;
+ } catch (error) {
+ forceLogoutIfNecessary(serverUrl, error as ClientError);
+ return {error};
+ }
+};
+
+export const fetchGlobalDataRetentionPolicy = async (serverUrl: string): Promise<{data?: GlobalDataRetentionPolicy; error?: unknown}> => {
let client;
try {
client = NetworkManager.getClient(serverUrl);
@@ -24,28 +63,47 @@ export const fetchDataRetentionPolicy = async (serverUrl: string) => {
return {error};
}
- let data = {};
try {
- data = await client.getDataRetentionPolicy();
+ const data = await client.getGlobalDataRetentionPolicy();
+ return {data};
} catch (error) {
forceLogoutIfNecessary(serverUrl, error as ClientError);
return {error};
}
+};
- const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
- if (operator) {
- const systems: IdValue[] = [{
- id: SYSTEM_IDENTIFIERS.DATA_RETENTION_POLICIES,
- value: JSON.stringify(data),
- }];
-
- operator.handleSystem({systems, prepareRecordsOnly: false}).
- catch((error) => {
- logError('An error occurred while saving data retention policies', error);
- });
+export const fetchAllGranularDataRetentionPolicies = async (
+ serverUrl: string,
+ isChannel = false,
+ page = 0,
+ policies: Array = [],
+): Promise<{data?: Array; error?: unknown}> => {
+ let client;
+ try {
+ client = NetworkManager.getClient(serverUrl);
+ } catch (error) {
+ return {error};
}
- return data;
+ const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
+ if (!operator) {
+ return {error: `${serverUrl} database not found`};
+ }
+
+ const {database} = operator;
+
+ const currentUserId = await getCurrentUserId(database);
+ let data;
+ if (isChannel) {
+ data = await client.getChannelDataRetentionPolicies(currentUserId, page);
+ } else {
+ data = await client.getTeamDataRetentionPolicies(currentUserId, page);
+ }
+ policies.push(...data.policies);
+ if (policies.length < data.total_count) {
+ await fetchAllGranularDataRetentionPolicies(serverUrl, isChannel, page + 1, policies);
+ }
+ return {data: policies};
};
export const fetchConfigAndLicense = async (serverUrl: string, fetchOnly = false): Promise => {
diff --git a/app/actions/remote/team.ts b/app/actions/remote/team.ts
index 1199288a97..2508e91b47 100644
--- a/app/actions/remote/team.ts
+++ b/app/actions/remote/team.ts
@@ -1,11 +1,9 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Model} from '@nozbe/watermelondb';
import {DeviceEventEmitter} from 'react-native';
import {removeUserFromTeam as localRemoveUserFromTeam} from '@actions/local/team';
-import {Client} from '@client/rest';
import {PER_PAGE_DEFAULT} from '@client/rest/constants';
import {Events} from '@constants';
import DatabaseManager from '@database/manager';
@@ -27,7 +25,9 @@ import {fetchPostsForChannel, fetchPostsForUnreadChannels} from './post';
import {fetchRolesIfNeeded} from './role';
import {forceLogoutIfNecessary} from './session';
+import type {Client} from '@client/rest';
import type ClientError from '@client/rest/error';
+import type {Model} from '@nozbe/watermelondb';
export type MyTeamsRequest = {
teams?: Team[];
@@ -114,6 +114,54 @@ export async function addUserToTeam(serverUrl: string, teamId: string, userId: s
}
}
+export async function addUsersToTeam(serverUrl: string, teamId: string, userIds: string[], fetchOnly = false) {
+ try {
+ const client = NetworkManager.getClient(serverUrl);
+ const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
+ EphemeralStore.startAddingToTeam(teamId);
+
+ const members = await client.addUsersToTeamGracefully(teamId, userIds);
+
+ if (!fetchOnly) {
+ const teamMemberships: TeamMembership[] = [];
+ const roles = [];
+
+ for (const {member} of members) {
+ teamMemberships.push(member);
+ roles.push(...member.roles.split(' '));
+ }
+
+ fetchRolesIfNeeded(serverUrl, Array.from(new Set(roles)));
+
+ if (operator) {
+ await operator.handleTeamMemberships({teamMemberships, prepareRecordsOnly: true});
+ }
+ }
+
+ EphemeralStore.finishAddingToTeam(teamId);
+ return {members};
+ } catch (error) {
+ if (EphemeralStore.isAddingToTeam(teamId)) {
+ EphemeralStore.finishAddingToTeam(teamId);
+ }
+
+ forceLogoutIfNecessary(serverUrl, error as ClientError);
+ return {error};
+ }
+}
+
+export async function sendEmailInvitesToTeam(serverUrl: string, teamId: string, emails: string[]) {
+ try {
+ const client = NetworkManager.getClient(serverUrl);
+ const members = await client.sendEmailInvitesToTeamGracefully(teamId, emails);
+
+ return {members};
+ } catch (error) {
+ forceLogoutIfNecessary(serverUrl, error as ClientError);
+ return {error};
+ }
+}
+
export async function fetchMyTeams(serverUrl: string, fetchOnly = false): Promise {
let client;
try {
@@ -428,3 +476,28 @@ export async function handleKickFromTeam(serverUrl: string, teamId: string) {
logDebug('Failed to kick user from team', error);
}
}
+
+export async function getTeamMembersByIds(serverUrl: string, teamId: string, userIds: string[], fetchOnly?: boolean) {
+ try {
+ const client = NetworkManager.getClient(serverUrl);
+ const {operator} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
+ const members = await client.getTeamMembersByIds(teamId, userIds);
+
+ if (!fetchOnly) {
+ const roles = [];
+
+ for (const {roles: memberRoles} of members) {
+ roles.push(...memberRoles.split(' '));
+ }
+
+ fetchRolesIfNeeded(serverUrl, Array.from(new Set(roles)));
+
+ await operator.handleTeamMemberships({teamMemberships: members, prepareRecordsOnly: true});
+ }
+
+ return {members};
+ } catch (error) {
+ forceLogoutIfNecessary(serverUrl, error as ClientError);
+ return {error};
+ }
+}
diff --git a/app/actions/remote/thread.ts b/app/actions/remote/thread.ts
index 25f38abf10..f4e91b0de4 100644
--- a/app/actions/remote/thread.ts
+++ b/app/actions/remote/thread.ts
@@ -1,8 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import Model from '@nozbe/watermelondb/Model';
-
import {markTeamThreadsAsRead, markThreadAsViewed, processReceivedThreads, switchToThread, updateTeamThreadsSync, updateThread} from '@actions/local/thread';
import {fetchPostThread} from '@actions/remote/post';
import {General} from '@constants';
@@ -19,6 +17,7 @@ import {getThreadsListEdges} from '@utils/thread';
import {forceLogoutIfNecessary} from './session';
import type {Client} from '@client/rest';
+import type Model from '@nozbe/watermelondb/Model';
type FetchThreadsOptions = {
before?: string;
diff --git a/app/actions/remote/user.ts b/app/actions/remote/user.ts
index 195f316a20..a1d6dc9c78 100644
--- a/app/actions/remote/user.ts
+++ b/app/actions/remote/user.ts
@@ -3,7 +3,6 @@
/* eslint-disable max-lines */
-import {Model} from '@nozbe/watermelondb';
import {chunk} from 'lodash';
import {updateChannelsDisplayName} from '@actions/local/channel';
@@ -26,6 +25,7 @@ import {forceLogoutIfNecessary} from './session';
import type {Client} from '@client/rest';
import type ClientError from '@client/rest/error';
+import type {Model} from '@nozbe/watermelondb';
import type UserModel from '@typings/database/models/servers/user';
export type MyUserRequest = {
diff --git a/app/actions/websocket/channel.ts b/app/actions/websocket/channel.ts
index 189c7f7d12..9d29e73469 100644
--- a/app/actions/websocket/channel.ts
+++ b/app/actions/websocket/channel.ts
@@ -1,8 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Model} from '@nozbe/watermelondb';
-
import {addChannelToDefaultCategory} from '@actions/local/category';
import {
markChannelAsViewed, removeCurrentUserFromChannel, setChannelDeleteAt,
@@ -22,6 +20,8 @@ import {getCurrentUser, getTeammateNameDisplay, getUserById} from '@queries/serv
import EphemeralStore from '@store/ephemeral_store';
import {logDebug} from '@utils/log';
+import type {Model} from '@nozbe/watermelondb';
+
// Received when current user created a channel in a different client
export async function handleChannelCreatedEvent(serverUrl: string, msg: any) {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
diff --git a/app/actions/websocket/posts.ts b/app/actions/websocket/posts.ts
index 1c5877e18a..ead0530a12 100644
--- a/app/actions/websocket/posts.ts
+++ b/app/actions/websocket/posts.ts
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Model} from '@nozbe/watermelondb';
import {DeviceEventEmitter} from 'react-native';
import {storeMyChannelsForTeam, markChannelAsUnread, markChannelAsViewed, updateLastPostAt} from '@actions/local/channel';
@@ -20,12 +19,11 @@ import NavigationStore from '@store/navigation_store';
import {isTablet} from '@utils/helpers';
import {isFromWebhook, isSystemMessage, shouldIgnorePost} from '@utils/post';
+import type {Model} from '@nozbe/watermelondb';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
function preparedMyChannelHack(myChannel: MyChannelModel) {
- // @ts-expect-error hack accessing _preparedState
if (!myChannel._preparedState) {
- // @ts-expect-error hack setting _preparedState
myChannel._preparedState = null;
}
}
diff --git a/app/actions/websocket/teams.ts b/app/actions/websocket/teams.ts
index c59d62d385..afd4ba6dd6 100644
--- a/app/actions/websocket/teams.ts
+++ b/app/actions/websocket/teams.ts
@@ -1,15 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Model} from '@nozbe/watermelondb';
-
import {removeUserFromTeam} from '@actions/local/team';
import {fetchMyChannelsForTeam} from '@actions/remote/channel';
import {fetchRoles} from '@actions/remote/role';
import {fetchMyTeam, handleKickFromTeam, updateCanJoinTeams} from '@actions/remote/team';
import {updateUsersNoLongerVisible} from '@actions/remote/user';
import DatabaseManager from '@database/manager';
-import ServerDataOperator from '@database/operator/server_data_operator';
import NetworkManager from '@managers/network_manager';
import {prepareCategoriesAndCategoriesChannels} from '@queries/servers/categories';
import {prepareMyChannelsForTeam} from '@queries/servers/channel';
@@ -19,6 +16,9 @@ import EphemeralStore from '@store/ephemeral_store';
import {setTeamLoading} from '@store/team_load_store';
import {logDebug} from '@utils/log';
+import type ServerDataOperator from '@database/operator/server_data_operator';
+import type {Model} from '@nozbe/watermelondb';
+
export async function handleTeamArchived(serverUrl: string, msg: WebSocketMessage) {
try {
const {database} = DatabaseManager.getServerDatabaseAndOperator(serverUrl);
diff --git a/app/actions/websocket/users.ts b/app/actions/websocket/users.ts
index 1cf23d41e0..71ba361fcc 100644
--- a/app/actions/websocket/users.ts
+++ b/app/actions/websocket/users.ts
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Model} from '@nozbe/watermelondb';
import {DeviceEventEmitter} from 'react-native';
import {updateChannelsDisplayName} from '@actions/local/channel';
@@ -16,6 +15,8 @@ import {getConfig, getLicense} from '@queries/servers/system';
import {getCurrentUser} from '@queries/servers/user';
import {displayUsername} from '@utils/user';
+import type {Model} from '@nozbe/watermelondb';
+
export async function handleUserUpdatedEvent(serverUrl: string, msg: WebSocketMessage) {
const operator = DatabaseManager.serverDatabases[serverUrl]?.operator;
if (!operator) {
diff --git a/app/client/graphQL/entry.ts b/app/client/graphQL/entry.ts
index b83e08d84b..7e6fb90ec5 100644
--- a/app/client/graphQL/entry.ts
+++ b/app/client/graphQL/entry.ts
@@ -1,11 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Client} from '@client/rest';
import {MEMBERS_PER_PAGE} from '@constants/graphql';
import NetworkManager from '@managers/network_manager';
import QueryNames from './constants';
+import type {Client} from '@client/rest';
+
const doGQLQuery = async (serverUrl: string, query: string, variables: {[name: string]: any}, operationName: string) => {
let client: Client;
try {
diff --git a/app/client/rest/base.ts b/app/client/rest/base.ts
index 573f09aa29..c2aa06885c 100644
--- a/app/client/rest/base.ts
+++ b/app/client/rest/base.ts
@@ -177,10 +177,14 @@ export default class ClientBase {
return `${this.getEmojisRoute()}/${emojiId}`;
}
- getDataRetentionRoute() {
+ getGlobalDataRetentionRoute() {
return `${this.urlVersion}/data_retention`;
}
+ getGranularDataRetentionRoute(userId: string) {
+ return `${this.getUserRoute(userId)}/data_retention`;
+ }
+
getRolesRoute() {
return `${this.urlVersion}/roles`;
}
diff --git a/app/client/rest/files.ts b/app/client/rest/files.ts
index 0a1f8a3d6e..c4cd648361 100644
--- a/app/client/rest/files.ts
+++ b/app/client/rest/files.ts
@@ -1,10 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {ClientResponse, ClientResponseError, ProgressPromise, UploadRequestOptions} from '@mattermost/react-native-network-client';
-
import {toMilliseconds} from '@utils/datetime';
+import type {ClientResponse, ClientResponseError, ProgressPromise, UploadRequestOptions} from '@mattermost/react-native-network-client';
+
export interface ClientFilesMix {
getFileUrl: (fileId: string, timestamp: number) => string;
getFileThumbnailUrl: (fileId: string, timestamp: number) => string;
diff --git a/app/client/rest/general.ts b/app/client/rest/general.ts
index c5486d34ff..b4093ca254 100644
--- a/app/client/rest/general.ts
+++ b/app/client/rest/general.ts
@@ -3,8 +3,14 @@
import {buildQueryString} from '@utils/helpers';
+import {PER_PAGE_DEFAULT} from './constants';
import ClientError from './error';
+type PoliciesResponse = {
+ policies: T[];
+ total_count: number;
+}
+
export interface ClientGeneralMix {
getOpenGraphMetadata: (url: string) => Promise;
ping: (deviceId?: string, timeoutInterval?: number) => Promise;
@@ -12,7 +18,9 @@ export interface ClientGeneralMix {
getClientConfigOld: () => Promise;
getClientLicenseOld: () => Promise;
getTimezones: () => Promise;
- getDataRetentionPolicy: () => Promise;
+ getGlobalDataRetentionPolicy: () => Promise;
+ getTeamDataRetentionPolicies: (userId: string, page?: number, perPage?: number) => Promise>;
+ getChannelDataRetentionPolicies: (userId: string, page?: number, perPage?: number) => Promise>;
getRolesByNames: (rolesNames: string[]) => Promise;
getRedirectLocation: (urlParam: string) => Promise>;
}
@@ -74,9 +82,23 @@ const ClientGeneral = (superclass: any) => class extends superclass {
);
};
- getDataRetentionPolicy = () => {
+ getGlobalDataRetentionPolicy = () => {
return this.doFetch(
- `${this.getDataRetentionRoute()}/policy`,
+ `${this.getGlobalDataRetentionRoute()}/policy`,
+ {method: 'get'},
+ );
+ };
+
+ getTeamDataRetentionPolicies = (userId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
+ return this.doFetch(
+ `${this.getGranularDataRetentionRoute(userId)}/team_policies${buildQueryString({page, per_page: perPage})}`,
+ {method: 'get'},
+ );
+ };
+
+ getChannelDataRetentionPolicies = (userId: string, page = 0, perPage = PER_PAGE_DEFAULT) => {
+ return this.doFetch(
+ `${this.getGranularDataRetentionRoute(userId)}/channel_policies${buildQueryString({page, per_page: perPage})}`,
{method: 'get'},
);
};
diff --git a/app/client/rest/teams.ts b/app/client/rest/teams.ts
index 9c53c0350b..1902565680 100644
--- a/app/client/rest/teams.ts
+++ b/app/client/rest/teams.ts
@@ -18,7 +18,10 @@ export interface ClientTeamsMix {
getMyTeamMembers: () => Promise;
getTeamMembers: (teamId: string, page?: number, perPage?: number) => Promise;
getTeamMember: (teamId: string, userId: string) => Promise;
+ getTeamMembersByIds: (teamId: string, userIds: string[]) => Promise;
addToTeam: (teamId: string, userId: string) => Promise;
+ addUsersToTeamGracefully: (teamId: string, userIds: string[]) => Promise;
+ sendEmailInvitesToTeamGracefully: (teamId: string, emails: string[]) => Promise;
joinTeam: (inviteId: string) => Promise;
removeFromTeam: (teamId: string, userId: string) => Promise;
getTeamStats: (teamId: string) => Promise;
@@ -120,6 +123,13 @@ const ClientTeams = (superclass: any) => class extends superclass {
);
};
+ getTeamMembersByIds = (teamId: string, userIds: string[]) => {
+ return this.doFetch(
+ `${this.getTeamMembersRoute(teamId)}/ids`,
+ {method: 'post', body: userIds},
+ );
+ };
+
addToTeam = async (teamId: string, userId: string) => {
this.analytics.trackAPI('api_teams_invite_members', {team_id: teamId});
@@ -130,6 +140,27 @@ const ClientTeams = (superclass: any) => class extends superclass {
);
};
+ addUsersToTeamGracefully = (teamId: string, userIds: string[]) => {
+ this.analytics.trackAPI('api_teams_batch_add_members', {team_id: teamId, count: userIds.length});
+
+ const members: Array<{team_id: string; user_id: string}> = [];
+ userIds.forEach((id) => members.push({team_id: teamId, user_id: id}));
+
+ return this.doFetch(
+ `${this.getTeamMembersRoute(teamId)}/batch?graceful=true`,
+ {method: 'post', body: members},
+ );
+ };
+
+ sendEmailInvitesToTeamGracefully = (teamId: string, emails: string[]) => {
+ this.analytics.trackAPI('api_teams_invite_members', {team_id: teamId});
+
+ return this.doFetch(
+ `${this.getTeamRoute(teamId)}/invite/email?graceful=true`,
+ {method: 'post', body: emails},
+ );
+ };
+
joinTeam = async (inviteId: string) => {
const query = buildQueryString({invite_id: inviteId});
return this.doFetch(
diff --git a/app/components/autocomplete/autocomplete.tsx b/app/components/autocomplete/autocomplete.tsx
index 640fd4f34c..2f7998d71e 100644
--- a/app/components/autocomplete/autocomplete.tsx
+++ b/app/components/autocomplete/autocomplete.tsx
@@ -31,8 +31,9 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
elevation: 3,
},
shadow: {
+ backgroundColor: theme.centerChannelBg,
shadowColor: '#000',
- shadowOpacity: 0.12,
+ shadowOpacity: 1,
shadowRadius: 6,
shadowOffset: {
width: 0,
diff --git a/app/components/autocomplete/slash_suggestion/app_command_parser/app_command_parser.ts b/app/components/autocomplete/slash_suggestion/app_command_parser/app_command_parser.ts
index 899d760946..5b8f1431ce 100644
--- a/app/components/autocomplete/slash_suggestion/app_command_parser/app_command_parser.ts
+++ b/app/components/autocomplete/slash_suggestion/app_command_parser/app_command_parser.ts
@@ -1,9 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Database} from '@nozbe/watermelondb';
-import {IntlShape} from 'react-intl';
-
import {doAppFetchForm, doAppLookup} from '@actions/remote/apps';
import {fetchChannelById, fetchChannelByName, searchChannels} from '@actions/remote/channel';
import {fetchUsersByIds, fetchUsersByUsernames, searchUsers} from '@actions/remote/user';
@@ -17,8 +14,10 @@ import {createCallRequest, filterEmptyOptions} from '@utils/apps';
import {getChannelSuggestions, getUserSuggestions, inTextMentionSuggestions} from './mentions';
+import type {Database} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
import type UserModel from '@typings/database/models/servers/user';
+import type {IntlShape} from 'react-intl';
/* eslint-disable max-lines */
diff --git a/app/components/block/index.tsx b/app/components/block/index.tsx
index b016afece2..de8fb4ca24 100644
--- a/app/components/block/index.tsx
+++ b/app/components/block/index.tsx
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {MessageDescriptor} from '@formatjs/intl/src/types';
import React from 'react';
import {StyleProp, TextStyle, View, ViewProps, ViewStyle} from 'react-native';
@@ -9,6 +8,8 @@ import FormattedText from '@components/formatted_text';
import {useTheme} from '@context/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
+import type {MessageDescriptor} from '@formatjs/intl/src/types';
+
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
container: {
diff --git a/app/components/channel_actions/add_people_box/index.tsx b/app/components/channel_actions/add_people_box/index.tsx
index d3b106be80..4ef09ef6b2 100644
--- a/app/components/channel_actions/add_people_box/index.tsx
+++ b/app/components/channel_actions/add_people_box/index.tsx
@@ -3,12 +3,13 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
-import {StyleProp, ViewStyle} from 'react-native';
import OptionBox from '@components/option_box';
import {Screens} from '@constants';
import {dismissBottomSheet, goToScreen, showModal} from '@screens/navigation';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
channelId: string;
containerStyle?: StyleProp;
diff --git a/app/components/channel_actions/favorite_box/favorite_box.tsx b/app/components/channel_actions/favorite_box/favorite_box.tsx
index 06950b36f0..ee60331a39 100644
--- a/app/components/channel_actions/favorite_box/favorite_box.tsx
+++ b/app/components/channel_actions/favorite_box/favorite_box.tsx
@@ -3,13 +3,14 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
-import {StyleProp, ViewStyle} from 'react-native';
import {toggleFavoriteChannel} from '@actions/remote/category';
import OptionBox from '@components/option_box';
import {useServerUrl} from '@context/server';
import {dismissBottomSheet} from '@screens/navigation';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
channelId: string;
containerStyle?: StyleProp;
diff --git a/app/components/channel_actions/info_box/index.tsx b/app/components/channel_actions/info_box/index.tsx
index 6d236197fb..036e4a2b66 100644
--- a/app/components/channel_actions/info_box/index.tsx
+++ b/app/components/channel_actions/info_box/index.tsx
@@ -3,7 +3,6 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
-import {StyleProp, ViewStyle} from 'react-native';
import CompassIcon from '@components/compass_icon';
import OptionBox from '@components/option_box';
@@ -12,6 +11,8 @@ import {Screens} from '@constants';
import {useTheme} from '@context/theme';
import {dismissBottomSheet, showModal} from '@screens/navigation';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
channelId: string;
containerStyle?: StyleProp;
diff --git a/app/components/channel_actions/mute_box/mute_box.tsx b/app/components/channel_actions/mute_box/mute_box.tsx
index 4d96c7d5d2..8a9b086383 100644
--- a/app/components/channel_actions/mute_box/mute_box.tsx
+++ b/app/components/channel_actions/mute_box/mute_box.tsx
@@ -3,13 +3,14 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
-import {StyleProp, ViewStyle} from 'react-native';
import {toggleMuteChannel} from '@actions/remote/channel';
import OptionBox from '@components/option_box';
import {useServerUrl} from '@context/server';
import {dismissBottomSheet} from '@screens/navigation';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
channelId: string;
containerStyle?: StyleProp;
diff --git a/app/components/channel_actions/set_header_box/set_header.tsx b/app/components/channel_actions/set_header_box/set_header.tsx
index e9d67cc169..54ad73f87f 100644
--- a/app/components/channel_actions/set_header_box/set_header.tsx
+++ b/app/components/channel_actions/set_header_box/set_header.tsx
@@ -3,12 +3,13 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
-import {StyleProp, ViewStyle} from 'react-native';
import OptionBox from '@components/option_box';
import {Screens} from '@constants';
import {dismissBottomSheet, goToScreen, showModal} from '@screens/navigation';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
channelId: string;
containerStyle?: StyleProp;
diff --git a/app/components/channel_item/__snapshots__/channel_item.test.tsx.snap b/app/components/channel_item/__snapshots__/channel_item.test.tsx.snap
index 24c2442e29..ea25aef92e 100644
--- a/app/components/channel_item/__snapshots__/channel_item.test.tsx.snap
+++ b/app/components/channel_item/__snapshots__/channel_item.test.tsx.snap
@@ -2,6 +2,23 @@
exports[`components/channel_list/categories/body/channel_item should match snapshot 1`] = `
{
let database: Database;
const channel: Channel = {
diff --git a/app/components/common_post_options/copy_permalink_option/copy_permalink_option.tsx b/app/components/common_post_options/copy_permalink_option/copy_permalink_option.tsx
index 8ba0ee61d0..07b9c6a864 100644
--- a/app/components/common_post_options/copy_permalink_option/copy_permalink_option.tsx
+++ b/app/components/common_post_options/copy_permalink_option/copy_permalink_option.tsx
@@ -5,7 +5,6 @@ import Clipboard from '@react-native-clipboard/clipboard';
import React, {useCallback} from 'react';
import {BaseOption} from '@components/common_post_options';
-import {Screens} from '@constants';
import {SNACK_BAR_TYPE} from '@constants/snack_bar';
import {useServerUrl} from '@context/server';
import {t} from '@i18n';
@@ -13,10 +12,11 @@ import {dismissBottomSheet} from '@screens/navigation';
import {showSnackBar} from '@utils/snack_bar';
import type PostModel from '@typings/database/models/servers/post';
+import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
- sourceScreen: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
+ sourceScreen: AvailableScreens;
post: PostModel;
teamName: string;
}
diff --git a/app/components/common_post_options/follow_thread_option/follow_thread_option.tsx b/app/components/common_post_options/follow_thread_option/follow_thread_option.tsx
index 6791dafdd9..475e55ea99 100644
--- a/app/components/common_post_options/follow_thread_option/follow_thread_option.tsx
+++ b/app/components/common_post_options/follow_thread_option/follow_thread_option.tsx
@@ -5,15 +5,15 @@ import React, {useCallback} from 'react';
import {updateThreadFollowing} from '@actions/remote/thread';
import {BaseOption} from '@components/common_post_options';
-import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
import type ThreadModel from '@typings/database/models/servers/thread';
+import type {AvailableScreens} from '@typings/screens/navigation';
type FollowThreadOptionProps = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
thread: ThreadModel;
teamId?: string;
};
diff --git a/app/components/common_post_options/reply_option.tsx b/app/components/common_post_options/reply_option.tsx
index 6afa518792..3741e358ba 100644
--- a/app/components/common_post_options/reply_option.tsx
+++ b/app/components/common_post_options/reply_option.tsx
@@ -5,16 +5,16 @@ import React, {useCallback} from 'react';
import {fetchAndSwitchToThread} from '@actions/remote/thread';
import {BaseOption} from '@components/common_post_options';
-import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
import type PostModel from '@typings/database/models/servers/post';
+import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
post: PostModel;
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
}
const ReplyOption = ({post, bottomSheetId}: Props) => {
const serverUrl = useServerUrl();
diff --git a/app/components/common_post_options/save_option.tsx b/app/components/common_post_options/save_option.tsx
index fcb0fd396a..1abe0a5436 100644
--- a/app/components/common_post_options/save_option.tsx
+++ b/app/components/common_post_options/save_option.tsx
@@ -5,13 +5,14 @@ import React, {useCallback} from 'react';
import {deleteSavedPost, savePostPreference} from '@actions/remote/preference';
import {BaseOption} from '@components/common_post_options';
-import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type CopyTextProps = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
isSaved: boolean;
postId: string;
}
diff --git a/app/components/custom_status/__snapshots__/clear_button.test.tsx.snap b/app/components/custom_status/__snapshots__/clear_button.test.tsx.snap
index 5f33922500..43b6af9005 100644
--- a/app/components/custom_status/__snapshots__/clear_button.test.tsx.snap
+++ b/app/components/custom_status/__snapshots__/clear_button.test.tsx.snap
@@ -2,6 +2,23 @@
exports[`components/custom_status/clear_button should match snapshot 1`] = `
{
let database: Database | undefined;
beforeAll(async () => {
diff --git a/app/components/emoji/index.tsx b/app/components/emoji/index.tsx
index 918f4bd23a..5fbe48f274 100644
--- a/app/components/emoji/index.tsx
+++ b/app/components/emoji/index.tsx
@@ -3,7 +3,7 @@
import React, {useMemo} from 'react';
-import {EmojiComponent, EmojiProps} from '@typings/components/emoji';
+import type {EmojiComponent, EmojiProps} from '@typings/components/emoji';
let emojiComponent: EmojiComponent;
diff --git a/app/components/files/document_file.tsx b/app/components/files/document_file.tsx
index 7c2f74a7fb..9ff052dd88 100644
--- a/app/components/files/document_file.tsx
+++ b/app/components/files/document_file.tsx
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {ClientResponse, ProgressPromise} from '@mattermost/react-native-network-client';
import React, {forwardRef, useImperativeHandle, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {Platform, StatusBar, StatusBarStyle, StyleSheet, TouchableOpacity, View} from 'react-native';
@@ -21,6 +20,7 @@ import {emptyFunction} from '@utils/general';
import FileIcon from './file_icon';
import type {Client} from '@client/rest';
+import type {ClientResponse, ProgressPromise} from '@mattermost/react-native-network-client';
export type DocumentFileRef = {
handlePreviewPress: () => void;
diff --git a/app/components/files/image_file.tsx b/app/components/files/image_file.tsx
index 0610a479fb..9146d05104 100644
--- a/app/components/files/image_file.tsx
+++ b/app/components/files/image_file.tsx
@@ -104,7 +104,8 @@ const ImageFile = ({
const props: ProgressiveImageProps = {};
if (file.localPath) {
- props.defaultSource = {uri: file.localPath};
+ const prefix = file.localPath.startsWith('file://') ? '' : 'file://';
+ props.defaultSource = {uri: prefix + file.localPath};
} else if (file.id) {
if (file.mini_preview && file.mime_type) {
props.thumbnailUri = `data:${file.mime_type};base64,${file.mini_preview}`;
diff --git a/app/components/illustrations/alert.tsx b/app/components/illustrations/alert.tsx
new file mode 100644
index 0000000000..44aaf0e6e5
--- /dev/null
+++ b/app/components/illustrations/alert.tsx
@@ -0,0 +1,30 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+import * as React from 'react';
+import Svg, {Path} from 'react-native-svg';
+
+function AlertSvgComponent() {
+ return (
+
+
+
+
+
+ );
+}
+
+export default AlertSvgComponent;
diff --git a/app/components/illustrations/error.tsx b/app/components/illustrations/error.tsx
new file mode 100644
index 0000000000..7dd1b636c7
--- /dev/null
+++ b/app/components/illustrations/error.tsx
@@ -0,0 +1,34 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+import * as React from 'react';
+import Svg, {G, Path, Defs, ClipPath, Rect} from 'react-native-svg';
+
+function ErrorSvgComponent() {
+ return (
+
+
+
+
+
+
+
+
+
+
+ );
+}
+
+export default ErrorSvgComponent;
diff --git a/app/components/illustrations/success.tsx b/app/components/illustrations/success.tsx
new file mode 100644
index 0000000000..ac5b3e1b18
--- /dev/null
+++ b/app/components/illustrations/success.tsx
@@ -0,0 +1,22 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+import * as React from 'react';
+import Svg, {Path} from 'react-native-svg';
+
+function SuccessSvgComponent() {
+ return (
+
+
+
+ );
+}
+
+export default SuccessSvgComponent;
diff --git a/app/components/loading_error/__snapshots__/index.test.tsx.snap b/app/components/loading_error/__snapshots__/index.test.tsx.snap
index 200e83f611..f03c8a4193 100644
--- a/app/components/loading_error/__snapshots__/index.test.tsx.snap
+++ b/app/components/loading_error/__snapshots__/index.test.tsx.snap
@@ -73,6 +73,23 @@ exports[`Loading Error should match snapshot 1`] = `
Error description
;
mentionName: string;
- mentionStyle: TextStyle;
+ mentionStyle: StyleProp;
onPostPress?: (e: GestureResponderEvent) => void;
teammateNameDisplay: string;
textStyle?: StyleProp;
@@ -203,7 +203,7 @@ const AtMention = ({
}
}, [managedConfig, intl, theme, bottom]);
- const mentionTextStyle = [];
+ const mentionTextStyle: StyleProp = [];
let backgroundColor;
let canPress = false;
diff --git a/app/components/markdown/markdown.tsx b/app/components/markdown/markdown.tsx
index 0437097154..b0182e885d 100644
--- a/app/components/markdown/markdown.tsx
+++ b/app/components/markdown/markdown.tsx
@@ -5,7 +5,7 @@ import {useManagedConfig} from '@mattermost/react-native-emm';
import {Parser, Node} from 'commonmark';
import Renderer from 'commonmark-react-renderer';
import React, {ReactElement, useMemo, useRef} from 'react';
-import {Dimensions, GestureResponderEvent, Platform, StyleProp, Text, TextStyle, View, ViewStyle} from 'react-native';
+import {Dimensions, GestureResponderEvent, Platform, StyleProp, StyleSheet, Text, TextStyle, View, ViewStyle} from 'react-native';
import CompassIcon from '@components/compass_icon';
import Emoji from '@components/emoji';
@@ -143,13 +143,15 @@ const Markdown = ({
if (disableAtMentions) {
return renderText({context, literal: `@${mentionName}`});
}
+ const computedStyles = StyleSheet.flatten(computeTextStyle(textStyles, baseTextStyle, context));
+ const {fontFamily, fontSize, fontWeight} = computedStyles;
return (
('default');
const [longMessageAlertShown, setLongMessageAlertShown] = useState(false);
const disableCopyAndPaste = managedConfig.copyAndPasteProtection === 'true';
@@ -180,11 +180,6 @@ export default function PostInput({
const handlePostDraftSelectionChanged = useCallback((event: NativeSyntheticEvent | null, fromHandleTextChange = false) => {
const cp = fromHandleTextChange ? cursorPosition : event!.nativeEvent.selection.end;
- if (Platform.OS === 'ios') {
- const newKeyboardType = switchKeyboardForCodeBlocks(value, cp);
- setKeyboardType(newKeyboardType);
- }
-
updateCursorPosition(cp);
}, [updateCursorPosition, cursorPosition]);
@@ -194,11 +189,6 @@ export default function PostInput({
checkMessageLength(newValue);
- // Workaround to avoid iOS emdash autocorrect in Code Blocks
- if (Platform.OS === 'ios') {
- handlePostDraftSelectionChanged(null, true);
- }
-
if (
newValue &&
lastTypingEventSent.current + timeBetweenUserTypingUpdatesMilliseconds < Date.now() &&
@@ -211,7 +201,6 @@ export default function PostInput({
}, [
updateValue,
checkMessageLength,
- handlePostDraftSelectionChanged,
timeBetweenUserTypingUpdatesMilliseconds,
channelId,
rootId,
@@ -228,7 +217,7 @@ export default function PostInput({
const handleHardwareEnterPress = useCallback((keyEvent: {pressedKey: string}) => {
const topScreen = NavigationStore.getVisibleScreen();
- let sourceScreen = Screens.CHANNEL;
+ let sourceScreen: AvailableScreens = Screens.CHANNEL;
if (rootId) {
sourceScreen = Screens.THREAD;
} else if (isTablet) {
@@ -307,24 +296,24 @@ export default function PostInput({
return (
);
}
diff --git a/app/components/post_draft/quick_actions/camera_quick_action/camera_type.tsx b/app/components/post_draft/quick_actions/camera_quick_action/camera_type.tsx
index c42eccb1d4..e681c7a566 100644
--- a/app/components/post_draft/quick_actions/camera_quick_action/camera_type.tsx
+++ b/app/components/post_draft/quick_actions/camera_quick_action/camera_type.tsx
@@ -4,7 +4,6 @@
import React from 'react';
import {useIntl} from 'react-intl';
import {View} from 'react-native';
-import {CameraOptions} from 'react-native-image-picker';
import FormattedText from '@components/formatted_text';
import SlideUpPanelItem from '@components/slide_up_panel_item';
@@ -14,6 +13,8 @@ import {dismissBottomSheet} from '@screens/navigation';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {CameraOptions} from 'react-native-image-picker';
+
type Props = {
onPress: (options: CameraOptions) => void;
}
diff --git a/app/components/post_draft/quick_actions/camera_quick_action/index.tsx b/app/components/post_draft/quick_actions/camera_quick_action/index.tsx
index f13817be11..cfba22fdf1 100644
--- a/app/components/post_draft/quick_actions/camera_quick_action/index.tsx
+++ b/app/components/post_draft/quick_actions/camera_quick_action/index.tsx
@@ -4,7 +4,6 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
import {Alert, StyleSheet} from 'react-native';
-import {CameraOptions} from 'react-native-image-picker';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import CompassIcon from '@components/compass_icon';
@@ -22,6 +21,7 @@ import {changeOpacity} from '@utils/theme';
import CameraType from './camera_type';
import type {QuickActionAttachmentProps} from '@typings/components/post_draft_quick_action';
+import type {CameraOptions} from 'react-native-image-picker';
const style = StyleSheet.create({
icon: {
diff --git a/app/components/post_draft/send_handler/send_handler.tsx b/app/components/post_draft/send_handler/send_handler.tsx
index 97c7e7e696..7c8c4b4a81 100644
--- a/app/components/post_draft/send_handler/send_handler.tsx
+++ b/app/components/post_draft/send_handler/send_handler.tsx
@@ -3,15 +3,14 @@
import React, {useCallback, useEffect, useState} from 'react';
import {useIntl} from 'react-intl';
-import {Alert, DeviceEventEmitter} from 'react-native';
+import {DeviceEventEmitter} from 'react-native';
import {getChannelTimezones} from '@actions/remote/channel';
import {executeCommand, handleGotoLocation} from '@actions/remote/command';
import {createPost} from '@actions/remote/post';
import {handleReactionToLatestPost} from '@actions/remote/reactions';
import {setStatus} from '@actions/remote/user';
-import {canEndCall, endCall, getEndCallMessage} from '@calls/actions/calls';
-import ClientError from '@client/rest/error';
+import {handleCallsSlashCommand} from '@calls/actions/calls';
import {Events, Screens} from '@constants';
import {PostPriorityType} from '@constants/post';
import {NOTIFY_ALL_MEMBERS} from '@constants/post_draft';
@@ -147,54 +146,19 @@ export default function SendHandler({
DraftUtils.alertChannelWideMention(intl, notifyAllMessage, doSubmitMessage, cancel);
}, [intl, isTimezoneEnabled, channelTimezoneCount, doSubmitMessage]);
- const handleEndCall = useCallback(async () => {
- const hasPermissions = await canEndCall(serverUrl, channelId);
-
- if (!hasPermissions) {
- Alert.alert(
- intl.formatMessage({
- id: 'mobile.calls_end_permission_title',
- defaultMessage: 'Error',
- }),
- intl.formatMessage({
- id: 'mobile.calls_end_permission_msg',
- defaultMessage: 'You don\'t have permission to end the call. Please ask the call owner to end the call.',
- }));
- return;
- }
-
- const message = await getEndCallMessage(serverUrl, channelId, currentUserId, intl);
- const title = intl.formatMessage({id: 'mobile.calls_end_call_title', defaultMessage: 'End call'});
-
- Alert.alert(
- title,
- message,
- [
- {
- text: intl.formatMessage({id: 'mobile.post.cancel', defaultMessage: 'Cancel'}),
- },
- {
- text: title,
- onPress: async () => {
- try {
- await endCall(serverUrl, channelId);
- } catch (e) {
- const err = (e as ClientError).message || 'unable to complete command, see server logs';
- Alert.alert('Error', `Error: ${err}`);
- }
- },
- style: 'cancel',
- },
- ],
- );
- }, [serverUrl, channelId, currentUserId, intl]);
-
const sendCommand = useCallback(async () => {
- if (value.trim() === '/call end') {
- await handleEndCall();
- setSendingMessage(false);
- clearDraft();
- return;
+ if (value.trim().startsWith('/call')) {
+ const {handled, error} = await handleCallsSlashCommand(value.trim(), serverUrl, channelId, currentUserId, intl);
+ if (handled) {
+ setSendingMessage(false);
+ clearDraft();
+ return;
+ }
+ if (error) {
+ setSendingMessage(false);
+ DraftUtils.alertSlashCommandFailed(intl, error);
+ return;
+ }
}
const status = DraftUtils.getStatusFromSlashCommand(value);
@@ -226,7 +190,7 @@ export default function SendHandler({
if (data?.goto_location && !value.startsWith('/leave')) {
handleGotoLocation(serverUrl, intl, data.goto_location);
}
- }, [userIsOutOfOffice, currentUserId, intl, value, serverUrl, channelId, rootId, handleEndCall]);
+ }, [userIsOutOfOffice, currentUserId, intl, value, serverUrl, channelId, rootId]);
const sendMessage = useCallback(() => {
const notificationsToChannel = enableConfirmNotificationsToChannel && useChannelMentions;
diff --git a/app/components/post_list/more_messages/more_messages.tsx b/app/components/post_list/more_messages/more_messages.tsx
index 835ce0c6be..e1d438c146 100644
--- a/app/components/post_list/more_messages/more_messages.tsx
+++ b/app/components/post_list/more_messages/more_messages.tsx
@@ -46,7 +46,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
animatedContainer: {
position: 'absolute',
margin: 8,
- backgroundColor: theme.buttonBg,
},
cancelContainer: {
alignItems: 'center',
@@ -55,6 +54,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
justifyContent: 'center',
},
container: {
+ backgroundColor: theme.buttonBg,
flexDirection: 'row',
justifyContent: 'space-evenly',
alignItems: 'center',
diff --git a/app/components/post_list/post/body/content/embedded_bindings/button_binding/index.tsx b/app/components/post_list/post/body/content/embedded_bindings/button_binding/index.tsx
index 117098c75e..68efc1418c 100644
--- a/app/components/post_list/post/body/content/embedded_bindings/button_binding/index.tsx
+++ b/app/components/post_list/post/body/content/embedded_bindings/button_binding/index.tsx
@@ -132,8 +132,6 @@ const ButtonBinding = ({currentTeamId, binding, post, teamID, theme}: Props) =>
/>
);
-
- return null;
};
const withTeamId = withObservables(['post'], ({post, database}: {post: PostModel} & WithDatabaseArgs) => ({
diff --git a/app/components/post_list/post/body/content/image_preview/image_preview.tsx b/app/components/post_list/post/body/content/image_preview/image_preview.tsx
index 8285e40e22..14b5042347 100644
--- a/app/components/post_list/post/body/content/image_preview/image_preview.tsx
+++ b/app/components/post_list/post/body/content/image_preview/image_preview.tsx
@@ -69,8 +69,9 @@ const ImagePreview = ({expandedLink, isReplyPost, layoutWidth, link, location, m
width: imageProps.width,
height: imageProps.height,
name: extractFilenameFromUrl(imageUrl) || 'imagePreview.png',
- mime_type: lookupMimeType(imageUrl) || 'images/png',
+ mime_type: lookupMimeType(imageUrl) || 'image/png',
type: 'image',
+ lastPictureUpdate: 0,
};
openGalleryAtIndex(galleryIdentifier, 0, [item]);
};
diff --git a/app/components/post_list/post/body/content/message_attachments/attachment_image/index.tsx b/app/components/post_list/post/body/content/message_attachments/attachment_image/index.tsx
index 321c1af05f..2d7f5ef225 100644
--- a/app/components/post_list/post/body/content/message_attachments/attachment_image/index.tsx
+++ b/app/components/post_list/post/body/content/message_attachments/attachment_image/index.tsx
@@ -72,8 +72,9 @@ const AttachmentImage = ({imageUrl, imageMetadata, layoutWidth, location, postId
width: imageMetadata.width,
height: imageMetadata.height,
name: extractFilenameFromUrl(imageUrl) || 'attachmentImage.png',
- mime_type: lookupMimeType(imageUrl) || 'images/png',
+ mime_type: lookupMimeType(imageUrl) || 'image/png',
type: 'image',
+ lastPictureUpdate: 0,
};
openGalleryAtIndex(galleryIdentifier, 0, [item]);
};
diff --git a/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx b/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx
index be80402004..a895b665d3 100644
--- a/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx
+++ b/app/components/post_list/post/body/content/opengraph/opengraph_image/index.tsx
@@ -98,8 +98,9 @@ const OpengraphImage = ({isReplyPost, layoutWidth, location, metadata, openGraph
width: imageDimensions.width,
height: imageDimensions.height,
name: extractFilenameFromUrl(imageUrl) || 'openGraph.png',
- mime_type: lookupMimeType(imageUrl) || 'images/png',
+ mime_type: lookupMimeType(imageUrl) || 'image/png',
type: 'image',
+ lastPictureUpdate: 0,
};
openGalleryAtIndex(galleryIdentifier, 0, [item]);
};
diff --git a/app/components/profile_picture/image.tsx b/app/components/profile_picture/image.tsx
index 229012db89..482812883a 100644
--- a/app/components/profile_picture/image.tsx
+++ b/app/components/profile_picture/image.tsx
@@ -43,6 +43,7 @@ const Image = ({author, forwardRef, iconSize, size, source, url}: Props) => {
const style = getStyleSheet(theme);
const fIStyle = useMemo(() => ({
borderRadius: size / 2,
+ backgroundColor: theme.centerChannelBg,
height: size,
width: size,
}), [size]);
diff --git a/app/components/progressive_image/thumbnail.tsx b/app/components/progressive_image/thumbnail.tsx
index 6ace4800f1..620dc33491 100644
--- a/app/components/progressive_image/thumbnail.tsx
+++ b/app/components/progressive_image/thumbnail.tsx
@@ -2,10 +2,11 @@
// See LICENSE.txt for license information.
import React from 'react';
-import {ColorValue, StyleProp} from 'react-native';
import FastImage, {ImageStyle, Source} from 'react-native-fast-image';
import Animated, {SharedValue} from 'react-native-reanimated';
+import type {ColorValue, StyleProp} from 'react-native';
+
// @ts-expect-error FastImage does work with Animated.createAnimatedComponent
const AnimatedFastImage = Animated.createAnimatedComponent(FastImage);
diff --git a/app/components/selected_chip/index.tsx b/app/components/selected_chip/index.tsx
new file mode 100644
index 0000000000..3ea8e221dd
--- /dev/null
+++ b/app/components/selected_chip/index.tsx
@@ -0,0 +1,100 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {useCallback} from 'react';
+import {Text, TouchableOpacity, View} from 'react-native';
+import Animated, {FadeIn, FadeOut} from 'react-native-reanimated';
+
+import CompassIcon from '@components/compass_icon';
+import {useTheme} from '@context/theme';
+import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
+import {typography} from '@utils/typography';
+
+type SelectedChipProps = {
+ id: string;
+ text: string;
+ extra?: React.ReactNode;
+ onRemove: (id: string) => void;
+ testID?: string;
+}
+
+export const USER_CHIP_HEIGHT = 32;
+export const USER_CHIP_BOTTOM_MARGIN = 8;
+const FADE_DURATION = 100;
+
+const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
+ return {
+ container: {
+ alignItems: 'center',
+ justifyContent: 'center',
+ flexDirection: 'row',
+ borderRadius: 16,
+ height: USER_CHIP_HEIGHT,
+ backgroundColor: changeOpacity(theme.centerChannelColor, 0.08),
+ marginBottom: USER_CHIP_BOTTOM_MARGIN,
+ marginRight: 8,
+ paddingHorizontal: 7,
+ },
+ extraContent: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ color: theme.centerChannelColor,
+ },
+ text: {
+ marginLeft: 8,
+ color: theme.centerChannelColor,
+ ...typography('Body', 100, 'SemiBold'),
+ },
+ remove: {
+ justifyContent: 'center',
+ marginLeft: 7,
+ },
+ };
+});
+
+export default function SelectedChip({
+ id,
+ text,
+ extra,
+ onRemove,
+ testID,
+}: SelectedChipProps) {
+ const theme = useTheme();
+ const style = getStyleFromTheme(theme);
+
+ const onPress = useCallback(() => {
+ onRemove(id);
+ }, [onRemove, id]);
+
+ return (
+
+ {extra && (
+
+ {extra}
+
+ )}
+
+ {text}
+
+
+
+
+
+ );
+}
diff --git a/app/components/selected_users/index.tsx b/app/components/selected_users/index.tsx
index e2ffad6f76..feac09143c 100644
--- a/app/components/selected_users/index.tsx
+++ b/app/components/selected_users/index.tsx
@@ -6,6 +6,7 @@ import {LayoutChangeEvent, Platform, ScrollView, useWindowDimensions, View} from
import Animated, {useAnimatedStyle, useDerivedValue, useSharedValue, withTiming} from 'react-native-reanimated';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
+import {USER_CHIP_BOTTOM_MARGIN, USER_CHIP_HEIGHT} from '@components/selected_chip';
import Toast from '@components/toast';
import {General} from '@constants';
import {useTheme} from '@context/theme';
@@ -13,7 +14,7 @@ import {useIsTablet, useKeyboardHeightWithDuration} from '@hooks/device';
import Button from '@screens/bottom_sheet/button';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
-import SelectedUser, {USER_CHIP_BOTTOM_MARGIN, USER_CHIP_HEIGHT} from './selected_user';
+import SelectedUser from './selected_user';
type Props = {
@@ -95,6 +96,7 @@ const TOAST_BOTTOM_MARGIN = 24;
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
return {
container: {
+ backgroundColor: theme.centerChannelBg,
borderBottomWidth: 0,
borderColor: changeOpacity(theme.centerChannelColor, 0.16),
borderTopLeftRadius: 12,
@@ -231,10 +233,10 @@ export default function SelectedUsers({
}, [showToast, keyboard]);
const animatedViewStyle = useAnimatedStyle(() => ({
- height: withTiming(totalPanelHeight.value, {duration: 250}),
+ height: withTiming(totalPanelHeight.value + insets.bottom, {duration: 250}),
borderWidth: isVisible ? 1 : 0,
- maxHeight: isVisible ? PANEL_MAX_HEIGHT + BUTTON_HEIGHT : 0,
- }), [totalPanelHeight.value, isVisible]);
+ maxHeight: isVisible ? PANEL_MAX_HEIGHT + BUTTON_HEIGHT + insets.bottom : 0,
+ }), [isVisible, insets]);
const animatedButtonStyle = useAnimatedStyle(() => ({
opacity: withTiming(isVisible ? 1 : 0, {duration: isVisible ? 500 : 100}),
diff --git a/app/components/selected_users/selected_user.tsx b/app/components/selected_users/selected_user.tsx
index 03ecd506c6..c5d7cebe20 100644
--- a/app/components/selected_users/selected_user.tsx
+++ b/app/components/selected_users/selected_user.tsx
@@ -3,18 +3,9 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
-import {
- Text,
- TouchableOpacity,
- View,
-} from 'react-native';
-import Animated, {FadeIn, FadeOut} from 'react-native-reanimated';
-import CompassIcon from '@components/compass_icon';
import ProfilePicture from '@components/profile_picture';
-import {useTheme} from '@context/theme';
-import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
-import {typography} from '@utils/typography';
+import SelectedChip from '@components/selected_chip';
import {displayUsername} from '@utils/user';
type Props = {
@@ -40,87 +31,34 @@ type Props = {
testID?: string;
}
-export const USER_CHIP_HEIGHT = 32;
-export const USER_CHIP_BOTTOM_MARGIN = 8;
-const FADE_DURATION = 100;
-
-const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
- return {
- container: {
- alignItems: 'center',
- justifyContent: 'center',
- flexDirection: 'row',
- borderRadius: 16,
- height: USER_CHIP_HEIGHT,
- backgroundColor: changeOpacity(theme.centerChannelColor, 0.08),
- marginBottom: USER_CHIP_BOTTOM_MARGIN,
- marginRight: 8,
- paddingHorizontal: 7,
- },
- remove: {
- justifyContent: 'center',
- marginLeft: 7,
- },
- profileContainer: {
- flexDirection: 'row',
- alignItems: 'center',
- marginRight: 8,
- color: theme.centerChannelColor,
- },
- text: {
- color: theme.centerChannelColor,
- ...typography('Body', 100, 'SemiBold'),
- },
- };
-});
-
export default function SelectedUser({
teammateNameDisplay,
user,
onRemove,
testID,
}: Props) {
- const theme = useTheme();
- const style = getStyleFromTheme(theme);
const intl = useIntl();
- const onPress = useCallback(() => {
- onRemove(user.id);
- }, [onRemove, user.id]);
+ const onPress = useCallback((id: string) => {
+ onRemove(id);
+ }, [onRemove]);
const userItemTestID = `${testID}.${user.id}`;
+
return (
-
-
+
-
-
- {displayUsername(user, intl.locale, teammateNameDisplay)}
-
-
-
-
-
+ )}
+ onRemove={onPress}
+ testID={userItemTestID}
+ />
);
}
diff --git a/app/components/server_icon/__snapshots__/server_icon.test.tsx.snap b/app/components/server_icon/__snapshots__/server_icon.test.tsx.snap
index f6c642aa86..55309659d9 100644
--- a/app/components/server_icon/__snapshots__/server_icon.test.tsx.snap
+++ b/app/components/server_icon/__snapshots__/server_icon.test.tsx.snap
@@ -5,7 +5,19 @@ exports[`Server Icon Server Icon Component should match snapshot 1`] = `
;
diff --git a/app/components/syntax_highlight/renderer.tsx b/app/components/syntax_highlight/renderer.tsx
index 71c45d3109..055e7af2e0 100644
--- a/app/components/syntax_highlight/renderer.tsx
+++ b/app/components/syntax_highlight/renderer.tsx
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React, {useCallback} from 'react';
+import React, {useCallback, useRef} from 'react';
import {FlatList, ListRenderItemInfo, ScrollView, StyleSheet, Text} from 'react-native';
import {createStyleObject} from 'react-syntax-highlighter/create-element';
@@ -115,6 +115,7 @@ function createNativeElement({node, stylesheet, key, defaultColor, fontFamily, f
}
const CodeHighlightRenderer = ({defaultColor, digits, fontFamily, fontSize, rows, selectable, stylesheet}: Props) => {
+ const listKey = useRef(generateId()).current;
const renderItem = useCallback(({item, index}: ListRenderItemInfo) => {
return createNativeElement({
node: item,
@@ -137,7 +138,9 @@ const CodeHighlightRenderer = ({defaultColor, digits, fontFamily, fontSize, rows
);
diff --git a/app/components/threads_button/__snapshots__/threads_button.test.tsx.snap b/app/components/threads_button/__snapshots__/threads_button.test.tsx.snap
index c7b564c6f8..c07f7a3829 100644
--- a/app/components/threads_button/__snapshots__/threads_button.test.tsx.snap
+++ b/app/components/threads_button/__snapshots__/threads_button.test.tsx.snap
@@ -2,6 +2,23 @@
exports[`Thread item in the channel list Threads Component should match snapshot 1`] = `
{
const currentTeamId = observeCurrentTeamId(database);
diff --git a/app/components/touchable_with_feedback/touchable_with_feedback.android.tsx b/app/components/touchable_with_feedback/touchable_with_feedback.android.tsx
index e815745386..36f166bccb 100644
--- a/app/components/touchable_with_feedback/touchable_with_feedback.android.tsx
+++ b/app/components/touchable_with_feedback/touchable_with_feedback.android.tsx
@@ -40,7 +40,7 @@ const TouchableWithFeedbackAndroid = ({borderlessRipple = false, children, rippl
{children}
);
- case 'none':
+ default:
return (
);
}
-
- return null;
};
export default memo(TouchableWithFeedbackAndroid);
diff --git a/app/components/touchable_with_feedback/touchable_with_feedback.ios.tsx b/app/components/touchable_with_feedback/touchable_with_feedback.ios.tsx
index 0199eafbf8..170cda20df 100644
--- a/app/components/touchable_with_feedback/touchable_with_feedback.ios.tsx
+++ b/app/components/touchable_with_feedback/touchable_with_feedback.ios.tsx
@@ -41,7 +41,7 @@ const TouchableWithFeedbackIOS = ({testID, children, type = 'native', cancelTouc
{children}
);
- case 'none':
+ default:
return (
);
}
-
- return null;
};
export default memo(TouchableWithFeedbackIOS);
diff --git a/app/components/tutorial_highlight/index.tsx b/app/components/tutorial_highlight/index.tsx
index e83fcfa84b..182ad6e6e6 100644
--- a/app/components/tutorial_highlight/index.tsx
+++ b/app/components/tutorial_highlight/index.tsx
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React, {useEffect, useState} from 'react';
+import React, {useCallback} from 'react';
import {Modal, StyleSheet, useWindowDimensions, View} from 'react-native';
import HighlightItem from './item';
@@ -11,45 +11,43 @@ type Props = {
itemBounds: TutorialItemBounds;
itemBorderRadius?: number;
onDismiss: () => void;
+ onLayout: () => void;
onShow?: () => void;
}
-const TutorialHighlight = ({children, itemBounds, itemBorderRadius, onDismiss, onShow}: Props) => {
+const TutorialHighlight = ({children, itemBounds, itemBorderRadius, onDismiss, onLayout, onShow}: Props) => {
const {width, height} = useWindowDimensions();
- const [visible, setIsVisible] = useState(false);
- const isLandscape = width > height;
- const supportedOrientations = isLandscape ? 'landscape' : 'portrait';
- useEffect(() => {
- const t = setTimeout(() => {
- setIsVisible(true);
- }, 500);
-
- return () => clearTimeout(t);
- }, []);
+ const handleShowTutorial = useCallback(() => {
+ if (onShow) {
+ setTimeout(onShow, 1000);
+ }
+ }, [itemBounds]);
return (
+ {itemBounds.endX > 0 &&
+ }
{children}
);
diff --git a/app/components/tutorial_highlight/item.tsx b/app/components/tutorial_highlight/item.tsx
index de98bb12ae..dc96f45f50 100644
--- a/app/components/tutorial_highlight/item.tsx
+++ b/app/components/tutorial_highlight/item.tsx
@@ -14,22 +14,24 @@ type Props = {
height: number;
itemBounds: TutorialItemBounds;
onDismiss: () => void;
+ onLayout: () => void;
width: number;
}
-const HighlightItem = ({height, itemBounds, onDismiss, borderRadius = 0, width}: Props) => {
+const HighlightItem = ({height, itemBounds, onDismiss, onLayout, borderRadius = 0, width}: Props) => {
const theme = useTheme();
const isDark = tinyColor(theme.centerChannelBg).isDark();
const pathD = useMemo(() => {
const parent = {startX: 0, startY: 0, endX: width, endY: height};
return constructRectangularPathWithBorderRadius(parent, itemBounds, borderRadius);
- }, [borderRadius, itemBounds, width]);
+ }, [borderRadius, itemBounds, width, height]);
return (
diff --git a/app/components/user_avatars_stack/index.tsx b/app/components/user_avatars_stack/index.tsx
index 1e084d8546..8ea5efeea2 100644
--- a/app/components/user_avatars_stack/index.tsx
+++ b/app/components/user_avatars_stack/index.tsx
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {BottomSheetProps} from '@gorhom/bottom-sheet';
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
import {StyleProp, Text, TouchableOpacity, View, ViewStyle} from 'react-native';
@@ -20,6 +19,7 @@ import {typography} from '@utils/typography';
import UserAvatar from './user_avatar';
import UsersList from './users_list';
+import type {BottomSheetProps} from '@gorhom/bottom-sheet';
import type UserModel from '@typings/database/models/servers/user';
const OVERFLOW_DISPLAY_LIMIT = 99;
diff --git a/app/components/user_item/user_item.tsx b/app/components/user_item/user_item.tsx
index a16e3a443b..24c0812d78 100644
--- a/app/components/user_item/user_item.tsx
+++ b/app/components/user_item/user_item.tsx
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React from 'react';
+import React, {useMemo} from 'react';
import {IntlShape, useIntl} from 'react-intl';
import {StyleProp, Text, View, ViewStyle} from 'react-native';
@@ -81,7 +81,6 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme: Theme) => {
color: changeOpacity(theme.centerChannelColor, 0.64),
fontSize: 15,
fontFamily: 'OpenSans',
- flexShrink: 5,
},
icon: {
marginLeft: 4,
@@ -113,6 +112,19 @@ const UserItem = ({
const userItemTestId = `${testID}.${user?.id}`;
+ let rowUsernameFlexShrink = 1;
+ if (user) {
+ for (const rowInfoElem of [bot, guest, Boolean(name.length), isCurrentUser]) {
+ if (rowInfoElem) {
+ rowUsernameFlexShrink++;
+ }
+ }
+ }
+
+ const usernameTextStyle = useMemo(() => {
+ return [style.rowUsername, {flexShrink: rowUsernameFlexShrink}];
+ }, [user, rowUsernameFlexShrink]);
+
return (
{bot && }
{guest && }
@@ -148,15 +160,15 @@ const UserItem = ({
testID={`${userItemTestId}.current_user_indicator`}
/>
}
- {Boolean(user) &&
-
- {` @${user!.username}`}
-
- }
+ {Boolean(user) && (
+
+ {` @${user!.username}`}
+
+ )}
{Boolean(isCustomStatusEnabled && !bot && customStatus?.emoji && !customStatusExpired) && (
@@ -111,6 +112,7 @@ exports[`components/channel_list_row should show no results 1`] = `
@@ -129,6 +131,14 @@ exports[`components/channel_list_row should show no results 1`] = `
onStartShouldSetResponderCapture={[Function]}
>
@@ -346,6 +357,7 @@ exports[`components/channel_list_row should show results and tutorial 1`] = `
>
@@ -383,6 +395,7 @@ exports[`components/channel_list_row should show results and tutorial 1`] = `
@@ -401,6 +414,14 @@ exports[`components/channel_list_row should show results and tutorial 1`] = `
onStartShouldSetResponderCapture={[Function]}
>
+
+
+
+
+
+
+ Long-press on an item to view a user's profile
+
+
+
+
@@ -618,6 +720,7 @@ exports[`components/channel_list_row should show results no tutorial 1`] = `
>
@@ -655,6 +758,7 @@ exports[`components/channel_list_row should show results no tutorial 1`] = `
@@ -673,6 +777,14 @@ exports[`components/channel_list_row should show results no tutorial 1`] = `
onStartShouldSetResponderCapture={[Function]}
>
diff --git a/app/components/user_list/index.test.tsx b/app/components/user_list/index.test.tsx
index 26560b5351..122c491fda 100644
--- a/app/components/user_list/index.test.tsx
+++ b/app/components/user_list/index.test.tsx
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import Database from '@nozbe/watermelondb/Database';
import React from 'react';
import {renderWithEverything} from '@test/intl-test-helper';
@@ -9,6 +8,8 @@ import TestHelper from '@test/test_helper';
import UserList from '.';
+import type Database from '@nozbe/watermelondb/Database';
+
describe('components/channel_list_row', () => {
let database: Database;
const user: UserProfile = {
diff --git a/app/components/user_list_row/index.tsx b/app/components/user_list_row/index.tsx
index 94c5c27777..b908e17a02 100644
--- a/app/components/user_list_row/index.tsx
+++ b/app/components/user_list_row/index.tsx
@@ -4,6 +4,7 @@
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {
+ InteractionManager,
Platform,
Text,
View,
@@ -122,13 +123,12 @@ function UserListRow({
const startTutorial = () => {
viewRef.current?.measureInWindow((x, y, w, h) => {
const bounds: TutorialItemBounds = {
- startX: x - 20,
+ startX: x,
startY: y,
endX: x + w,
endY: y + h,
};
if (viewRef.current) {
- setShowTutorial(true);
setItemBounds(bounds);
}
});
@@ -140,12 +140,16 @@ function UserListRow({
}, []);
useEffect(() => {
- let time: NodeJS.Timeout;
if (highlight && !tutorialWatched) {
- time = setTimeout(startTutorial, 650);
+ if (isTablet) {
+ setShowTutorial(true);
+ return;
+ }
+ InteractionManager.runAfterInteractions(() => {
+ setShowTutorial(true);
+ });
}
- return () => clearTimeout(time);
- }, [highlight, tutorialWatched]);
+ }, [highlight, tutorialWatched, isTablet]);
const handlePress = useCallback(() => {
onPress?.(user);
@@ -155,6 +159,10 @@ function UserListRow({
onLongPress?.(user);
}, [onLongPress, user]);
+ const onLayout = useCallback(() => {
+ startTutorial();
+ }, []);
+
const icon = useMemo(() => {
if (!selectable) {
return null;
@@ -256,6 +264,7 @@ function UserListRow({
= {
SYSTEM_AUTO_RESPONDER: 'system_auto_responder',
CUSTOM_CALLS: 'custom_calls',
+ CUSTOM_CALLS_RECORDING: 'custom_calls_recording',
};
export const PostPriorityColors = {
diff --git a/app/constants/screens.ts b/app/constants/screens.ts
index f3a2d7b3da..244d7fbc63 100644
--- a/app/constants/screens.ts
+++ b/app/constants/screens.ts
@@ -29,6 +29,7 @@ export const GLOBAL_THREADS = 'GlobalThreads';
export const HOME = 'Home';
export const INTEGRATION_SELECTOR = 'IntegrationSelector';
export const INTERACTIVE_DIALOG = 'InteractiveDialog';
+export const INVITE = 'Invite';
export const IN_APP_NOTIFICATION = 'InAppNotification';
export const JOIN_TEAM = 'JoinTeam';
export const LATEX = 'Latex';
@@ -96,6 +97,7 @@ export default {
HOME,
INTEGRATION_SELECTOR,
INTERACTIVE_DIALOG,
+ INVITE,
IN_APP_NOTIFICATION,
JOIN_TEAM,
LATEX,
@@ -133,7 +135,7 @@ export default {
THREAD_FOLLOW_BUTTON,
THREAD_OPTIONS,
USER_PROFILE,
-};
+} as const;
export const MODAL_SCREENS_WITHOUT_BACK = new Set([
BROWSE_CHANNELS,
@@ -146,6 +148,7 @@ export const MODAL_SCREENS_WITHOUT_BACK = new Set([
EDIT_SERVER,
FIND_CHANNELS,
GALLERY,
+ INVITE,
PERMALINK,
]);
diff --git a/app/constants/server_errors.ts b/app/constants/server_errors.ts
index 9799970b70..39810710d1 100644
--- a/app/constants/server_errors.ts
+++ b/app/constants/server_errors.ts
@@ -5,5 +5,6 @@ export default {
DELETED_ROOT_POST_ERROR: 'api.post.create_post.root_id.app_error',
TOWN_SQUARE_READ_ONLY_ERROR: 'api.post.create_post.town_square_read_only',
PLUGIN_DISMISSED_POST_ERROR: 'plugin.message_will_be_posted.dismiss_post',
+ SEND_EMAIL_WITH_DEFAULTS_ERROR: 'api.team.invite_members.unable_to_send_email_with_defaults.app_error',
TEAM_MEMBERSHIP_DENIAL_ERROR_ID: 'api.team.add_members.user_denied',
};
diff --git a/app/database/components/index.tsx b/app/database/components/index.tsx
index 0f22a50106..103c905544 100644
--- a/app/database/components/index.tsx
+++ b/app/database/components/index.tsx
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Database} from '@nozbe/watermelondb';
import DatabaseProvider from '@nozbe/watermelondb/DatabaseProvider';
import React, {ComponentType, useEffect, useState} from 'react';
@@ -11,6 +10,7 @@ import UserLocaleProvider from '@context/user_locale';
import DatabaseManager from '@database/manager';
import {subscribeActiveServers} from '@database/subscription/servers';
+import type {Database} from '@nozbe/watermelondb';
import type ServersModel from '@typings/database/models/app/servers';
type State = {
diff --git a/app/database/manager/__mocks__/index.ts b/app/database/manager/__mocks__/index.ts
index 0d38775cc8..a234993d1b 100644
--- a/app/database/manager/__mocks__/index.ts
+++ b/app/database/manager/__mocks__/index.ts
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Database, Q} from '@nozbe/watermelondb';
+import {Database, Model, Q} from '@nozbe/watermelondb';
import LokiJSAdapter from '@nozbe/watermelondb/adapters/lokijs';
import logger from '@nozbe/watermelondb/utils/common/logger';
import {DeviceEventEmitter, Platform} from 'react-native';
@@ -45,14 +45,14 @@ class DatabaseManager {
private readonly serverModels: Models;
constructor() {
- this.appModels = [InfoModel, GlobalModel, ServersModel];
+ this.appModels = [InfoModel, GlobalModel, ServersModel] as unknown[] as Model[];
this.serverModels = [
CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, ConfigModel, CustomEmojiModel, DraftModel, FileModel,
GroupModel, GroupChannelModel, GroupTeamModel, GroupMembershipModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
ThreadModel, ThreadParticipantModel, ThreadInTeamModel, TeamThreadsSyncModel, UserModel,
- ];
+ ] as unknown[] as Model[];
this.databaseDirectory = '';
}
diff --git a/app/database/manager/index.ts b/app/database/manager/index.ts
index 93eed0b393..a780522b7d 100644
--- a/app/database/manager/index.ts
+++ b/app/database/manager/index.ts
@@ -43,14 +43,14 @@ class DatabaseManager {
private readonly serverModels: Models;
constructor() {
- this.appModels = [InfoModel, GlobalModel, ServersModel];
+ this.appModels = [InfoModel, GlobalModel, ServersModel] as unknown[] as Models;
this.serverModels = [
CategoryModel, CategoryChannelModel, ChannelModel, ChannelInfoModel, ChannelMembershipModel, ConfigModel, CustomEmojiModel, DraftModel, FileModel,
GroupModel, GroupChannelModel, GroupTeamModel, GroupMembershipModel, MyChannelModel, MyChannelSettingsModel, MyTeamModel,
PostModel, PostsInChannelModel, PostsInThreadModel, PreferenceModel, ReactionModel, RoleModel,
SystemModel, TeamModel, TeamChannelHistoryModel, TeamMembershipModel, TeamSearchHistoryModel,
ThreadModel, ThreadParticipantModel, ThreadInTeamModel, TeamThreadsSyncModel, UserModel,
- ];
+ ] as unknown[] as Models;
this.databaseDirectory = Platform.OS === 'ios' ? getIOSAppGroupDetails().appGroupDatabase : `${FileSystem.DocumentDirectoryPath}/databases/`;
}
diff --git a/app/database/models/server/category_channel.ts b/app/database/models/server/category_channel.ts
index 0db4942f21..287e24735f 100644
--- a/app/database/models/server/category_channel.ts
+++ b/app/database/models/server/category_channel.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation, relation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type CategoryModel from '@typings/database/models/servers/category';
import type CategoryChannelInterface from '@typings/database/models/servers/category_channel';
import type ChannelModel from '@typings/database/models/servers/channel';
diff --git a/app/database/models/server/channel.ts b/app/database/models/server/channel.ts
index cdb3768edd..89d41978fa 100644
--- a/app/database/models/server/channel.ts
+++ b/app/database/models/server/channel.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Query, Relation} from '@nozbe/watermelondb';
import {children, field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Query, Relation} from '@nozbe/watermelondb';
import type CategoryChannelModel from '@typings/database/models/servers/category_channel';
import type ChannelModelInterface from '@typings/database/models/servers/channel';
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
diff --git a/app/database/models/server/channel_info.ts b/app/database/models/server/channel_info.ts
index 8d5fdcdea1..f257268638 100644
--- a/app/database/models/server/channel_info.ts
+++ b/app/database/models/server/channel_info.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
import type ChannelInfoInterface from '@typings/database/models/servers/channel_info';
diff --git a/app/database/models/server/file.ts b/app/database/models/server/file.ts
index 2394dcf3b1..aa60518611 100644
--- a/app/database/models/server/file.ts
+++ b/app/database/models/server/file.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type FileModelInterface from '@typings/database/models/servers/file';
import type PostModel from '@typings/database/models/servers/post';
diff --git a/app/database/models/server/group_channel.ts b/app/database/models/server/group_channel.ts
index 8a5d7c4e2d..fa5717f949 100644
--- a/app/database/models/server/group_channel.ts
+++ b/app/database/models/server/group_channel.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
import type GroupModel from '@typings/database/models/servers/group';
import type GroupChannelInterface from '@typings/database/models/servers/group_channel';
diff --git a/app/database/models/server/group_membership.ts b/app/database/models/server/group_membership.ts
index 54d39e5479..f45c227702 100644
--- a/app/database/models/server/group_membership.ts
+++ b/app/database/models/server/group_membership.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type GroupModel from '@typings/database/models/servers/group';
import type GroupMembershipInterface from '@typings/database/models/servers/group_membership';
import type UserModel from '@typings/database/models/servers/user';
diff --git a/app/database/models/server/group_team.ts b/app/database/models/server/group_team.ts
index c2be191992..e8e5e6ff3b 100644
--- a/app/database/models/server/group_team.ts
+++ b/app/database/models/server/group_team.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type GroupModel from '@typings/database/models/servers/group';
import type GroupTeamInterface from '@typings/database/models/servers/group_team';
import type TeamModel from '@typings/database/models/servers/team';
diff --git a/app/database/models/server/my_channel.ts b/app/database/models/server/my_channel.ts
index ea01dfa3c2..a7a45ca9dd 100644
--- a/app/database/models/server/my_channel.ts
+++ b/app/database/models/server/my_channel.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
import type MyChannelModelInterface from '@typings/database/models/servers/my_channel';
import type MyChannelSettingsModel from '@typings/database/models/servers/my_channel_settings';
@@ -66,7 +66,6 @@ export default class MyChannelModel extends Model implements MyChannelModelInter
}
resetPreparedState() {
- // @ts-expect-error hack setting _preparedState
this._preparedState = null;
}
}
diff --git a/app/database/models/server/my_channel_settings.ts b/app/database/models/server/my_channel_settings.ts
index e96aafde86..59b82959b5 100644
--- a/app/database/models/server/my_channel_settings.ts
+++ b/app/database/models/server/my_channel_settings.ts
@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {immutableRelation, json} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
import {safeParseJSON} from '@utils/helpers';
+import type {Relation} from '@nozbe/watermelondb';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
import type MyChannelSettingsModelInterface from '@typings/database/models/servers/my_channel_settings';
diff --git a/app/database/models/server/my_team.ts b/app/database/models/server/my_team.ts
index cb606a453b..da1854b448 100644
--- a/app/database/models/server/my_team.ts
+++ b/app/database/models/server/my_team.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, relation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type MyTeamModelInterface from '@typings/database/models/servers/my_team';
import type TeamModel from '@typings/database/models/servers/team';
diff --git a/app/database/models/server/posts_in_channel.ts b/app/database/models/server/posts_in_channel.ts
index 8abda43f3a..aae9a54f3a 100644
--- a/app/database/models/server/posts_in_channel.ts
+++ b/app/database/models/server/posts_in_channel.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
import type PostsInChannelModelInterface from '@typings/database/models/servers/posts_in_channel';
diff --git a/app/database/models/server/posts_in_thread.ts b/app/database/models/server/posts_in_thread.ts
index 838122b085..8618a3aef6 100644
--- a/app/database/models/server/posts_in_thread.ts
+++ b/app/database/models/server/posts_in_thread.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type PostModel from '@typings/database/models/servers/post';
import type PostsInThreadModelInterface from '@typings/database/models/servers/posts_in_thread';
diff --git a/app/database/models/server/preference.ts b/app/database/models/server/preference.ts
index e04c990d04..a75b41a5ca 100644
--- a/app/database/models/server/preference.ts
+++ b/app/database/models/server/preference.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type PreferenceModelInterface from '@typings/database/models/servers/preference';
import type UserModel from '@typings/database/models/servers/user';
diff --git a/app/database/models/server/reaction.ts b/app/database/models/server/reaction.ts
index bc2dc0576e..be2fa78e8a 100644
--- a/app/database/models/server/reaction.ts
+++ b/app/database/models/server/reaction.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type PostModel from '@typings/database/models/servers/post';
import type ReactionModelInterface from '@typings/database/models/servers/reaction';
import type UserModel from '@typings/database/models/servers/user';
diff --git a/app/database/models/server/team_channel_history.ts b/app/database/models/server/team_channel_history.ts
index 547d8689b0..924f43b22f 100644
--- a/app/database/models/server/team_channel_history.ts
+++ b/app/database/models/server/team_channel_history.ts
@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {immutableRelation, json} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
import {safeParseJSON} from '@utils/helpers';
+import type {Relation} from '@nozbe/watermelondb';
import type TeamModel from '@typings/database/models/servers/team';
import type TeamChannelHistoryModelInterface from '@typings/database/models/servers/team_channel_history';
diff --git a/app/database/models/server/team_search_history.ts b/app/database/models/server/team_search_history.ts
index 1118cc7b25..41b88ec546 100644
--- a/app/database/models/server/team_search_history.ts
+++ b/app/database/models/server/team_search_history.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation, text} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type TeamModel from '@typings/database/models/servers/team';
import type TeamSearchHistoryModelInterface from '@typings/database/models/servers/team_search_history';
diff --git a/app/database/models/server/team_threads_sync.ts b/app/database/models/server/team_threads_sync.ts
index 9b5a8409f5..f999436622 100644
--- a/app/database/models/server/team_threads_sync.ts
+++ b/app/database/models/server/team_threads_sync.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type TeamModel from '@typings/database/models/servers/team';
import type TeamThreadsSyncModelInterface from '@typings/database/models/servers/team_threads_sync';
diff --git a/app/database/models/server/thread.ts b/app/database/models/server/thread.ts
index 0efdf678bd..2c7c50d24a 100644
--- a/app/database/models/server/thread.ts
+++ b/app/database/models/server/thread.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Query, Relation} from '@nozbe/watermelondb';
import {children, field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Query, Relation} from '@nozbe/watermelondb';
import type PostModel from '@typings/database/models/servers/post';
import type ThreadModelInterface from '@typings/database/models/servers/thread';
import type ThreadInTeamModel from '@typings/database/models/servers/thread_in_team';
diff --git a/app/database/models/server/thread_in_team.ts b/app/database/models/server/thread_in_team.ts
index 50373e0b15..8825d5979f 100644
--- a/app/database/models/server/thread_in_team.ts
+++ b/app/database/models/server/thread_in_team.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type TeamModel from '@typings/database/models/servers/team';
import type ThreadModel from '@typings/database/models/servers/thread';
import type ThreadInTeamModelInterface from '@typings/database/models/servers/thread_in_team';
diff --git a/app/database/models/server/thread_participant.ts b/app/database/models/server/thread_participant.ts
index a70f10bc83..07f3ad3cfc 100644
--- a/app/database/models/server/thread_participant.ts
+++ b/app/database/models/server/thread_participant.ts
@@ -1,12 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Relation} from '@nozbe/watermelondb';
import {field, immutableRelation} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
+import type {Relation} from '@nozbe/watermelondb';
import type ThreadModel from '@typings/database/models/servers/thread';
import type ThreadParticipantModelInterface from '@typings/database/models/servers/thread_participant';
import type UserModel from '@typings/database/models/servers/user';
diff --git a/app/database/models/server/user.ts b/app/database/models/server/user.ts
index 1dc48e0f2a..59d089e142 100644
--- a/app/database/models/server/user.ts
+++ b/app/database/models/server/user.ts
@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Query} from '@nozbe/watermelondb';
import {children, field, json} from '@nozbe/watermelondb/decorators';
import Model, {Associations} from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
import {safeParseJSON} from '@utils/helpers';
+import type {Query} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
import type ChannelMembershipModel from '@typings/database/models/servers/channel_membership';
import type PostModel from '@typings/database/models/servers/post';
diff --git a/app/database/operator/app_data_operator/transformers/test.ts b/app/database/operator/app_data_operator/transformers/test.ts
index c86517e106..944d80adb5 100644
--- a/app/database/operator/app_data_operator/transformers/test.ts
+++ b/app/database/operator/app_data_operator/transformers/test.ts
@@ -33,7 +33,7 @@ describe('** APP DATA TRANSFORMER **', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('InfoModel');
+ expect(preparedRecords!.collection.table).toBe('Info');
});
it('=> transformGlobalRecord: should return an array of type Global', async () => {
@@ -52,6 +52,6 @@ describe('** APP DATA TRANSFORMER **', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('GlobalModel');
+ expect(preparedRecords!.collection.table).toBe('Global');
});
});
diff --git a/app/database/operator/base_data_operator/index.ts b/app/database/operator/base_data_operator/index.ts
index 430b9a2915..78bc9b7491 100644
--- a/app/database/operator/base_data_operator/index.ts
+++ b/app/database/operator/base_data_operator/index.ts
@@ -11,7 +11,6 @@ import {
} from '@database/operator/utils/general';
import {logWarning} from '@utils/log';
-import type {WriterInterface} from '@nozbe/watermelondb/Database';
import type Model from '@nozbe/watermelondb/Model';
import type {
HandleRecordsArgs,
@@ -186,7 +185,7 @@ export default class BaseDataOperator {
async batchRecords(models: Model[]): Promise {
try {
if (models.length > 0) {
- await this.database.write(async (writer: WriterInterface) => {
+ await this.database.write(async (writer) => {
await writer.batch(...models);
});
}
diff --git a/app/database/operator/server_data_operator/handlers/category.test.ts b/app/database/operator/server_data_operator/handlers/category.test.ts
index c7773a6800..b2188aef33 100644
--- a/app/database/operator/server_data_operator/handlers/category.test.ts
+++ b/app/database/operator/server_data_operator/handlers/category.test.ts
@@ -8,7 +8,7 @@ import {
transformCategoryChannelRecord,
} from '@database/operator/server_data_operator/transformers/category';
-import ServerDataOperator from '..';
+import type ServerDataOperator from '..';
describe('*** Operator: Category Handlers tests ***', () => {
let operator: ServerDataOperator;
diff --git a/app/database/operator/server_data_operator/handlers/channel.test.ts b/app/database/operator/server_data_operator/handlers/channel.test.ts
index 4799f73aff..d3fe042478 100644
--- a/app/database/operator/server_data_operator/handlers/channel.test.ts
+++ b/app/database/operator/server_data_operator/handlers/channel.test.ts
@@ -15,7 +15,7 @@ import {
transformMyChannelSettingsRecord,
} from '@database/operator/server_data_operator/transformers/channel';
-import ServerDataOperator from '..';
+import type ServerDataOperator from '..';
describe('*** Operator: Channel Handlers tests ***', () => {
let operator: ServerDataOperator;
diff --git a/app/database/operator/server_data_operator/handlers/group.test.ts b/app/database/operator/server_data_operator/handlers/group.test.ts
index f967c0d887..30cf6c2034 100644
--- a/app/database/operator/server_data_operator/handlers/group.test.ts
+++ b/app/database/operator/server_data_operator/handlers/group.test.ts
@@ -8,7 +8,7 @@ import {
transformGroupRecord,
} from '@database/operator/server_data_operator/transformers/group';
-import ServerDataOperator from '..';
+import type ServerDataOperator from '..';
describe('*** Operator: Group Handlers tests ***', () => {
let operator: ServerDataOperator;
diff --git a/app/database/operator/server_data_operator/handlers/post.test.ts b/app/database/operator/server_data_operator/handlers/post.test.ts
index 69abea6a45..2d08b3b18b 100644
--- a/app/database/operator/server_data_operator/handlers/post.test.ts
+++ b/app/database/operator/server_data_operator/handlers/post.test.ts
@@ -9,7 +9,7 @@ import {buildDraftKey} from '@database/operator/server_data_operator/comparators
import {transformDraftRecord} from '@database/operator/server_data_operator/transformers/post';
import {createPostsChain} from '@database/operator/utils/post';
-import ServerDataOperator from '..';
+import type ServerDataOperator from '..';
Q.sortBy = jest.fn().mockImplementation((field) => {
return Q.where(field, Q.gte(0));
diff --git a/app/database/operator/server_data_operator/handlers/posts_in_channel.ts b/app/database/operator/server_data_operator/handlers/posts_in_channel.ts
index dc8d964f28..6bb8f80404 100644
--- a/app/database/operator/server_data_operator/handlers/posts_in_channel.ts
+++ b/app/database/operator/server_data_operator/handlers/posts_in_channel.ts
@@ -6,6 +6,7 @@ import {Q} from '@nozbe/watermelondb';
import {Database} from '@constants';
import {getPostListEdges} from '@database//operator/utils/post';
import {transformPostsInChannelRecord} from '@database/operator/server_data_operator/transformers/post';
+import {emptyFunction} from '@utils/general';
import {logWarning} from '@utils/log';
import type PostsInChannelModel from '@typings/database/models/servers/posts_in_channel';
@@ -42,7 +43,7 @@ const PostsInChannelHandler = (superclass: any) => class extends superclass {
for (const chunk of existingChunks) {
if (newChunk.earliest <= chunk.earliest && newChunk.latest >= chunk.latest) {
if (!prepareRecordsOnly) {
- newChunk.prepareUpdate();
+ newChunk.prepareUpdate(emptyFunction);
}
result.push(newChunk);
result.push(chunk.prepareDestroyPermanently());
diff --git a/app/database/operator/server_data_operator/handlers/reaction.test.ts b/app/database/operator/server_data_operator/handlers/reaction.test.ts
index 9cda5389c4..021d403509 100644
--- a/app/database/operator/server_data_operator/handlers/reaction.test.ts
+++ b/app/database/operator/server_data_operator/handlers/reaction.test.ts
@@ -2,7 +2,8 @@
// See LICENSE.txt for license information.
import DatabaseManager from '@database/manager';
-import ServerDataOperator from '@database/operator/server_data_operator';
+
+import type ServerDataOperator from '@database/operator/server_data_operator';
describe('*** Operator: User Handlers tests ***', () => {
let operator: ServerDataOperator;
diff --git a/app/database/operator/server_data_operator/handlers/team.test.ts b/app/database/operator/server_data_operator/handlers/team.test.ts
index 721414903f..ac01b78594 100644
--- a/app/database/operator/server_data_operator/handlers/team.test.ts
+++ b/app/database/operator/server_data_operator/handlers/team.test.ts
@@ -14,7 +14,7 @@ import {
transformTeamSearchHistoryRecord,
} from '@database/operator/server_data_operator/transformers/team';
-import ServerDataOperator from '..';
+import type ServerDataOperator from '..';
describe('*** Operator: Team Handlers tests ***', () => {
let operator: ServerDataOperator;
diff --git a/app/database/operator/server_data_operator/handlers/thread.test.ts b/app/database/operator/server_data_operator/handlers/thread.test.ts
index cacdf28c15..b7a987fb33 100644
--- a/app/database/operator/server_data_operator/handlers/thread.test.ts
+++ b/app/database/operator/server_data_operator/handlers/thread.test.ts
@@ -4,7 +4,7 @@
import DatabaseManager from '@database/manager';
import {transformThreadRecord, transformThreadParticipantRecord, transformThreadInTeamRecord, transformTeamThreadsSyncRecord} from '@database/operator/server_data_operator/transformers/thread';
-import ServerDataOperator from '..';
+import type ServerDataOperator from '..';
jest.mock('@database/operator/utils/thread', () => {
return {
diff --git a/app/database/operator/server_data_operator/handlers/thread.ts b/app/database/operator/server_data_operator/handlers/thread.ts
index 605e71827f..5cb71befe4 100644
--- a/app/database/operator/server_data_operator/handlers/thread.ts
+++ b/app/database/operator/server_data_operator/handlers/thread.ts
@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import {Q} from '@nozbe/watermelondb';
-import Model from '@nozbe/watermelondb/Model';
import {MM_TABLES} from '@constants/database';
import {
@@ -14,6 +13,7 @@ import {sanitizeThreadParticipants} from '@database/operator/utils/thread';
import {logWarning} from '@utils/log';
import type Database from '@nozbe/watermelondb/Database';
+import type Model from '@nozbe/watermelondb/Model';
import type {HandleThreadsArgs, HandleThreadParticipantsArgs} from '@typings/database/database';
import type ThreadModel from '@typings/database/models/servers/thread';
import type ThreadInTeamModel from '@typings/database/models/servers/thread_in_team';
diff --git a/app/database/operator/server_data_operator/handlers/user.test.ts b/app/database/operator/server_data_operator/handlers/user.test.ts
index 238329f624..18e8ed73ec 100644
--- a/app/database/operator/server_data_operator/handlers/user.test.ts
+++ b/app/database/operator/server_data_operator/handlers/user.test.ts
@@ -2,13 +2,14 @@
// See LICENSE.txt for license information.
import DatabaseManager from '@database/manager';
-import ServerDataOperator from '@database/operator/server_data_operator';
import {buildPreferenceKey} from '@database/operator/server_data_operator/comparators';
import {
transformPreferenceRecord,
transformUserRecord,
} from '@database/operator/server_data_operator/transformers/user';
+import type ServerDataOperator from '@database/operator/server_data_operator';
+
describe('*** Operator: User Handlers tests ***', () => {
let operator: ServerDataOperator;
diff --git a/app/database/operator/server_data_operator/transformers/category.test.ts b/app/database/operator/server_data_operator/transformers/category.test.ts
index 58930cbe25..7be88d50b6 100644
--- a/app/database/operator/server_data_operator/transformers/category.test.ts
+++ b/app/database/operator/server_data_operator/transformers/category.test.ts
@@ -34,7 +34,7 @@ describe('*** CATEGORY Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords.collection.modelClass.name).toBe('CategoryModel');
+ expect(preparedRecords.collection.table).toBe('Category');
});
it('=> transformCategoryChannelRecord: should return an array of type CategoryChannelModel', async () => {
@@ -58,6 +58,6 @@ describe('*** CATEGORY Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords.collection.modelClass.name).toBe('CategoryChannelModel');
+ expect(preparedRecords.collection.table).toBe('CategoryChannel');
});
});
diff --git a/app/database/operator/server_data_operator/transformers/channel.test.ts b/app/database/operator/server_data_operator/transformers/channel.test.ts
index 73f514d267..571bec3dc3 100644
--- a/app/database/operator/server_data_operator/transformers/channel.test.ts
+++ b/app/database/operator/server_data_operator/transformers/channel.test.ts
@@ -46,7 +46,7 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords.collection.modelClass.name).toBe('ChannelModel');
+ expect(preparedRecords.collection.table).toBe('Channel');
});
it('=> transformMyChannelSettingsRecord: should return an array of type MyChannelSettings', async () => {
@@ -82,7 +82,7 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('MyChannelSettingsModel');
+ expect(preparedRecords!.collection.table).toBe('MyChannelSettings');
});
it('=> transformChannelInfoRecord: should return an array of type ChannelInfo', async () => {
@@ -109,7 +109,7 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('ChannelInfoModel');
+ expect(preparedRecords!.collection.table).toBe('ChannelInfo');
});
it('=> transformMyChannelRecord: should return an array of type MyChannel', async () => {
@@ -138,7 +138,7 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('MyChannelModel');
+ expect(preparedRecords!.collection.table).toBe('MyChannel');
});
it('=> transformChannelMembershipRecord: should return an array of type ChannelMembership', async () => {
@@ -174,6 +174,6 @@ describe('*** CHANNEL Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('ChannelMembershipModel');
+ expect(preparedRecords!.collection.table).toBe('ChannelMembership');
});
});
diff --git a/app/database/operator/server_data_operator/transformers/general.test.ts b/app/database/operator/server_data_operator/transformers/general.test.ts
index ddf9cc2f64..12e25c6e1c 100644
--- a/app/database/operator/server_data_operator/transformers/general.test.ts
+++ b/app/database/operator/server_data_operator/transformers/general.test.ts
@@ -30,7 +30,7 @@ describe('*** Role Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('RoleModel');
+ expect(preparedRecords!.collection.table).toBe('Role');
});
});
@@ -51,7 +51,7 @@ describe('*** System Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('SystemModel');
+ expect(preparedRecords!.collection.table).toBe('System');
});
});
@@ -79,7 +79,7 @@ describe('*** CustomEmoj Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('CustomEmojiModel');
+ expect(preparedRecords!.collection.table).toBe('CustomEmoji');
});
});
diff --git a/app/database/operator/server_data_operator/transformers/group.test.ts b/app/database/operator/server_data_operator/transformers/group.test.ts
index 28a84f2695..8ec75765ad 100644
--- a/app/database/operator/server_data_operator/transformers/group.test.ts
+++ b/app/database/operator/server_data_operator/transformers/group.test.ts
@@ -29,6 +29,6 @@ describe('*** GROUP Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords.collection.modelClass.name).toBe('GroupModel');
+ expect(preparedRecords.collection.table).toBe('Group');
});
});
diff --git a/app/database/operator/server_data_operator/transformers/index.ts b/app/database/operator/server_data_operator/transformers/index.ts
index 611bfab74d..7e6d963c2d 100644
--- a/app/database/operator/server_data_operator/transformers/index.ts
+++ b/app/database/operator/server_data_operator/transformers/index.ts
@@ -1,11 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import Model from '@nozbe/watermelondb/Model';
-
import {OperationType} from '@constants/database';
-import type {TransformerArgs} from '@typings/database/database';
+import type Model from '@nozbe/watermelondb/Model';
+import type {PrepareBaseRecordArgs} from '@typings/database/database';
/**
* prepareBaseRecord: This is the last step for each operator and depending on the 'action', it will either prepare an
@@ -15,7 +14,7 @@ import type {TransformerArgs} from '@typings/database/database';
* @param {Database} operatorBase.database
* @param {string} operatorBase.tableName
* @param {RecordPair} operatorBase.value
- * @param {((TransformerArgs) => void)} operatorBase.generator
+ * @param {((PrepareBaseRecordArgs) => void)} operatorBase.generator
* @returns {Promise}
*/
export const prepareBaseRecord = async ({
@@ -24,10 +23,10 @@ export const prepareBaseRecord = async ({
tableName,
value,
fieldsMapper,
-}: TransformerArgs): Promise => {
+}: PrepareBaseRecordArgs): Promise => {
if (action === OperationType.UPDATE) {
const record = value.record as Model;
- return record.prepareUpdate(() => fieldsMapper!(record));
+ return record.prepareUpdate(() => fieldsMapper(record));
}
return database.collections.get(tableName!).prepareCreate(fieldsMapper);
diff --git a/app/database/operator/server_data_operator/transformers/post.test.ts b/app/database/operator/server_data_operator/transformers/post.test.ts
index 67eea50924..53bea8c62e 100644
--- a/app/database/operator/server_data_operator/transformers/post.test.ts
+++ b/app/database/operator/server_data_operator/transformers/post.test.ts
@@ -48,7 +48,7 @@ describe('*** POST Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('PostModel');
+ expect(preparedRecords!.collection.table).toBe('Post');
});
it('=> transformPostInThreadRecord: should return an array of type PostsInThread', async () => {
@@ -72,9 +72,7 @@ describe('*** POST Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe(
- 'PostsInThreadModel',
- );
+ expect(preparedRecords!.collection.table).toBe('PostsInThread');
});
it('=> transformFileRecord: should return an array of type File', async () => {
@@ -107,7 +105,7 @@ describe('*** POST Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('FileModel');
+ expect(preparedRecords!.collection.table).toBe('File');
});
it('=> transformDraftRecord: should return an array of type Draft', async () => {
@@ -132,7 +130,7 @@ describe('*** POST Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('DraftModel');
+ expect(preparedRecords!.collection.table).toBe('Draft');
});
it('=> transformPostsInChannelRecord: should return an array of type PostsInChannel', async () => {
@@ -156,8 +154,6 @@ describe('*** POST Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe(
- 'PostsInChannelModel',
- );
+ expect(preparedRecords!.collection.table).toBe('PostsInChannel');
});
});
diff --git a/app/database/operator/server_data_operator/transformers/reaction.test.ts b/app/database/operator/server_data_operator/transformers/reaction.test.ts
index 1b8675d4e7..7105da1a9d 100644
--- a/app/database/operator/server_data_operator/transformers/reaction.test.ts
+++ b/app/database/operator/server_data_operator/transformers/reaction.test.ts
@@ -30,6 +30,6 @@ describe('*** REACTION Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('ReactionModel');
+ expect(preparedRecords!.collection.table).toBe('Reaction');
});
});
diff --git a/app/database/operator/server_data_operator/transformers/team.test.ts b/app/database/operator/server_data_operator/transformers/team.test.ts
index 810546fde6..faf04037d0 100644
--- a/app/database/operator/server_data_operator/transformers/team.test.ts
+++ b/app/database/operator/server_data_operator/transformers/team.test.ts
@@ -31,7 +31,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('MyTeamModel');
+ expect(preparedRecords!.collection.table).toBe('MyTeam');
});
it('=> transformTeamRecord: should return an array of type Team', async () => {
@@ -67,7 +67,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('TeamModel');
+ expect(preparedRecords!.collection.table).toBe('Team');
});
it('=> transformTeamChannelHistoryRecord: should return an array of type Team', async () => {
@@ -89,7 +89,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('TeamChannelHistoryModel');
+ expect(preparedRecords!.collection.table).toBe('TeamChannelHistory');
});
it('=> transformTeamSearchHistoryRecord: should return an array of type TeamSearchHistory', async () => {
@@ -113,7 +113,7 @@ describe('*** TEAM Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('TeamSearchHistoryModel');
+ expect(preparedRecords!.collection.table).toBe('TeamSearchHistory');
});
it('=> transformTeamMembershipRecord: should return an array of type TeamMembership', async () => {
@@ -141,6 +141,6 @@ describe('*** TEAM Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('TeamMembershipModel');
+ expect(preparedRecords!.collection.table).toBe('TeamMembership');
});
});
diff --git a/app/database/operator/server_data_operator/transformers/user.test.ts b/app/database/operator/server_data_operator/transformers/user.test.ts
index bf4d487349..05d886995c 100644
--- a/app/database/operator/server_data_operator/transformers/user.test.ts
+++ b/app/database/operator/server_data_operator/transformers/user.test.ts
@@ -22,7 +22,7 @@ describe('*** USER Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('PreferenceModel');
+ expect(preparedRecords!.collection.table).toBe('Preference');
});
it('=> transformUserRecord: should return an array of type User', async () => {
@@ -78,6 +78,6 @@ describe('*** USER Prepare Records Test ***', () => {
});
expect(preparedRecords).toBeTruthy();
- expect(preparedRecords!.collection.modelClass.name).toBe('UserModel');
+ expect(preparedRecords!.collection.table).toBe('User');
});
});
diff --git a/app/database/operator/utils/test.ts b/app/database/operator/utils/test.ts
index 5399e5a976..94b00eba6e 100644
--- a/app/database/operator/utils/test.ts
+++ b/app/database/operator/utils/test.ts
@@ -7,8 +7,6 @@ import {sanitizeReactions} from '@database/operator/utils/reaction';
import {mockedPosts, mockedReactions} from './mock';
-import type {WriterInterface} from '@nozbe/watermelondb/Database';
-
describe('DataOperator: Utils tests', () => {
it('=> sanitizePosts: should filter between ordered and unordered posts', () => {
const {postsOrdered, postsUnordered} = sanitizePosts({
@@ -96,7 +94,7 @@ describe('DataOperator: Utils tests', () => {
// Jest in not using the same database instance amongst the Singletons; hence, we are creating the reaction record here
// eslint-disable-next-line max-nested-callbacks
- await server.database.write(async (writer: WriterInterface) => {
+ await server.database.write(async (writer) => {
await writer.batch(...prepareRecords);
});
diff --git a/app/hooks/android_back_handler.ts b/app/hooks/android_back_handler.ts
index d789cf5299..0bb2525c29 100644
--- a/app/hooks/android_back_handler.ts
+++ b/app/hooks/android_back_handler.ts
@@ -6,7 +6,9 @@ import {BackHandler} from 'react-native';
import NavigationStore from '@store/navigation_store';
-const useAndroidHardwareBackHandler = (componentId: string, callback: () => void) => {
+import type {AvailableScreens} from '@typings/screens/navigation';
+
+const useAndroidHardwareBackHandler = (componentId: AvailableScreens | undefined, callback: () => void) => {
useEffect(() => {
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
if (NavigationStore.getVisibleScreen() === componentId) {
diff --git a/app/hooks/device.ts b/app/hooks/device.ts
index c29a91ec50..0c6b29da7d 100644
--- a/app/hooks/device.ts
+++ b/app/hooks/device.ts
@@ -3,11 +3,12 @@
import React, {RefObject, useEffect, useRef, useState} from 'react';
import {AppState, Keyboard, NativeModules, Platform, useWindowDimensions, View} from 'react-native';
-import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {Device} from '@constants';
+import type {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
+
const {MattermostManaged} = NativeModules;
const isRunningInSplitView = MattermostManaged.isRunningInSplitView;
diff --git a/app/hooks/header.ts b/app/hooks/header.ts
index 0411612a3c..cbfde03572 100644
--- a/app/hooks/header.ts
+++ b/app/hooks/header.ts
@@ -2,13 +2,14 @@
// See LICENSE.txt for license information.
import React, {useCallback, useMemo} from 'react';
-import {NativeScrollEvent} from 'react-native';
import Animated, {runOnJS, scrollTo, useAnimatedRef, useAnimatedScrollHandler, useDerivedValue, useSharedValue, withTiming} from 'react-native-reanimated';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import ViewConstants from '@constants/view';
import {useIsTablet} from '@hooks/device';
+import type {NativeScrollEvent} from 'react-native';
+
type HeaderScrollContext = {
dragging?: boolean;
momentum?: string;
diff --git a/app/hooks/keyboard_tracking.ts b/app/hooks/keyboard_tracking.ts
index 95da896846..2cc198a890 100644
--- a/app/hooks/keyboard_tracking.ts
+++ b/app/hooks/keyboard_tracking.ts
@@ -2,11 +2,12 @@
// See LICENSE.txt for license information.
import {RefObject, useEffect, useRef} from 'react';
-import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
import {Navigation} from 'react-native-navigation';
import NavigationStore from '@store/navigation_store';
+import type {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
+
export const useKeyboardTrackingPaused = (keyboardTrackingRef: RefObject, trackerId: string, screens: string[]) => {
const isPostDraftPaused = useRef(false);
diff --git a/app/init/managed_app.ts b/app/init/managed_app.ts
index 234a5f783d..912d45f11d 100644
--- a/app/init/managed_app.ts
+++ b/app/init/managed_app.ts
@@ -78,7 +78,7 @@ class ManagedApp {
const jailbreakProtection = config!.jailbreakProtection === 'true';
if (jailbreakProtection && !this.isTrustedDevice()) {
- this.alertDeviceIsUntrusted();
+ this.alertDeviceIsNotTrusted();
return;
}
@@ -88,14 +88,17 @@ class ManagedApp {
}
};
- alertDeviceIsUntrusted = () => {
+ alertDeviceIsNotTrusted = () => {
// We use the default device locale as this is an app wide setting
// and does not require any server data
const locale = DEFAULT_LOCALE;
const translations = getTranslations(locale);
Alert.alert(
translations[t('mobile.managed.blocked_by')].replace('{vendor}', this.vendor),
- translations[t('mobile.managed.jailbreak')].replace('{vendor}', this.vendor),
+ translations[t('mobile.managed.jailbreak')].
+ replace('{vendor}', this.vendor).
+ replace('{reason}', JailMonkey.jailBrokenMessage() || translations[t('mobile.managed.jailbreak_no_reason')]).
+ replace('{debug}', JSON.stringify(JailMonkey.androidRootedDetectionMethods || translations[t('mobile.managed.jailbreak_no_debug_info')])),
[{
text: translations[t('mobile.managed.exit')],
style: 'destructive',
@@ -139,7 +142,7 @@ class ManagedApp {
};
isTrustedDevice = () => {
- return __DEV__ || JailMonkey.trustFall();
+ return __DEV__ || !JailMonkey.isJailBroken();
};
onAppStateChange = async (appState: AppStateStatus) => {
diff --git a/app/managers/draft_upload_manager/index.test.ts b/app/managers/draft_upload_manager/index.test.ts
index f13f2ae845..545dcf60be 100644
--- a/app/managers/draft_upload_manager/index.test.ts
+++ b/app/managers/draft_upload_manager/index.test.ts
@@ -1,18 +1,19 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {ClientResponse, ProgressPromise} from '@mattermost/react-native-network-client';
import {AppState, AppStateStatus} from 'react-native';
import {addFilesToDraft} from '@actions/local/draft';
import {PROGRESS_TIME_TO_STORE} from '@constants/files';
import DatabaseManager from '@database/manager';
-import ServerDataOperator from '@database/operator/server_data_operator';
import {getDraft} from '@queries/servers/drafts';
import TestHelper from '@test/test_helper';
import {exportedForTesting} from '.';
+import type ServerDataOperator from '@database/operator/server_data_operator';
+import type {ClientResponse, ProgressPromise} from '@mattermost/react-native-network-client';
+
const {DraftUploadManager} = exportedForTesting;
const url = 'baseHandler.test.com';
diff --git a/app/managers/draft_upload_manager/index.ts b/app/managers/draft_upload_manager/index.ts
index 76d11764a9..44a9d74bc7 100644
--- a/app/managers/draft_upload_manager/index.ts
+++ b/app/managers/draft_upload_manager/index.ts
@@ -1,13 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {ClientResponse, ClientResponseError} from '@mattermost/react-native-network-client';
import {AppState, AppStateStatus} from 'react-native';
import {updateDraftFile} from '@actions/local/draft';
import {uploadFile} from '@actions/remote/file';
import {PROGRESS_TIME_TO_STORE} from '@constants/files';
+import type {ClientResponse, ClientResponseError} from '@mattermost/react-native-network-client';
+
type FileHandler = {
[clientId: string]: {
cancel?: () => void;
diff --git a/app/products/calls/actions/calls.test.ts b/app/products/calls/actions/calls.test.ts
index 672787e820..bf9437d74e 100644
--- a/app/products/calls/actions/calls.test.ts
+++ b/app/products/calls/actions/calls.test.ts
@@ -100,6 +100,7 @@ const addFakeCall = (serverUrl: string, channelId: string) => {
describe('Actions.Calls', () => {
const {newConnection} = require('@calls/connection/connection');
InCallManager.setSpeakerphoneOn = jest.fn();
+ InCallManager.setForceSpeakerphoneOn = jest.fn();
// eslint-disable-next-line
// @ts-ignore
NetworkManager.getClient = () => mockClient;
diff --git a/app/products/calls/actions/calls.ts b/app/products/calls/actions/calls.ts
index c363eabefb..f935ff42f5 100644
--- a/app/products/calls/actions/calls.ts
+++ b/app/products/calls/actions/calls.ts
@@ -1,11 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import {Alert} from 'react-native';
import InCallManager from 'react-native-incall-manager';
+import {Navigation} from 'react-native-navigation';
import {forceLogoutIfNecessary} from '@actions/remote/session';
import {fetchUsersByIds} from '@actions/remote/user';
-import {needsRecordingWillBePostedAlert} from '@calls/alerts';
+import {leaveAndJoinWithAlert, needsRecordingWillBePostedAlert} from '@calls/alerts';
import {
getCallsConfig,
getCallsState,
@@ -18,8 +20,10 @@ import {
setCallForChannel,
newCurrentCall,
myselfLeftCall,
+ getCurrentCall,
+ getChannelsWithCalls,
} from '@calls/state';
-import {General, Preferences} from '@constants';
+import {General, Preferences, Screens} from '@constants';
import Calls from '@constants/calls';
import DatabaseManager from '@database/manager';
import {getTeammateNameDisplaySetting} from '@helpers/api/preference';
@@ -28,6 +32,8 @@ import {getChannelById} from '@queries/servers/channel';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {getConfig, getLicense} from '@queries/servers/system';
import {getCurrentUser, getUserById} from '@queries/servers/user';
+import {dismissAllModalsAndPopToScreen} from '@screens/navigation';
+import NavigationStore from '@store/navigation_store';
import {logWarning} from '@utils/log';
import {displayUsername, getUserIdFromChannelName, isSystemAdmin} from '@utils/user';
@@ -228,7 +234,13 @@ export const enableChannelCalls = async (serverUrl: string, channelId: string, e
return {};
};
-export const joinCall = async (serverUrl: string, channelId: string, userId: string, hasMicPermission: boolean): Promise<{ error?: string | Error; data?: string }> => {
+export const joinCall = async (
+ serverUrl: string,
+ channelId: string,
+ userId: string,
+ hasMicPermission: boolean,
+ title?: string,
+): Promise<{ error?: string | Error; data?: string }> => {
// Edge case: calls was disabled when app loaded, and then enabled, but app hasn't
// reconnected its websocket since then (i.e., hasn't called batchLoadCalls yet)
const {data: enabled} = await checkIsCallsPluginEnabled(serverUrl);
@@ -246,7 +258,7 @@ export const joinCall = async (serverUrl: string, channelId: string, userId: str
try {
connection = await newConnection(serverUrl, channelId, () => {
myselfLeftCall();
- }, setScreenShareURL, hasMicPermission);
+ }, setScreenShareURL, hasMicPermission, title);
} catch (error: unknown) {
await forceLogoutIfNecessary(serverUrl, error as ClientError);
return {error: error as Error};
@@ -270,6 +282,16 @@ export const leaveCall = () => {
setSpeakerphoneOn(false);
};
+export const leaveCallPopCallScreen = async () => {
+ leaveCall();
+
+ // Need to pop the call screen, if it's somewhere in the stack.
+ if (NavigationStore.getScreensInStack().includes(Screens.CALL)) {
+ await dismissAllModalsAndPopToScreen(Screens.CALL, 'Call');
+ Navigation.pop(Screens.CALL).catch(() => null);
+ }
+};
+
export const muteMyself = () => {
if (connection) {
connection.mute();
@@ -307,7 +329,7 @@ export const sendReaction = (emoji: CallReactionEmoji) => {
};
export const setSpeakerphoneOn = (speakerphoneOn: boolean) => {
- InCallManager.setSpeakerphoneOn(speakerphoneOn);
+ InCallManager.setForceSpeakerphoneOn(speakerphoneOn);
setSpeakerPhone(speakerphoneOn);
};
@@ -419,3 +441,89 @@ export const stopCallRecording = async (serverUrl: string, callId: string) => {
return data;
};
+
+// handleCallsSlashCommand will return true if the slash command was handled
+export const handleCallsSlashCommand = async (value: string, serverUrl: string, channelId: string, currentUserId: string, intl: IntlShape):
+ Promise<{ handled?: boolean; error?: string }> => {
+ const tokens = value.split(' ');
+ if (tokens.length < 2 || tokens[0] !== '/call') {
+ return {handled: false};
+ }
+
+ switch (tokens[1]) {
+ case 'end':
+ await handleEndCall(serverUrl, channelId, currentUserId, intl);
+ return {handled: true};
+ case 'start': {
+ if (getChannelsWithCalls(serverUrl)[channelId]) {
+ return {
+ error: intl.formatMessage({
+ id: 'mobile.calls_start_call_exists',
+ defaultMessage: 'A call is already ongoing in the channel.',
+ }),
+ };
+ }
+ const title = tokens.length > 2 ? tokens.slice(2).join(' ') : undefined;
+ await leaveAndJoinWithAlert(intl, serverUrl, channelId, title);
+ return {handled: true};
+ }
+ case 'join':
+ await leaveAndJoinWithAlert(intl, serverUrl, channelId);
+ return {handled: true};
+ case 'leave':
+ if (getCurrentCall()?.channelId === channelId) {
+ await leaveCallPopCallScreen();
+ return {handled: true};
+ }
+ return {
+ error: intl.formatMessage({
+ id: 'mobile.calls_not_connected',
+ defaultMessage: 'You\'re not connected to a call in the current channel.',
+ }),
+ };
+ }
+
+ return {handled: false};
+};
+
+const handleEndCall = async (serverUrl: string, channelId: string, currentUserId: string, intl: IntlShape) => {
+ const hasPermissions = await canEndCall(serverUrl, channelId);
+
+ if (!hasPermissions) {
+ Alert.alert(
+ intl.formatMessage({
+ id: 'mobile.calls_end_permission_title',
+ defaultMessage: 'Error',
+ }),
+ intl.formatMessage({
+ id: 'mobile.calls_end_permission_msg',
+ defaultMessage: 'You don\'t have permission to end the call. Please ask the call owner to end the call.',
+ }));
+ return;
+ }
+
+ const message = await getEndCallMessage(serverUrl, channelId, currentUserId, intl);
+ const title = intl.formatMessage({id: 'mobile.calls_end_call_title', defaultMessage: 'End call'});
+
+ Alert.alert(
+ title,
+ message,
+ [
+ {
+ text: intl.formatMessage({id: 'mobile.post.cancel', defaultMessage: 'Cancel'}),
+ },
+ {
+ text: title,
+ onPress: async () => {
+ try {
+ await endCall(serverUrl, channelId);
+ } catch (e) {
+ const err = (e as ClientError).message || 'unable to complete command, see server logs';
+ Alert.alert('Error', `Error: ${err}`);
+ }
+ },
+ style: 'cancel',
+ },
+ ],
+ );
+};
diff --git a/app/products/calls/actions/index.ts b/app/products/calls/actions/index.ts
index e8f579c9f4..612d9bfa2a 100644
--- a/app/products/calls/actions/index.ts
+++ b/app/products/calls/actions/index.ts
@@ -12,6 +12,7 @@ export {
raiseHand,
unraiseHand,
setSpeakerphoneOn,
+ handleCallsSlashCommand,
} from './calls';
export {hasMicrophonePermission} from './permissions';
diff --git a/app/products/calls/alerts.ts b/app/products/calls/alerts.ts
index fc954f101d..1ff6fafc8b 100644
--- a/app/products/calls/alerts.ts
+++ b/app/products/calls/alerts.ts
@@ -2,20 +2,25 @@
// See LICENSE.txt for license information.
import {Alert} from 'react-native';
-import {Navigation} from 'react-native-navigation';
-import {hasMicrophonePermission, joinCall, leaveCall, unmuteMyself} from '@calls/actions';
-import {LimitRestrictedInfo} from '@calls/observers';
-import {getCallsConfig, getCallsState, setMicPermissionsGranted} from '@calls/state';
+import {hasMicrophonePermission, joinCall, unmuteMyself} from '@calls/actions';
+import {leaveCallPopCallScreen} from '@calls/actions/calls';
+import {
+ getCallsConfig,
+ getCallsState,
+ getChannelsWithCalls,
+ getCurrentCall,
+ setMicPermissionsGranted,
+} from '@calls/state';
import {errorAlert} from '@calls/utils';
-import {Screens} from '@constants';
import DatabaseManager from '@database/manager';
+import {getChannelById} from '@queries/servers/channel';
import {getCurrentUser} from '@queries/servers/user';
-import {dismissAllModals, dismissAllModalsAndPopToScreen} from '@screens/navigation';
-import NavigationStore from '@store/navigation_store';
+import {isDMorGM} from '@utils/channel';
import {logError} from '@utils/log';
import {isSystemAdmin} from '@utils/user';
+import type {LimitRestrictedInfo} from '@calls/observers';
import type {IntlShape} from 'react-intl';
// Only allow one recording alert per call.
@@ -56,17 +61,39 @@ export const showLimitRestrictedAlert = (info: LimitRestrictedInfo, intl: IntlSh
);
};
-export const leaveAndJoinWithAlert = (
+export const leaveAndJoinWithAlert = async (
intl: IntlShape,
- serverUrl: string,
- channelId: string,
- leaveChannelName: string,
- joinChannelName: string,
- confirmToJoin: boolean,
- newCall: boolean,
- isDMorGM: boolean,
+ joinServerUrl: string,
+ joinChannelId: string,
+ title?: string,
) => {
- if (confirmToJoin) {
+ let leaveChannelName = '';
+ let joinChannelName = '';
+ let joinChannelIsDMorGM = false;
+ let leaveServerUrl = '';
+ let leaveChannelId = '';
+ const newCall = !getChannelsWithCalls(joinServerUrl)[joinChannelId];
+
+ try {
+ const {database: joinDatabase} = DatabaseManager.getServerDatabaseAndOperator(joinServerUrl);
+ const joinChannel = await getChannelById(joinDatabase, joinChannelId);
+ joinChannelName = joinChannel?.displayName || '';
+ joinChannelIsDMorGM = joinChannel ? isDMorGM(joinChannel) : false;
+
+ const currentCall = getCurrentCall();
+ if (currentCall) {
+ const {database: leaveDatabase} = DatabaseManager.getServerDatabaseAndOperator(currentCall.serverUrl);
+ const leaveChannel = await getChannelById(leaveDatabase, currentCall.channelId);
+ leaveChannelName = leaveChannel?.displayName || '';
+ leaveServerUrl = currentCall.serverUrl;
+ leaveChannelId = currentCall.channelId;
+ }
+ } catch (error) {
+ logError('failed to getServerDatabase in leaveAndJoinWithAlert', error);
+ return;
+ }
+
+ if (leaveServerUrl && leaveChannelId) {
const {formatMessage} = intl;
let joinMessage = formatMessage({
@@ -99,17 +126,24 @@ export const leaveAndJoinWithAlert = (
id: 'mobile.leave_and_join_confirmation',
defaultMessage: 'Leave & Join',
}),
- onPress: () => doJoinCall(serverUrl, channelId, isDMorGM, newCall, intl),
+ onPress: () => doJoinCall(joinServerUrl, joinChannelId, joinChannelIsDMorGM, newCall, intl, title),
style: 'cancel',
},
],
);
} else {
- doJoinCall(serverUrl, channelId, isDMorGM, newCall, intl);
+ doJoinCall(joinServerUrl, joinChannelId, joinChannelIsDMorGM, newCall, intl, title);
}
};
-const doJoinCall = async (serverUrl: string, channelId: string, isDMorGM: boolean, newCall: boolean, intl: IntlShape) => {
+const doJoinCall = async (
+ serverUrl: string,
+ channelId: string,
+ joinChannelIsDMorGM: boolean,
+ newCall: boolean,
+ intl: IntlShape,
+ title?: string,
+) => {
const {formatMessage} = intl;
let user;
@@ -155,14 +189,14 @@ const doJoinCall = async (serverUrl: string, channelId: string, isDMorGM: boolea
const hasPermission = await hasMicrophonePermission();
setMicPermissionsGranted(hasPermission);
- const res = await joinCall(serverUrl, channelId, user.id, hasPermission);
+ const res = await joinCall(serverUrl, channelId, user.id, hasPermission, title);
if (res.error) {
const seeLogs = formatMessage({id: 'mobile.calls_see_logs', defaultMessage: 'See server logs'});
errorAlert(res.error?.toString() || seeLogs, intl);
return;
}
- if (isDMorGM) {
+ if (joinChannelIsDMorGM) {
// FIXME (MM-46048) - HACK
// There's a race condition between unmuting and receiving existing tracks from other participants.
// Fixing this properly requires extensive and potentially breaking changes.
@@ -222,14 +256,7 @@ export const recordingAlert = (isHost: boolean, intl: IntlShape) => {
defaultMessage: 'Leave',
}),
onPress: async () => {
- leaveCall();
-
- // Need to pop the call screen, if it's somewhere in the stack.
- await dismissAllModals();
- if (NavigationStore.getScreensInStack().includes(Screens.CALL)) {
- await dismissAllModalsAndPopToScreen(Screens.CALL, 'Call');
- Navigation.pop(Screens.CALL).catch(() => null);
- }
+ await leaveCallPopCallScreen();
},
style: 'destructive',
},
diff --git a/app/products/calls/components/call_avatar.tsx b/app/products/calls/components/call_avatar.tsx
index ee704d4224..fdd41b1339 100644
--- a/app/products/calls/components/call_avatar.tsx
+++ b/app/products/calls/components/call_avatar.tsx
@@ -4,11 +4,11 @@
import React, {useMemo} from 'react';
import {View, StyleSheet, Text, Platform} from 'react-native';
-import {CallReactionEmoji} from '@calls/types/calls';
import CompassIcon from '@components/compass_icon';
import Emoji from '@components/emoji';
import ProfilePicture from '@components/profile_picture';
+import type {CallReactionEmoji} from '@calls/types/calls';
import type UserModel from '@typings/database/models/servers/user';
type Props = {
diff --git a/app/products/calls/components/calls_custom_message/calls_custom_message.tsx b/app/products/calls/components/calls_custom_message/calls_custom_message.tsx
index 16640f43f0..e651dcff4a 100644
--- a/app/products/calls/components/calls_custom_message/calls_custom_message.tsx
+++ b/app/products/calls/components/calls_custom_message/calls_custom_message.tsx
@@ -14,6 +14,7 @@ import FormattedTime from '@components/formatted_time';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
+import {typography} from '@utils/typography';
import {displayUsername, getUserTimezone} from '@utils/user';
import type {LimitRestrictedInfo} from '@calls/observers';
@@ -26,15 +27,16 @@ type Props = {
author?: UserModel;
isMilitaryTime: boolean;
teammateNameDisplay?: string;
- currentCallChannelId?: string;
- leaveChannelName?: string;
- joinChannelName?: string;
- joinChannelIsDMorGM?: boolean;
limitRestrictedInfo?: LimitRestrictedInfo;
+ ccChannelId?: string;
}
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
return {
+ title: {
+ ...typography('Heading', 500),
+ color: theme.centerChannelColor,
+ },
messageStyle: {
flexDirection: 'row',
color: changeOpacity(theme.centerChannelColor, 0.6),
@@ -108,7 +110,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
export const CallsCustomMessage = ({
post, currentUser, author, isMilitaryTime, teammateNameDisplay,
- currentCallChannelId, leaveChannelName, joinChannelName, joinChannelIsDMorGM, limitRestrictedInfo,
+ ccChannelId, limitRestrictedInfo,
}: Props) => {
const intl = useIntl();
const theme = useTheme();
@@ -116,8 +118,7 @@ export const CallsCustomMessage = ({
const serverUrl = useServerUrl();
const timezone = getUserTimezone(currentUser);
- const confirmToJoin = Boolean(currentCallChannelId && currentCallChannelId !== post.channelId);
- const alreadyInTheCall = Boolean(currentCallChannelId && currentCallChannelId === post.channelId);
+ const alreadyInTheCall = Boolean(ccChannelId && ccChannelId === post.channelId);
const isLimitRestricted = Boolean(limitRestrictedInfo?.limitRestricted);
const joinHandler = () => {
@@ -130,100 +131,110 @@ export const CallsCustomMessage = ({
return;
}
- leaveAndJoinWithAlert(intl, serverUrl, post.channelId, leaveChannelName || '', joinChannelName || '', confirmToJoin, false, Boolean(joinChannelIsDMorGM));
+ leaveAndJoinWithAlert(intl, serverUrl, post.channelId);
};
+ const title = post.props.title ? (
+
+ {post.props.title}
+
+ ) : null;
+
if (post.props.end_at) {
return (
-
-
-
-
+ {title}
+
+
-
+
- {' '}
- {
+
+
+ {' '}
- }
- {'•'}
-
+ {'•'}
+
+
-
+ >
);
}
const joinTextStyle = [style.joinCallButtonText, isLimitRestricted && style.joinCallButtonTextRestricted];
return (
-
-
-
-
-
-
-
-
+ <>
+ {title}
+
- {
- alreadyInTheCall &&
+
- }
- {
- !alreadyInTheCall &&
-
- }
-
-
+
+
+
+
+ {
+ alreadyInTheCall &&
+
+ }
+ {
+ !alreadyInTheCall &&
+
+ }
+
+
+ >
);
};
diff --git a/app/products/calls/components/calls_custom_message/index.ts b/app/products/calls/components/calls_custom_message/index.ts
index e2fa8be68f..3f4234817c 100644
--- a/app/products/calls/components/calls_custom_message/index.ts
+++ b/app/products/calls/components/calls_custom_message/index.ts
@@ -3,19 +3,16 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
-import {combineLatest, of as of$} from 'rxjs';
+import {of as of$} from 'rxjs';
import {distinctUntilChanged, switchMap} from 'rxjs/operators';
import {CallsCustomMessage} from '@calls/components/calls_custom_message/calls_custom_message';
import {observeIsCallLimitRestricted} from '@calls/observers';
import {observeCurrentCall} from '@calls/state';
import {Preferences} from '@constants';
-import DatabaseManager from '@database/manager';
import {getPreferenceAsBool} from '@helpers/api/preference';
-import {observeChannel} from '@queries/servers/channel';
import {queryPreferencesByCategoryAndName} from '@queries/servers/preference';
import {observeCurrentUser, observeTeammateNameDisplay, observeUser} from '@queries/servers/user';
-import {isDMorGM} from '@utils/channel';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PostModel from '@typings/database/models/servers/post';
@@ -43,27 +40,8 @@ const enhanced = withObservables(['post'], ({serverUrl, post, database}: OwnProp
};
}
- const ccDatabase = observeCurrentCall().pipe(
- switchMap((call) => of$(call?.serverUrl || '')),
- distinctUntilChanged(),
- switchMap((url) => of$(DatabaseManager.serverDatabases[url]?.database)),
- );
- const currentCallChannelId = observeCurrentCall().pipe(
- switchMap((call) => of$(call?.channelId || '')),
- distinctUntilChanged(),
- );
- const leaveChannelName = combineLatest([ccDatabase, currentCallChannelId]).pipe(
- switchMap(([db, id]) => (db && id ? observeChannel(db, id) : of$(undefined))),
- switchMap((c) => of$(c ? c.displayName : '')),
- distinctUntilChanged(),
- );
- const joinChannel = observeChannel(database, post.channelId);
- const joinChannelName = joinChannel.pipe(
- switchMap((chan) => of$(chan?.displayName || '')),
- distinctUntilChanged(),
- );
- const joinChannelIsDMorGM = joinChannel.pipe(
- switchMap((chan) => of$(chan ? isDMorGM(chan) : false)),
+ const ccChannelId = observeCurrentCall().pipe(
+ switchMap((call) => of$(call?.channelId)),
distinctUntilChanged(),
);
@@ -72,11 +50,8 @@ const enhanced = withObservables(['post'], ({serverUrl, post, database}: OwnProp
author,
isMilitaryTime,
teammateNameDisplay: observeTeammateNameDisplay(database),
- currentCallChannelId,
- leaveChannelName,
- joinChannelName,
- joinChannelIsDMorGM,
limitRestrictedInfo: observeIsCallLimitRestricted(database, serverUrl, post.channelId),
+ ccChannelId,
};
});
diff --git a/app/products/calls/components/channel_info_start/channel_info_start_button.tsx b/app/products/calls/components/channel_info_start/channel_info_start_button.tsx
index 6cdeb09c83..0b699eac14 100644
--- a/app/products/calls/components/channel_info_start/channel_info_start_button.tsx
+++ b/app/products/calls/components/channel_info_start/channel_info_start_button.tsx
@@ -14,26 +14,18 @@ import type {LimitRestrictedInfo} from '@calls/observers';
export interface Props {
serverUrl: string;
- displayName: string;
channelId: string;
- channelIsDMorGM: boolean;
isACallInCurrentChannel: boolean;
- confirmToJoin: boolean;
alreadyInCall: boolean;
- currentCallChannelName: string;
dismissChannelInfo: () => void;
limitRestrictedInfo: LimitRestrictedInfo;
}
const ChannelInfoStartButton = ({
serverUrl,
- displayName,
channelId,
- channelIsDMorGM,
isACallInCurrentChannel,
- confirmToJoin,
alreadyInCall,
- currentCallChannelName,
dismissChannelInfo,
limitRestrictedInfo,
}: Props) => {
@@ -46,11 +38,11 @@ const ChannelInfoStartButton = ({
} else if (isLimitRestricted) {
showLimitRestrictedAlert(limitRestrictedInfo, intl);
} else {
- leaveAndJoinWithAlert(intl, serverUrl, channelId, currentCallChannelName, displayName, confirmToJoin, !isACallInCurrentChannel, channelIsDMorGM);
+ leaveAndJoinWithAlert(intl, serverUrl, channelId);
}
dismissChannelInfo();
- }, [isLimitRestricted, alreadyInCall, dismissChannelInfo, intl, serverUrl, channelId, currentCallChannelName, displayName, confirmToJoin, isACallInCurrentChannel]);
+ }, [isLimitRestricted, alreadyInCall, dismissChannelInfo, intl, serverUrl, channelId, isACallInCurrentChannel]);
const [tryJoin, msgPostfix] = useTryCallsFunction(toggleJoinLeave);
diff --git a/app/products/calls/components/channel_info_start/index.ts b/app/products/calls/components/channel_info_start/index.ts
index cef55b4874..06bf3b22ce 100644
--- a/app/products/calls/components/channel_info_start/index.ts
+++ b/app/products/calls/components/channel_info_start/index.ts
@@ -3,15 +3,12 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
-import {combineLatest, of as of$} from 'rxjs';
+import {of as of$} from 'rxjs';
import {distinctUntilChanged, switchMap} from 'rxjs/operators';
import ChannelInfoStartButton from '@calls/components/channel_info_start/channel_info_start_button';
import {observeIsCallLimitRestricted} from '@calls/observers';
import {observeChannelsWithCalls, observeCurrentCall} from '@calls/state';
-import DatabaseManager from '@database/manager';
-import {observeChannel} from '@queries/servers/channel';
-import {isDMorGM} from '@utils/channel';
import type {WithDatabaseArgs} from '@typings/database/database';
@@ -21,43 +18,21 @@ type EnhanceProps = WithDatabaseArgs & {
}
const enhanced = withObservables([], ({serverUrl, channelId, database}: EnhanceProps) => {
- const channel = observeChannel(database, channelId);
- const displayName = channel.pipe(
- switchMap((c) => of$(c?.displayName || '')),
- distinctUntilChanged(),
- );
- const channelIsDMorGM = channel.pipe(
- switchMap((chan) => of$(chan ? isDMorGM(chan) : false)),
- distinctUntilChanged(),
- );
const isACallInCurrentChannel = observeChannelsWithCalls(serverUrl).pipe(
switchMap((calls) => of$(Boolean(calls[channelId]))),
distinctUntilChanged(),
);
- const ccDatabase = observeCurrentCall().pipe(
- switchMap((call) => of$(call?.serverUrl || '')),
- distinctUntilChanged(),
- switchMap((url) => of$(DatabaseManager.serverDatabases[url]?.database)),
- );
const ccChannelId = observeCurrentCall().pipe(
switchMap((call) => of$(call?.channelId)),
distinctUntilChanged(),
);
const confirmToJoin = ccChannelId.pipe(switchMap((ccId) => of$(ccId && ccId !== channelId)));
const alreadyInCall = ccChannelId.pipe(switchMap((ccId) => of$(ccId && ccId === channelId)));
- const currentCallChannelName = combineLatest([ccDatabase, ccChannelId]).pipe(
- switchMap(([db, id]) => (db && id ? observeChannel(db, id) : of$(undefined))),
- switchMap((c) => of$(c?.displayName || '')),
- distinctUntilChanged(),
- );
return {
- displayName,
- channelIsDMorGM,
isACallInCurrentChannel,
confirmToJoin,
alreadyInCall,
- currentCallChannelName,
limitRestrictedInfo: observeIsCallLimitRestricted(database, serverUrl, channelId),
};
});
diff --git a/app/products/calls/components/current_call_bar/current_call_bar.tsx b/app/products/calls/components/current_call_bar/current_call_bar.tsx
index 171468c1dd..1cc2096745 100644
--- a/app/products/calls/components/current_call_bar/current_call_bar.tsx
+++ b/app/products/calls/components/current_call_bar/current_call_bar.tsx
@@ -4,7 +4,6 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
import {View, Text, TouchableOpacity, Pressable, Platform} from 'react-native';
-import {Options} from 'react-native-navigation';
import {muteMyself, unmuteMyself} from '@calls/actions';
import {recordingAlert, recordingWillBePostedAlert} from '@calls/alerts';
@@ -12,7 +11,6 @@ import CallAvatar from '@calls/components/call_avatar';
import PermissionErrorBar from '@calls/components/permission_error_bar';
import UnavailableIconWrapper from '@calls/components/unavailable_icon_wrapper';
import {usePermissionsChecker} from '@calls/hooks';
-import {CurrentCall} from '@calls/types/calls';
import CompassIcon from '@components/compass_icon';
import {Screens} from '@constants';
import {CURRENT_CALL_BAR_HEIGHT} from '@constants/view';
@@ -21,7 +19,9 @@ import {dismissAllModalsAndPopToScreen} from '@screens/navigation';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {displayUsername} from '@utils/user';
+import type {CurrentCall} from '@calls/types/calls';
import type UserModel from '@typings/database/models/servers/user';
+import type {Options} from 'react-native-navigation';
type Props = {
displayName: string;
diff --git a/app/products/calls/components/emoji_list.tsx b/app/products/calls/components/emoji_list.tsx
index 7934abdbba..48bcef6f7f 100644
--- a/app/products/calls/components/emoji_list.tsx
+++ b/app/products/calls/components/emoji_list.tsx
@@ -6,7 +6,8 @@ import {StyleSheet, View} from 'react-native';
import LinearGradient from 'react-native-linear-gradient';
import EmojiPill from '@calls/components/emoji_pill';
-import {ReactionStreamEmoji} from '@calls/types/calls';
+
+import type {ReactionStreamEmoji} from '@calls/types/calls';
const styles = StyleSheet.create({
container: {
diff --git a/app/products/calls/components/join_call_banner/index.ts b/app/products/calls/components/join_call_banner/index.ts
index efaa0c32fb..5e4a2ebc1d 100644
--- a/app/products/calls/components/join_call_banner/index.ts
+++ b/app/products/calls/components/join_call_banner/index.ts
@@ -8,11 +8,9 @@ import {distinctUntilChanged, switchMap} from 'rxjs/operators';
import JoinCallBanner from '@calls/components/join_call_banner/join_call_banner';
import {observeIsCallLimitRestricted} from '@calls/observers';
-import {observeCallsState, observeCurrentCall} from '@calls/state';
+import {observeCallsState} from '@calls/state';
import {idsAreEqual} from '@calls/utils';
-import {observeChannel} from '@queries/servers/channel';
import {queryUsersById} from '@queries/servers/user';
-import {isDMorGM} from '@utils/channel';
import type {WithDatabaseArgs} from '@typings/database/database';
@@ -26,15 +24,6 @@ const enhanced = withObservables(['serverUrl', 'channelId'], ({
channelId,
database,
}: OwnProps & WithDatabaseArgs) => {
- const channel = observeChannel(database, channelId);
- const displayName = channel.pipe(
- switchMap((c) => of$(c?.displayName)),
- distinctUntilChanged(),
- );
- const channelIsDMorGM = channel.pipe(
- switchMap((chan) => of$(chan ? isDMorGM(chan) : false)),
- distinctUntilChanged(),
- );
const callsState = observeCallsState(serverUrl);
const participants = callsState.pipe(
switchMap((state) => of$(state.calls[channelId])),
@@ -43,30 +32,13 @@ const enhanced = withObservables(['serverUrl', 'channelId'], ({
distinctUntilChanged((prev, curr) => idsAreEqual(prev, curr)), // Continue only if we have a different set of participant ids
switchMap((ids) => (ids.length > 0 ? queryUsersById(database, ids).observeWithColumns(['last_picture_update']) : of$([]))),
);
- const currentCallChannelId = observeCurrentCall().pipe(
- switchMap((call) => of$(call?.channelId || undefined)),
- distinctUntilChanged(),
- );
- const inACall = currentCallChannelId.pipe(
- switchMap((id) => of$(Boolean(id))),
- distinctUntilChanged(),
- );
- const currentCallChannelName = currentCallChannelId.pipe(
- switchMap((id) => observeChannel(database, id || '')),
- switchMap((c) => of$(c ? c.displayName : '')),
- distinctUntilChanged(),
- );
const channelCallStartTime = callsState.pipe(
switchMap((cs) => of$(cs.calls[channelId]?.startTime || 0)),
distinctUntilChanged(),
);
return {
- displayName,
- channelIsDMorGM,
participants,
- inACall,
- currentCallChannelName,
channelCallStartTime,
limitRestrictedInfo: observeIsCallLimitRestricted(database, serverUrl, channelId),
};
diff --git a/app/products/calls/components/join_call_banner/join_call_banner.tsx b/app/products/calls/components/join_call_banner/join_call_banner.tsx
index 2f35fc5964..77928e3012 100644
--- a/app/products/calls/components/join_call_banner/join_call_banner.tsx
+++ b/app/products/calls/components/join_call_banner/join_call_banner.tsx
@@ -21,11 +21,7 @@ import type UserModel from '@typings/database/models/servers/user';
type Props = {
channelId: string;
serverUrl: string;
- displayName: string;
- channelIsDMorGM: boolean;
- inACall: boolean;
participants: UserModel[];
- currentCallChannelName: string;
channelCallStartTime: number;
limitRestrictedInfo: LimitRestrictedInfo;
}
@@ -86,11 +82,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
const JoinCallBanner = ({
channelId,
serverUrl,
- displayName,
- channelIsDMorGM,
participants,
- inACall,
- currentCallChannelName,
channelCallStartTime,
limitRestrictedInfo,
}: Props) => {
@@ -104,7 +96,7 @@ const JoinCallBanner = ({
showLimitRestrictedAlert(limitRestrictedInfo, intl);
return;
}
- leaveAndJoinWithAlert(intl, serverUrl, channelId, currentCallChannelName, displayName, inACall, false, channelIsDMorGM);
+ leaveAndJoinWithAlert(intl, serverUrl, channelId);
};
return (
diff --git a/app/products/calls/connection/connection.ts b/app/products/calls/connection/connection.ts
index e6bb5de328..cb72effbfb 100644
--- a/app/products/calls/connection/connection.ts
+++ b/app/products/calls/connection/connection.ts
@@ -12,6 +12,7 @@ import {
mediaDevices,
} from 'react-native-webrtc';
+import {setSpeakerPhone} from '@calls/state';
import {getICEServersConfigs} from '@calls/utils';
import {WebsocketEvents} from '@constants';
import {getServerCredentials} from '@init/credentials';
@@ -31,6 +32,7 @@ export async function newConnection(
closeCb: () => void,
setScreenShareURL: (url: string) => void,
hasMicPermission: boolean,
+ title?: string,
) {
let peer: Peer | null = null;
let stream: MediaStream;
@@ -203,8 +205,8 @@ export async function newConnection(
}
}
- InCallManager.start({media: 'audio'});
- InCallManager.stopProximitySensor();
+ InCallManager.start({media: 'video'});
+ setSpeakerPhone(true);
peer = new Peer(null, iceConfigs);
peer.on('signal', (data: any) => {
@@ -249,6 +251,7 @@ export async function newConnection(
} else {
ws.send('join', {
channelID,
+ title,
});
}
});
diff --git a/app/products/calls/hooks.ts b/app/products/calls/hooks.ts
index cc2b88f7fe..eba430542c 100644
--- a/app/products/calls/hooks.ts
+++ b/app/products/calls/hooks.ts
@@ -11,12 +11,13 @@ import Permissions from 'react-native-permissions';
import {initializeVoiceTrack} from '@calls/actions/calls';
import {setMicPermissionsGranted} from '@calls/state';
import {errorAlert} from '@calls/utils';
-import {Client} from '@client/rest';
-import ClientError from '@client/rest/error';
import {useServerUrl} from '@context/server';
import {useAppState} from '@hooks/device';
import NetworkManager from '@managers/network_manager';
+import type {Client} from '@client/rest';
+import type ClientError from '@client/rest/error';
+
export const useTryCallsFunction = (fn: () => void) => {
const intl = useIntl();
const serverUrl = useServerUrl();
diff --git a/app/products/calls/screens/call_screen/call_screen.tsx b/app/products/calls/screens/call_screen/call_screen.tsx
index 95b1dbeb44..b1d0d47d60 100644
--- a/app/products/calls/screens/call_screen/call_screen.tsx
+++ b/app/products/calls/screens/call_screen/call_screen.tsx
@@ -31,7 +31,6 @@ import ReactionBar from '@calls/components/reaction_bar';
import UnavailableIconWrapper from '@calls/components/unavailable_icon_wrapper';
import {usePermissionsChecker} from '@calls/hooks';
import {useCallsConfig} from '@calls/state';
-import {CallParticipant, CurrentCall} from '@calls/types/calls';
import {sortParticipants} from '@calls/utils';
import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
@@ -40,6 +39,7 @@ import {Preferences, Screens, WebsocketEvents} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import DatabaseManager from '@database/manager';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {
bottomSheet,
dismissAllModalsAndPopToScreen,
@@ -53,8 +53,11 @@ import {mergeNavigationOptions} from '@utils/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {displayUsername} from '@utils/user';
+import type {CallParticipant, CurrentCall} from '@calls/types/calls';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
export type Props = {
- componentId: string;
+ componentId: AvailableScreens;
currentCall: CurrentCall | null;
participantsDict: Dictionary;
micPermissionsGranted: boolean;
@@ -415,6 +418,10 @@ const CallScreen = ({
recordOptionTitle, stopRecording, stopRecordingOptionTitle, style, switchToThread, callThreadOptionTitle,
openChannelOptionTitle]);
+ useAndroidHardwareBackHandler(componentId, () => {
+ popTopScreen(componentId);
+ });
+
useEffect(() => {
const listener = DeviceEventEmitter.addListener(WebsocketEvents.CALLS_CALL_END, ({channelId}) => {
if (channelId === currentCall?.channelId && NavigationStore.getVisibleScreen() === componentId) {
diff --git a/app/products/calls/screens/call_screen/index.ts b/app/products/calls/screens/call_screen/index.ts
index aa59e70a43..89fc899d42 100644
--- a/app/products/calls/screens/call_screen/index.ts
+++ b/app/products/calls/screens/call_screen/index.ts
@@ -7,10 +7,10 @@ import {distinctUntilChanged, switchMap} from 'rxjs/operators';
import CallScreen from '@calls/screens/call_screen/call_screen';
import {observeCurrentCall, observeGlobalCallsState} from '@calls/state';
-import {CallParticipant} from '@calls/types/calls';
import DatabaseManager from '@database/manager';
import {observeTeammateNameDisplay, queryUsersById} from '@queries/servers/user';
+import type {CallParticipant} from '@calls/types/calls';
import type UserModel from '@typings/database/models/servers/user';
const enhanced = withObservables([], () => {
diff --git a/app/products/calls/state/channels_with_calls.ts b/app/products/calls/state/channels_with_calls.ts
index 150b8a4124..f16a16dea8 100644
--- a/app/products/calls/state/channels_with_calls.ts
+++ b/app/products/calls/state/channels_with_calls.ts
@@ -4,7 +4,7 @@
import {useEffect, useState} from 'react';
import {BehaviorSubject} from 'rxjs';
-import {ChannelsWithCalls} from '@calls/types/calls';
+import type {ChannelsWithCalls} from '@calls/types/calls';
const channelsWithCallsSubject: Dictionary> = {};
diff --git a/app/products/calls/state/current_call.ts b/app/products/calls/state/current_call.ts
index b394bfa44c..a3eec20159 100644
--- a/app/products/calls/state/current_call.ts
+++ b/app/products/calls/state/current_call.ts
@@ -4,7 +4,7 @@
import {useEffect, useState} from 'react';
import {BehaviorSubject} from 'rxjs';
-import {CurrentCall} from '@calls/types/calls';
+import type {CurrentCall} from '@calls/types/calls';
const currentCallSubject = new BehaviorSubject(null);
diff --git a/app/products/calls/utils.test.ts b/app/products/calls/utils.test.ts
index 69046c25e3..634137a619 100644
--- a/app/products/calls/utils.test.ts
+++ b/app/products/calls/utils.test.ts
@@ -3,11 +3,12 @@
import assert from 'assert';
-import {CallsConfig} from '@calls/types/calls';
import {License} from '@constants';
import {getICEServersConfigs} from './utils';
+import type {CallsConfig} from '@calls/types/calls';
+
describe('getICEServersConfigs', () => {
it('backwards compatible case, no ICEServersConfigs present', () => {
const config: CallsConfig = {
diff --git a/app/products/calls/utils.ts b/app/products/calls/utils.ts
index 2f94eefd79..dbe808cc60 100644
--- a/app/products/calls/utils.ts
+++ b/app/products/calls/utils.ts
@@ -70,7 +70,7 @@ export function isSupportedServerCalls(serverVersion?: string) {
}
export function isCallsCustomMessage(post: PostModel | Post): boolean {
- return Boolean(post.type && post.type?.startsWith(Post.POST_TYPES.CUSTOM_CALLS));
+ return Boolean(post.type && post.type === Post.POST_TYPES.CUSTOM_CALLS);
}
export function idsAreEqual(a: string[], b: string[]) {
diff --git a/app/queries/servers/channel.ts b/app/queries/servers/channel.ts
index 12e332dc68..e27eaf98df 100644
--- a/app/queries/servers/channel.ts
+++ b/app/queries/servers/channel.ts
@@ -374,7 +374,7 @@ export const queryTeamDefaultChannel = (database: Database, teamId: string) => {
};
export const queryMyChannelsByTeam = (database: Database, teamId: string, includeDeleted = false) => {
- const conditions: Q.Condition[] = [Q.where('team_id', Q.eq(teamId))];
+ const conditions: Q.Where[] = [Q.where('team_id', Q.eq(teamId))];
if (!includeDeleted) {
conditions.push(Q.where('delete_at', Q.eq(0)));
}
@@ -453,7 +453,7 @@ export const queryEmptyDirectAndGroupChannels = (database: Database) => {
};
export function observeMyChannelMentionCount(database: Database, teamId?: string, columns = ['mentions_count', 'is_unread']): Observable {
- const conditions: Q.Condition[] = [
+ const conditions: Q.Where[] = [
Q.where('delete_at', Q.eq(0)),
];
@@ -616,7 +616,7 @@ export const queryChannelsForAutocomplete = (database: Database, matchTerm: stri
Q.experimentalNestedJoin(CHANNEL_MEMBERSHIP, USER),
);
}
- const orConditions: Q.Condition[] = [
+ const orConditions: Q.Where[] = [
Q.where('display_name', Q.like(matchTerm)),
Q.where('name', Q.like(likeTerm)),
];
@@ -644,7 +644,7 @@ export const queryChannelsForAutocomplete = (database: Database, matchTerm: stri
teamsToSearch.push('');
}
- const andConditions: Q.Condition[] = [
+ const andConditions: Q.Where[] = [
Q.where('team_id', Q.oneOf(teamsToSearch)),
];
if (!isSearch) {
diff --git a/app/queries/servers/entry.ts b/app/queries/servers/entry.ts
index c2774517f3..bafed89422 100644
--- a/app/queries/servers/entry.ts
+++ b/app/queries/servers/entry.ts
@@ -3,7 +3,6 @@
import {MM_TABLES} from '@constants/database';
import DatabaseManager from '@database/manager';
-import ServerDataOperator from '@database/operator/server_data_operator';
import {prepareCategoriesAndCategoriesChannels} from './categories';
import {prepareDeleteChannel, prepareMyChannelsForTeam} from './channel';
@@ -16,6 +15,7 @@ import type {MyChannelsRequest} from '@actions/remote/channel';
import type {MyPreferencesRequest} from '@actions/remote/preference';
import type {MyTeamsRequest} from '@actions/remote/team';
import type {MyUserRequest} from '@actions/remote/user';
+import type ServerDataOperator from '@database/operator/server_data_operator';
import type {Model} from '@nozbe/watermelondb';
import type ChannelModel from '@typings/database/models/servers/channel';
import type TeamModel from '@typings/database/models/servers/team';
diff --git a/app/queries/servers/post.ts b/app/queries/servers/post.ts
index 20732b44bc..8e04c6fec0 100644
--- a/app/queries/servers/post.ts
+++ b/app/queries/servers/post.ts
@@ -20,24 +20,17 @@ const {SERVER: {POST, POSTS_IN_CHANNEL, POSTS_IN_THREAD, PREFERENCE}} = MM_TABLE
export const prepareDeletePost = async (post: PostModel): Promise => {
const preparedModels: Model[] = [post.prepareDestroyPermanently()];
- const relations: Array> = [post.drafts, post.postsInThread];
- for await (const relation of relations) {
+ const relations: Array> = [post.drafts, post.postsInThread, post.files, post.reactions];
+ for await (const models of relations) {
try {
- const model = await relation.fetch();
- if (model) {
- model.forEach((m) => preparedModels.push(m.prepareDestroyPermanently()));
- }
+ models.forEach((m) => {
+ preparedModels.push(m.prepareDestroyPermanently());
+ });
} catch {
// Record not found, do nothing
}
}
- const associatedChildren: Array|undefined> = [post.files, post.reactions];
- await Promise.all(associatedChildren.map(async (children) => {
- const models = await children?.fetch();
- models?.forEach((model) => preparedModels.push(model.prepareDestroyPermanently()));
- }));
-
// If thread exists, delete thread, participants and threadsInTeam
try {
const thread = await post.thread.fetch();
@@ -141,7 +134,7 @@ export const getLastPostInThread = async (database: Database, rootId: string) =>
};
export const queryPostsChunk = (database: Database, id: string, earliest: number, latest: number, inThread = false, includeDeleted = false, limit = 0) => {
- const conditions: Q.Condition[] = [Q.where('create_at', Q.between(earliest, latest))];
+ const conditions: Q.Where[] = [Q.where('create_at', Q.between(earliest, latest))];
if (inThread) {
conditions.push(Q.where('root_id', id));
} else {
diff --git a/app/queries/servers/system.ts b/app/queries/servers/system.ts
index 5306d7e1f2..194fe48b2e 100644
--- a/app/queries/servers/system.ts
+++ b/app/queries/servers/system.ts
@@ -158,6 +158,50 @@ export const getConfigValue = async (database: Database, key: keyof ClientConfig
return list.length ? list[0].value : undefined;
};
+export const getLastGlobalDataRetentionRun = async (database: Database) => {
+ try {
+ const data = await database.get(SYSTEM).find(SYSTEM_IDENTIFIERS.LAST_DATA_RETENTION_RUN);
+ return data?.value || 0;
+ } catch {
+ return undefined;
+ }
+};
+
+export const getGlobalDataRetentionPolicy = async (database: Database) => {
+ try {
+ const data = await database.get(SYSTEM).find(SYSTEM_IDENTIFIERS.DATA_RETENTION_POLICIES);
+ return (data?.value || {}) as GlobalDataRetentionPolicy;
+ } catch {
+ return undefined;
+ }
+};
+
+export const getGranularDataRetentionPolicies = async (database: Database) => {
+ try {
+ const data = await database.get(SYSTEM).find(SYSTEM_IDENTIFIERS.GRANULAR_DATA_RETENTION_POLICIES);
+ return (data?.value || {
+ team: [],
+ channel: [],
+ }) as {
+ team: TeamDataRetentionPolicy[];
+ channel: ChannelDataRetentionPolicy[];
+ };
+ } catch {
+ return undefined;
+ }
+};
+
+export const getIsDataRetentionEnabled = async (database: Database) => {
+ const license = await getLicense(database);
+ if (!license || !Object.keys(license)?.length) {
+ return null;
+ }
+
+ const dataRetentionEnableMessageDeletion = await getConfigValue(database, 'DataRetentionEnableMessageDeletion');
+
+ return dataRetentionEnableMessageDeletion === 'true' && license?.IsLicensed === 'true' && license?.DataRetention === 'true';
+};
+
export const observeConfig = (database: Database): Observable => {
return database.get(CONFIG).query().observeWithColumns(['value']).pipe(
switchMap((result) => of$(fromModelToClientConfig(result))),
diff --git a/app/queries/servers/terms_of_service.ts b/app/queries/servers/terms_of_service.ts
index 820ad88a5e..3b0de3f199 100644
--- a/app/queries/servers/terms_of_service.ts
+++ b/app/queries/servers/terms_of_service.ts
@@ -1,13 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Database} from '@nozbe/watermelondb';
import {of as of$, combineLatest} from 'rxjs';
import {switchMap, distinctUntilChanged} from 'rxjs/operators';
import {observeLicense, observeConfigBooleanValue, observeConfigValue, observeConfigIntValue} from './system';
import {observeCurrentUser} from './user';
+import type {Database} from '@nozbe/watermelondb';
+
export const observeShowToS = (database: Database) => {
const isLicensed = observeLicense(database).pipe(
switchMap((lcs) => (lcs ? of$(lcs.IsLicensed === 'true') : of$(false))),
diff --git a/app/queries/servers/thread.ts b/app/queries/servers/thread.ts
index 4a200ad8ef..b449e544ff 100644
--- a/app/queries/servers/thread.ts
+++ b/app/queries/servers/thread.ts
@@ -193,7 +193,7 @@ export const queryThreads = (database: Database, teamId?: string, onlyUnreads =
];
// Only get threads from available channel
- const channelCondition: Q.Condition[] = [
+ const channelCondition: Q.Where[] = [
Q.where('delete_at', 0),
];
diff --git a/app/screens/apps_form/apps_form_component.tsx b/app/screens/apps_form/apps_form_component.tsx
index 0ce62822fb..b94ddf8aff 100644
--- a/app/screens/apps_form/apps_form_component.tsx
+++ b/app/screens/apps_form/apps_form_component.tsx
@@ -5,7 +5,6 @@ import React, {useCallback, useEffect, useMemo, useReducer, useRef, useState} fr
import {useIntl} from 'react-intl';
import {Keyboard, ScrollView, Text, View} from 'react-native';
import Button from 'react-native-button';
-import {ImageResource} from 'react-native-navigation';
import {SafeAreaView} from 'react-native-safe-area-context';
import {handleGotoLocation} from '@actions/remote/command';
@@ -27,6 +26,9 @@ import {buildNavigationButton, dismissModal, setButtons} from '../navigation';
import AppsFormField from './apps_form_field';
+import type {AvailableScreens} from '@typings/screens/navigation';
+import type {ImageResource} from 'react-native-navigation';
+
const getStyleFromTheme = makeStyleSheetFromTheme((theme: Theme) => {
return {
container: {
@@ -76,7 +78,7 @@ const makeCloseButton = (icon: ImageResource) => {
export type Props = {
form: AppForm;
- componentId: string;
+ componentId: AvailableScreens;
refreshOnSelect: (field: AppField, values: AppFormValues, value: AppFormValue) => Promise>;
submit: (values: AppFormValues) => Promise>;
performLookupCall: (field: AppField, values: AppFormValues, value: AppFormValue) => Promise>;
diff --git a/app/screens/apps_form/index.tsx b/app/screens/apps_form/index.tsx
index e890f3ec22..e9fd225fde 100644
--- a/app/screens/apps_form/index.tsx
+++ b/app/screens/apps_form/index.tsx
@@ -3,19 +3,24 @@
import React, {useCallback, useState} from 'react';
import {useIntl} from 'react-intl';
+import {Keyboard} from 'react-native';
import {doAppFetchForm, doAppLookup, doAppSubmit, postEphemeralCallResponseForContext} from '@actions/remote/apps';
import {handleGotoLocation} from '@actions/remote/command';
import {AppCallResponseTypes} from '@constants/apps';
import {useServerUrl} from '@context/server';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
+import {dismissModal} from '@screens/navigation';
import {createCallRequest, makeCallErrorResponse} from '@utils/apps';
import AppsFormComponent from './apps_form_component';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
export type Props = {
form?: AppForm;
context?: AppContext;
- componentId: string;
+ componentId: AvailableScreens;
};
function AppsFormContainer({
@@ -189,6 +194,13 @@ function AppsFormContainer({
return doAppLookup(serverUrl, creq, intl);
}, [context, serverUrl, intl]);
+ const close = useCallback(() => {
+ Keyboard.dismiss();
+ dismissModal({componentId});
+ }, [componentId]);
+
+ useAndroidHardwareBackHandler(componentId, close);
+
if (!currentForm?.submit || !context) {
return null;
}
diff --git a/app/screens/bottom_sheet/index.tsx b/app/screens/bottom_sheet/index.tsx
index 1a64f68309..7a3a5772c8 100644
--- a/app/screens/bottom_sheet/index.tsx
+++ b/app/screens/bottom_sheet/index.tsx
@@ -16,6 +16,7 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import Indicator from './indicator';
+import type {AvailableScreens} from '@typings/screens/navigation';
import type {WithSpringConfig} from 'react-native-reanimated';
export {default as BottomSheetButton, BUTTON_HEIGHT} from './button';
@@ -23,7 +24,7 @@ export {default as BottomSheetContent, TITLE_HEIGHT} from './content';
type Props = {
closeButtonId?: string;
- componentId: string;
+ componentId: AvailableScreens;
contentStyle?: StyleProp;
initialSnapIndex?: number;
footerComponent?: React.FC;
@@ -38,6 +39,7 @@ const PADDING_TOP_TABLET = 8;
export const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
return {
bottomSheet: {
+ backgroundColor: theme.centerChannelBg,
borderTopStartRadius: 24,
borderTopEndRadius: 24,
shadowOffset: {
@@ -94,6 +96,10 @@ const BottomSheet = ({
const styles = getStyleSheet(theme);
const interaction = useRef();
+ useEffect(() => {
+ interaction.current = InteractionManager.createInteractionHandle();
+ }, []);
+
const bottomSheetBackgroundStyle = useMemo(() => [
styles.bottomSheetBackground,
{borderWidth: isTablet ? 0 : 1},
@@ -116,7 +122,9 @@ const BottomSheet = ({
}, [close]);
const handleAnimationStart = useCallback(() => {
- interaction.current = InteractionManager.createInteractionHandle();
+ if (!interaction.current) {
+ interaction.current = InteractionManager.createInteractionHandle();
+ }
}, []);
const handleClose = useCallback(() => {
diff --git a/app/screens/browse_channels/browse_channels.tsx b/app/screens/browse_channels/browse_channels.tsx
index f70e4a0072..0b3445cd08 100644
--- a/app/screens/browse_channels/browse_channels.tsx
+++ b/app/screens/browse_channels/browse_channels.tsx
@@ -4,7 +4,6 @@
import React, {useCallback, useEffect, useState} from 'react';
import {IntlShape, useIntl} from 'react-intl';
import {Keyboard, Platform, StyleSheet, View} from 'react-native';
-import {ImageResource, OptionsTopBarButton} from 'react-native-navigation';
import {SafeAreaView} from 'react-native-safe-area-context';
import {joinChannel, switchToChannelById} from '@actions/remote/channel';
@@ -13,6 +12,7 @@ import Search from '@components/search';
import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal, goToScreen, setButtons} from '@screens/navigation';
import {alertErrorWithFallback} from '@utils/draft';
@@ -21,7 +21,8 @@ import {changeOpacity, getKeyboardAppearanceFromTheme} from '@utils/theme';
import ChannelDropdown from './channel_dropdown';
import ChannelList from './channel_list';
-import type {NavButtons} from '@typings/screens/navigation';
+import type {AvailableScreens, NavButtons} from '@typings/screens/navigation';
+import type {ImageResource, OptionsTopBarButton} from 'react-native-navigation';
const CLOSE_BUTTON_ID = 'close-browse-channels';
const CREATE_BUTTON_ID = 'create-pub-channel';
@@ -73,7 +74,7 @@ const style = StyleSheet.create({
type Props = {
// Screen Props (do not change during the lifetime of the screen)
- componentId: string;
+ componentId: AvailableScreens;
closeButton: ImageResource;
// Properties not changing during the lifetime of the screen)
@@ -169,6 +170,7 @@ export default function BrowseChannels(props: Props) {
useNavButtonPressed(CLOSE_BUTTON_ID, componentId, close, [close]);
useNavButtonPressed(CREATE_BUTTON_ID, componentId, handleCreate, [handleCreate]);
+ useAndroidHardwareBackHandler(componentId, close);
useEffect(() => {
// Update header buttons in case anything related to the header changes
diff --git a/app/screens/browse_channels/search_handler.tsx b/app/screens/browse_channels/search_handler.tsx
index f50eb95fba..2e59bb66fd 100644
--- a/app/screens/browse_channels/search_handler.tsx
+++ b/app/screens/browse_channels/search_handler.tsx
@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useReducer, useRef, useState} from 'react';
-import {ImageResource} from 'react-native-navigation';
import {fetchArchivedChannels, fetchChannels, fetchSharedChannels, searchChannels} from '@actions/remote/channel';
import {General} from '@constants';
@@ -12,11 +11,13 @@ import useDidUpdate from '@hooks/did_update';
import BrowseChannels, {ARCHIVED, PUBLIC, SHARED} from './browse_channels';
import type MyChannelModel from '@typings/database/models/servers/my_channel';
+import type {AvailableScreens} from '@typings/screens/navigation';
+import type {ImageResource} from 'react-native-navigation';
type Props = {
// Screen Props (do not change during the lifetime of the screen)
- componentId: string;
+ componentId: AvailableScreens;
categoryId?: string;
closeButton: ImageResource;
diff --git a/app/screens/channel/channel.tsx b/app/screens/channel/channel.tsx
index bb26e3181c..2a22fcf9f4 100644
--- a/app/screens/channel/channel.tsx
+++ b/app/screens/channel/channel.tsx
@@ -2,8 +2,7 @@
// See LICENSE.txt for license information.
import React, {useCallback, useEffect, useRef, useState} from 'react';
-import {BackHandler, LayoutChangeEvent, NativeEventSubscription, StyleSheet, View} from 'react-native';
-import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
+import {LayoutChangeEvent, StyleSheet, View} from 'react-native';
import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
import CurrentCallBar from '@calls/components/current_call_bar';
@@ -13,6 +12,7 @@ import FreezeScreen from '@components/freeze_screen';
import PostDraft from '@components/post_draft';
import {Screens} from '@constants';
import {ACCESSORIES_CONTAINER_NATIVE_ID} from '@constants/post_draft';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useChannelSwitch} from '@hooks/channel_switch';
import {useAppState, useIsTablet} from '@hooks/device';
import {useDefaultHeaderHeight} from '@hooks/header';
@@ -20,15 +20,17 @@ import {useKeyboardTrackingPaused} from '@hooks/keyboard_tracking';
import {useTeamSwitch} from '@hooks/team_switch';
import {popTopScreen} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
-import NavigationStore from '@store/navigation_store';
import ChannelPostList from './channel_post_list';
import ChannelHeader from './header';
+import type {AvailableScreens} from '@typings/screens/navigation';
+import type {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
+
type ChannelProps = {
serverUrl: string;
channelId: string;
- componentId?: string;
+ componentId?: AvailableScreens;
isCallInCurrentChannel: boolean;
isInACall: boolean;
isInCurrentChannelCall: boolean;
@@ -63,24 +65,12 @@ const Channel = ({
const postDraftRef = useRef(null);
const [containerHeight, setContainerHeight] = useState(0);
const shouldRender = !switchingTeam && !switchingChannels && shouldRenderPosts && Boolean(channelId);
+ const handleBack = () => {
+ popTopScreen(componentId);
+ };
useKeyboardTrackingPaused(postDraftRef, channelId, trackKeyboardForScreens);
-
- useEffect(() => {
- let back: NativeEventSubscription|undefined;
- if (!isTablet && componentId) {
- back = BackHandler.addEventListener('hardwareBackPress', () => {
- if (NavigationStore.getVisibleScreen() === componentId) {
- popTopScreen(componentId);
- return true;
- }
-
- return false;
- });
- }
-
- return () => back?.remove();
- }, [componentId, isTablet]);
+ useAndroidHardwareBackHandler(componentId, handleBack);
const marginTop = defaultHeight + (isTablet ? 0 : -insets.top);
useEffect(() => {
diff --git a/app/screens/channel/channel_post_list/index.ts b/app/screens/channel/channel_post_list/index.ts
index c46ceb12e2..39e60924ca 100644
--- a/app/screens/channel/channel_post_list/index.ts
+++ b/app/screens/channel/channel_post_list/index.ts
@@ -5,7 +5,6 @@ import {Q} from '@nozbe/watermelondb';
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
import React from 'react';
-import {AppStateStatus} from 'react-native';
import {combineLatest, of as of$} from 'rxjs';
import {switchMap, distinctUntilChanged} from 'rxjs/operators';
@@ -19,6 +18,7 @@ import {observeIsCRTEnabled} from '@queries/servers/thread';
import ChannelPostList from './channel_post_list';
import type {WithDatabaseArgs} from '@typings/database/database';
+import type {AppStateStatus} from 'react-native';
const enhanced = withObservables(['channelId', 'forceQueryAfterAppState'], ({database, channelId}: {channelId: string; forceQueryAfterAppState: AppStateStatus} & WithDatabaseArgs) => {
const isCRTEnabledObserver = observeIsCRTEnabled(database);
diff --git a/app/screens/channel/header/header.tsx b/app/screens/channel/header/header.tsx
index d01e81232c..e98dc06e87 100644
--- a/app/screens/channel/header/header.tsx
+++ b/app/screens/channel/header/header.tsx
@@ -27,6 +27,7 @@ import OtherMentionsBadge from './other_mentions_badge';
import QuickActions, {MARGIN, SEPARATOR_HEIGHT} from './quick_actions';
import type {HeaderRightButton} from '@components/navigation_header/header';
+import type {AvailableScreens} from '@typings/screens/navigation';
type ChannelProps = {
channelId: string;
@@ -34,7 +35,7 @@ type ChannelProps = {
customStatus?: UserCustomStatus;
isCustomStatusEnabled: boolean;
isCustomStatusExpired: boolean;
- componentId?: string;
+ componentId?: AvailableScreens;
displayName: string;
isOwnDirectMessage: boolean;
memberCount?: number;
@@ -97,7 +98,7 @@ const ChannelHeader = ({
const onBackPress = useCallback(() => {
Keyboard.dismiss();
popTopScreen(componentId);
- }, []);
+ }, [componentId]);
const onTitlePress = useCallback(preventDoubleTap(() => {
let title;
diff --git a/app/screens/channel_info/app_bindings/index.tsx b/app/screens/channel_info/app_bindings/index.tsx
index e9dcffb976..b73e8e2465 100644
--- a/app/screens/channel_info/app_bindings/index.tsx
+++ b/app/screens/channel_info/app_bindings/index.tsx
@@ -11,9 +11,10 @@ import {AppBindingLocations} from '@constants/apps';
import {useAppBinding} from '@hooks/apps';
import AppsManager from '@managers/apps_manager';
import {observeCurrentTeamId} from '@queries/servers/system';
-import {WithDatabaseArgs} from '@typings/database/database';
import {preventDoubleTap} from '@utils/tap';
+import type {WithDatabaseArgs} from '@typings/database/database';
+
type Props = {
channelId: string;
teamId: string;
diff --git a/app/screens/channel_info/channel_info.tsx b/app/screens/channel_info/channel_info.tsx
index cb9c660d6c..a18c536d64 100644
--- a/app/screens/channel_info/channel_info.tsx
+++ b/app/screens/channel_info/channel_info.tsx
@@ -9,6 +9,7 @@ import ChannelInfoEnableCalls from '@calls/components/channel_info_enable_calls'
import ChannelActions from '@components/channel_actions';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal} from '@screens/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@@ -19,10 +20,12 @@ import Extra from './extra';
import Options from './options';
import Title from './title';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
channelId: string;
closeButtonId: string;
- componentId: string;
+ componentId: AvailableScreens;
type?: ChannelType;
canEnableDisableCalls: boolean;
isCallsEnabledInChannel: boolean;
@@ -66,6 +69,7 @@ const ChannelInfo = ({
}, [componentId]);
useNavButtonPressed(closeButtonId, componentId, onPressed, []);
+ useAndroidHardwareBackHandler(componentId, onPressed);
return (
{
+const Code = ({code, componentId, language, textStyle}: Props) => {
const managedConfig = useManagedConfig();
+ useAndroidHardwareBackHandler(componentId, popTopScreen);
return (
{
mounted.current = true;
diff --git a/app/screens/create_or_edit_channel/create_or_edit_channel.tsx b/app/screens/create_or_edit_channel/create_or_edit_channel.tsx
index f3d7dd5aaa..bfc4657353 100644
--- a/app/screens/create_or_edit_channel/create_or_edit_channel.tsx
+++ b/app/screens/create_or_edit_channel/create_or_edit_channel.tsx
@@ -4,7 +4,6 @@
import React, {useCallback, useEffect, useMemo, useReducer, useState} from 'react';
import {useIntl} from 'react-intl';
import {Keyboard} from 'react-native';
-import {ImageResource} from 'react-native-navigation';
import {createChannel, patchChannel as handlePatchChannel, switchToChannelById} from '@actions/remote/channel';
import CompassIcon from '@components/compass_icon';
@@ -12,6 +11,7 @@ import {General} from '@constants';
import {MIN_CHANNEL_NAME_LENGTH} from '@constants/channel';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {buildNavigationButton, dismissModal, popTopScreen, setButtons} from '@screens/navigation';
import {validateDisplayName} from '@utils/channel';
@@ -20,9 +20,11 @@ import ChannelInfoForm from './channel_info_form';
import type ChannelModel from '@typings/database/models/servers/channel';
import type ChannelInfoModel from '@typings/database/models/servers/channel_info';
+import type {AvailableScreens} from '@typings/screens/navigation';
+import type {ImageResource} from 'react-native-navigation';
type Props = {
- componentId: string;
+ componentId: AvailableScreens;
channel?: ChannelModel;
channelInfo?: ChannelInfoModel;
headerOnly?: boolean;
@@ -49,7 +51,7 @@ interface RequestAction {
error?: string;
}
-const close = (componentId: string, isModal: boolean): void => {
+const close = (componentId: AvailableScreens, isModal: boolean): void => {
Keyboard.dismiss();
if (isModal) {
dismissModal({componentId});
@@ -228,6 +230,7 @@ const CreateOrEditChannel = ({
useNavButtonPressed(CLOSE_BUTTON_ID, componentId, handleClose, [handleClose]);
useNavButtonPressed(CREATE_BUTTON_ID, componentId, onCreateChannel, [onCreateChannel]);
useNavButtonPressed(EDIT_BUTTON_ID, componentId, onUpdateChannel, [onUpdateChannel]);
+ useAndroidHardwareBackHandler(componentId, handleClose);
return (
void;
diff --git a/app/screens/custom_status/custom_status.tsx b/app/screens/custom_status/custom_status.tsx
index 367f587c2c..fc1d6d86cd 100644
--- a/app/screens/custom_status/custom_status.tsx
+++ b/app/screens/custom_status/custom_status.tsx
@@ -35,6 +35,7 @@ import CustomStatusSuggestions from './components/custom_status_suggestions';
import RecentCustomStatuses from './components/recent_custom_statuses';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
type NewStatusType = {
emoji?: string;
@@ -47,7 +48,7 @@ type Props = {
customStatusExpirySupported: boolean;
currentUser: UserModel;
recentCustomStatuses: UserCustomStatus[];
- componentId: string;
+ componentId: AvailableScreens;
}
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
diff --git a/app/screens/custom_status_clear_after/index.tsx b/app/screens/custom_status_clear_after/index.tsx
index 76aaa8aab0..e82be68e75 100644
--- a/app/screens/custom_status_clear_after/index.tsx
+++ b/app/screens/custom_status_clear_after/index.tsx
@@ -11,7 +11,6 @@ import {
Navigation,
NavigationButtonPressedEvent,
NavigationComponent,
- NavigationComponentProps,
Options,
} from 'react-native-navigation';
@@ -26,8 +25,10 @@ import ClearAfterMenuItem from './components/clear_after_menu_item';
import type {WithDatabaseArgs} from '@typings/database/database';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
-interface Props extends NavigationComponentProps {
+interface Props {
+ componentId: AvailableScreens;
currentUser: UserModel;
handleClearAfterClick: (duration: CustomStatusDuration, expiresAt: string) => void;
initialDuration: CustomStatusDuration;
diff --git a/app/screens/edit_post/edit_post.tsx b/app/screens/edit_post/edit_post.tsx
index 9aa8abe602..a565be0851 100644
--- a/app/screens/edit_post/edit_post.tsx
+++ b/app/screens/edit_post/edit_post.tsx
@@ -3,7 +3,7 @@
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
-import {Alert, Keyboard, KeyboardType, LayoutChangeEvent, Platform, SafeAreaView, useWindowDimensions, View} from 'react-native';
+import {Alert, Keyboard, LayoutChangeEvent, Platform, SafeAreaView, useWindowDimensions, View} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
import {deletePost, editPost} from '@actions/remote/post';
@@ -11,18 +11,19 @@ import Autocomplete from '@components/autocomplete';
import Loading from '@components/loading';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useAutocompleteDefaultAnimatedValues} from '@hooks/autocomplete';
import {useIsTablet, useKeyboardHeight, useModalPosition} from '@hooks/device';
import useDidUpdate from '@hooks/did_update';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import PostError from '@screens/edit_post/post_error';
import {buildNavigationButton, dismissModal, setButtons} from '@screens/navigation';
-import {switchKeyboardForCodeBlocks} from '@utils/markdown';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import EditPostInput, {EditPostInputRef} from './edit_post_input';
import type PostModel from '@typings/database/models/servers/post';
+import type {AvailableScreens} from '@typings/screens/navigation';
const AUTOCOMPLETE_SEPARATION = 8;
@@ -46,7 +47,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
const RIGHT_BUTTON = buildNavigationButton('edit-post', 'edit_post.save.button');
type EditPostProps = {
- componentId: string;
+ componentId: AvailableScreens;
closeButtonId: string;
post: PostModel;
maxPostSize: number;
@@ -54,7 +55,6 @@ type EditPostProps = {
canDelete: boolean;
}
const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttached, canDelete}: EditPostProps) => {
- const [keyboardType, setKeyboardType] = useState('default');
const [postMessage, setPostMessage] = useState(post.message);
const [cursorPosition, setCursorPosition] = useState(post.message.length);
const [errorLine, setErrorLine] = useState();
@@ -109,9 +109,6 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
}, []);
const onTextSelectionChange = useCallback((curPos: number = cursorPosition) => {
- if (Platform.OS === 'ios') {
- setKeyboardType(switchKeyboardForCodeBlocks(postMessage, curPos));
- }
setCursorPosition(curPos);
}, [cursorPosition, postMessage]);
@@ -197,13 +194,13 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
useNavButtonPressed(RIGHT_BUTTON.id, componentId, onSavePostMessage, [postMessage]);
useNavButtonPressed(closeButtonId, componentId, onClose, []);
+ useAndroidHardwareBackHandler(componentId, onClose);
const bottomSpace = (dimensions.height - containerHeight - modalPosition);
const autocompletePosition = Platform.select({
- ios: isTablet ?
- Math.max(0, keyboardHeight - bottomSpace) :
- keyboardHeight || insets.bottom,
- default: 0}) + AUTOCOMPLETE_SEPARATION;
+ ios: isTablet ? Math.max(0, keyboardHeight - bottomSpace) : keyboardHeight || insets.bottom,
+ default: 0,
+ }) + AUTOCOMPLETE_SEPARATION;
const autocompleteAvailableSpace = containerHeight - autocompletePosition;
const [animatedAutocompletePosition, animatedAutocompleteAvailableSpace] = useAutocompleteDefaultAnimatedValues(autocompletePosition, autocompleteAvailableSpace);
@@ -235,7 +232,6 @@ const EditPost = ({componentId, maxPostSize, post, closeButtonId, hasFilesAttach
}
void;
@@ -37,15 +39,17 @@ type PostInputProps = {
}
const EditPostInput = forwardRef(({
- keyboardType, message, onChangeText, onTextSelectionChange, hasError,
+ message, onChangeText, onTextSelectionChange, hasError,
}: PostInputProps, ref) => {
const intl = useIntl();
const theme = useTheme();
const styles = getStyleSheet(theme);
const {height} = useWindowDimensions();
+ const managedConfig = useManagedConfig();
const textInputHeight = (height / 2) - HEIGHT_DIFF;
+ const disableCopyAndPaste = managedConfig.copyAndPasteProtection === 'true';
- const inputRef = useRef(null);
+ const inputRef = useRef();
const inputStyle = useMemo(() => {
return [styles.input, {height: textInputHeight}];
@@ -68,17 +72,20 @@ const EditPostInput = forwardRef(({
return (
- = {
gitlab: 'GitLab',
google: 'Google Apps',
diff --git a/app/screens/edit_profile/components/form.tsx b/app/screens/edit_profile/components/form.tsx
index 1a87accb3d..0dec755a31 100644
--- a/app/screens/edit_profile/components/form.tsx
+++ b/app/screens/edit_profile/components/form.tsx
@@ -5,7 +5,6 @@ import React, {useCallback, useMemo, useRef} from 'react';
import {MessageDescriptor, useIntl} from 'react-intl';
import {Keyboard, StyleSheet, View} from 'react-native';
-import {FloatingTextInputRef} from '@components/floating_text_input_label';
import {useTheme} from '@context/theme';
import {t} from '@i18n';
@@ -13,6 +12,7 @@ import DisabledFields from './disabled_fields';
import EmailField from './email_field';
import Field from './field';
+import type {FloatingTextInputRef} from '@components/floating_text_input_label';
import type UserModel from '@typings/database/models/servers/user';
import type {FieldConfig, FieldSequence, UserInfo} from '@typings/screens/edit_profile';
diff --git a/app/screens/edit_profile/components/profile_image_picker.tsx b/app/screens/edit_profile/components/profile_image_picker.tsx
index 7aead7a2e7..815e116d4b 100644
--- a/app/screens/edit_profile/components/profile_image_picker.tsx
+++ b/app/screens/edit_profile/components/profile_image_picker.tsx
@@ -6,7 +6,6 @@ import {useIntl} from 'react-intl';
import {TouchableOpacity} from 'react-native';
import {useSafeAreaInsets} from 'react-native-safe-area-context';
-import {Client} from '@client/rest';
import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
import {ITEM_HEIGHT} from '@components/slide_up_panel_item';
@@ -23,6 +22,7 @@ import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {Client} from '@client/rest';
import type UserModel from '@typings/database/models/servers/user';
const hitSlop = {top: 100, bottom: 20, right: 20, left: 100};
diff --git a/app/screens/edit_server/form.tsx b/app/screens/edit_server/form.tsx
index 8c29b38cad..1bdc58e210 100644
--- a/app/screens/edit_server/form.tsx
+++ b/app/screens/edit_server/form.tsx
@@ -5,7 +5,6 @@ import React, {MutableRefObject, useCallback, useEffect, useRef} from 'react';
import {useIntl} from 'react-intl';
import {Keyboard, Platform, useWindowDimensions, View} from 'react-native';
import Button from 'react-native-button';
-import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
import FloatingTextInput, {FloatingTextInputRef} from '@components/floating_text_input_label';
import FormattedText from '@components/formatted_text';
@@ -17,6 +16,8 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
import {removeProtocol, stripTrailingSlashes} from '@utils/url';
+import type {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
+
type Props = {
buttonDisabled: boolean;
connecting: boolean;
diff --git a/app/screens/edit_server/index.tsx b/app/screens/edit_server/index.tsx
index aec4167a4f..7331823cf0 100644
--- a/app/screens/edit_server/index.tsx
+++ b/app/screens/edit_server/index.tsx
@@ -5,10 +5,11 @@ import React, {useCallback, useEffect, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
import {Platform, View} from 'react-native';
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
-import {Navigation} from 'react-native-navigation';
import {SafeAreaView} from 'react-native-safe-area-context';
import DatabaseManager from '@database/manager';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
+import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {getServerByDisplayName} from '@queries/app/servers';
import Background from '@screens/background';
import {dismissModal} from '@screens/navigation';
@@ -18,10 +19,11 @@ import Form from './form';
import Header from './header';
import type ServersModel from '@typings/database/models/app/servers';
+import type {AvailableScreens} from '@typings/screens/navigation';
interface ServerProps {
closeButtonId?: string;
- componentId: string;
+ componentId: AvailableScreens;
server: ServersModel;
theme: Theme;
}
@@ -49,20 +51,14 @@ const EditServer = ({closeButtonId, componentId, server, theme}: ServerProps) =>
const [displayNameError, setDisplayNameError] = useState();
const styles = getStyleSheet(theme);
+ const close = () => {
+ dismissModal({componentId});
+ };
+
useEffect(() => {
setButtonDisabled(Boolean(!displayName || displayName === server.displayName));
}, [displayName]);
- useEffect(() => {
- const navigationEvents = Navigation.events().registerNavigationButtonPressedListener(({buttonId}) => {
- if (closeButtonId && buttonId === closeButtonId) {
- dismissModal({componentId});
- }
- });
-
- return () => navigationEvents.remove();
- }, []);
-
const handleUpdate = useCallback(async () => {
if (buttonDisabled) {
return;
@@ -93,6 +89,9 @@ const EditServer = ({closeButtonId, componentId, server, theme}: ServerProps) =>
setDisplayNameError(undefined);
}, []);
+ useNavButtonPressed(closeButtonId || '', componentId, close, []);
+ useAndroidHardwareBackHandler(componentId, close);
+
return (
diff --git a/app/screens/emoji_picker/index.tsx b/app/screens/emoji_picker/index.tsx
index 002c524ea6..d6423e4ca2 100644
--- a/app/screens/emoji_picker/index.tsx
+++ b/app/screens/emoji_picker/index.tsx
@@ -10,8 +10,10 @@ import BottomSheet from '@screens/bottom_sheet';
import Picker from './picker';
import PickerFooter from './picker/footer';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
- componentId: string;
+ componentId: AvailableScreens;
onEmojiPress: (emoji: string) => void;
closeButtonId: string;
};
diff --git a/app/screens/emoji_picker/picker/header/bottom_sheet_search.tsx b/app/screens/emoji_picker/picker/header/bottom_sheet_search.tsx
index 4710997052..4200010aac 100644
--- a/app/screens/emoji_picker/picker/header/bottom_sheet_search.tsx
+++ b/app/screens/emoji_picker/picker/header/bottom_sheet_search.tsx
@@ -3,10 +3,11 @@
import {useBottomSheet} from '@gorhom/bottom-sheet';
import React, {useCallback} from 'react';
-import {NativeSyntheticEvent, TextInputFocusEventData} from 'react-native';
import SearchBar, {SearchProps} from '@components/search';
+import type {NativeSyntheticEvent, TextInputFocusEventData} from 'react-native';
+
const BottomSheetSearch = ({onFocus, ...props}: SearchProps) => {
const {expand} = useBottomSheet();
diff --git a/app/screens/emoji_picker/picker/header/skintone_selector/skintone_selector.tsx b/app/screens/emoji_picker/picker/header/skintone_selector/skintone_selector.tsx
index 5f6ffdbe68..8e5e847972 100644
--- a/app/screens/emoji_picker/picker/header/skintone_selector/skintone_selector.tsx
+++ b/app/screens/emoji_picker/picker/header/skintone_selector/skintone_selector.tsx
@@ -114,6 +114,7 @@ const SkinToneSelector = ({skinTone = 'default', containerWidth, isSearching, tu
return {
width: withDelay(isSearching.value ? 0 : 700, withTiming(isSearching.value ? 0 : 32, {duration: isSearching.value ? 50 : 300})),
marginLeft: Platform.OS === 'android' ? 10 : undefined,
+ height: 34,
};
}, []);
diff --git a/app/screens/find_channels/index.tsx b/app/screens/find_channels/index.tsx
index 264e38c6d5..37e5176c24 100644
--- a/app/screens/find_channels/index.tsx
+++ b/app/screens/find_channels/index.tsx
@@ -1,13 +1,14 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import React, {useCallback, useEffect, useMemo, useState} from 'react';
+import React, {useCallback, useMemo, useState} from 'react';
import {Keyboard, View} from 'react-native';
-import {Navigation} from 'react-native-navigation';
import SearchBar from '@components/search';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useKeyboardHeight} from '@hooks/device';
+import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal} from '@screens/navigation';
import {changeOpacity, getKeyboardAppearanceFromTheme, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
@@ -16,9 +17,11 @@ import FilteredList from './filtered_list';
import QuickOptions from './quick_options';
import UnfilteredList from './unfiltered_list';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
closeButtonId: string;
- componentId: string;
+ componentId: AvailableScreens;
}
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
@@ -70,15 +73,8 @@ const FindChannels = ({closeButtonId, componentId}: Props) => {
}
}, []);
- useEffect(() => {
- const navigationEvents = Navigation.events().registerNavigationButtonPressedListener(({buttonId}) => {
- if (closeButtonId && buttonId === closeButtonId) {
- close();
- }
- });
-
- return () => navigationEvents.remove();
- }, []);
+ useNavButtonPressed(closeButtonId, componentId, close, []);
+ useAndroidHardwareBackHandler(componentId, close);
return (
({
},
}));
-const ForgotPassword = ({serverUrl, theme}: Props) => {
+const ForgotPassword = ({componentId, serverUrl, theme}: Props) => {
const dimensions = useWindowDimensions();
const translateX = useSharedValue(dimensions.width);
const isTablet = useIsTablet();
@@ -263,11 +267,17 @@ const ForgotPassword = ({serverUrl, theme}: Props) => {
translateX.value = -dimensions.width;
},
};
- const unsubscribe = Navigation.events().registerComponentListener(listener, Screens.FORGOT_PASSWORD);
+ const unsubscribe = Navigation.events().registerComponentListener(listener, componentId);
return () => unsubscribe.remove();
}, [dimensions]);
+ useEffect(() => {
+ translateX.value = 0;
+ }, []);
+
+ useAndroidHardwareBackHandler(componentId, onReturn);
+
return (
diff --git a/app/screens/gallery/footer/download_with_action/index.tsx b/app/screens/gallery/footer/download_with_action/index.tsx
index ce8b4c5d00..ac804ca8f5 100644
--- a/app/screens/gallery/footer/download_with_action/index.tsx
+++ b/app/screens/gallery/footer/download_with_action/index.tsx
@@ -14,7 +14,7 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Share from 'react-native-share';
import {updateLocalFilePath} from '@actions/local/file';
-import {downloadFile} from '@actions/remote/file';
+import {downloadFile, downloadProfileImage} from '@actions/remote/file';
import CompassIcon from '@components/compass_icon';
import ProgressBar from '@components/progress_bar';
import Toast from '@components/toast';
@@ -22,6 +22,7 @@ import {GALLERY_FOOTER_HEIGHT} from '@constants/gallery';
import {useServerUrl} from '@context/server';
import {alertFailedToOpenDocument} from '@utils/document';
import {fileExists, getLocalFilePathFromFile, hasWriteStoragePermission} from '@utils/file';
+import {pathWithPrefix} from '@utils/files';
import {galleryItemToFileInfo} from '@utils/gallery';
import {typography} from '@utils/typography';
@@ -105,6 +106,7 @@ const DownloadWithAction = ({action, item, onDownloadSuccess, setAction, gallery
switch (item.type) {
case 'image':
+ case 'avatar':
message = intl.formatMessage({id: 'gallery.image_saved', defaultMessage: 'Image saved'});
break;
case 'video':
@@ -177,7 +179,7 @@ const DownloadWithAction = ({action, item, onDownloadSuccess, setAction, gallery
updateLocalFilePath(serverUrl, item.id, path);
Share.open({
- url: path,
+ url: pathWithPrefix('file://', path),
saveToFiles: true,
}).catch(() => {
// do nothing
@@ -191,12 +193,15 @@ const DownloadWithAction = ({action, item, onDownloadSuccess, setAction, gallery
if (mounted.current) {
try {
const applicationName = DeviceInfo.getApplicationName();
+ const cameraType = item.type === 'avatar' ? 'image' : item.type;
await CameraRoll.save(path, {
- type: item.type === 'image' ? 'photo' : 'video',
+ type: cameraType === 'image' ? 'photo' : 'video',
album: applicationName,
});
setSaved(true);
- updateLocalFilePath(serverUrl, item.id, path);
+ if (item.type !== 'avatar') {
+ updateLocalFilePath(serverUrl, item.id, path);
+ }
} catch {
setError(intl.formatMessage({id: 'gallery.save_failed', defaultMessage: 'Unable to save the file'}));
}
@@ -231,7 +236,7 @@ const DownloadWithAction = ({action, item, onDownloadSuccess, setAction, gallery
Share.open({
message: '',
title: '',
- url: path,
+ url: pathWithPrefix('file://', path),
showAppsToView: true,
}).catch(() => {
// do nothing
@@ -269,7 +274,11 @@ const DownloadWithAction = ({action, item, onDownloadSuccess, setAction, gallery
data: {path},
});
} else {
- downloadPromise.current = downloadFile(serverUrl, item.id!, path);
+ if (item.type === 'avatar') {
+ downloadPromise.current = downloadProfileImage(serverUrl, item.id!, item.lastPictureUpdate, path);
+ } else {
+ downloadPromise.current = downloadFile(serverUrl, item.id!, path);
+ }
downloadPromise.current?.then(actionToExecute).catch(() => {
setError(intl.formatMessage({id: 'download.error', defaultMessage: 'Unable to download the file. Try again later'}));
});
diff --git a/app/screens/gallery/gallery.tsx b/app/screens/gallery/gallery.tsx
index 3f294f44f9..49f6f5e1d9 100644
--- a/app/screens/gallery/gallery.tsx
+++ b/app/screens/gallery/gallery.tsx
@@ -10,12 +10,12 @@ import {useGallery} from '@context/gallery';
import {freezeOtherScreens, measureItem} from '@utils/gallery';
import DocumentRenderer from './document_renderer';
-import {ImageRendererProps} from './image_renderer';
import LightboxSwipeout, {LightboxSwipeoutRef, RenderItemInfo} from './lightbox_swipeout';
import Backdrop, {BackdropProps} from './lightbox_swipeout/backdrop';
import VideoRenderer from './video_renderer';
import GalleryViewer from './viewer';
+import type {ImageRendererProps} from './image_renderer';
import type {GalleryItemType} from '@typings/screens/gallery';
// @ts-expect-error FastImage does work with Animated.createAnimatedComponent
diff --git a/app/screens/gallery/image_renderer/index.tsx b/app/screens/gallery/image_renderer/index.tsx
index 56c50001cb..258a58dae9 100644
--- a/app/screens/gallery/image_renderer/index.tsx
+++ b/app/screens/gallery/image_renderer/index.tsx
@@ -3,11 +3,11 @@
import React, {useMemo} from 'react';
-import {PagerProps} from '../pager';
-import {RenderPageProps} from '../pager/page';
-
import ImageTransformer, {ImageTransformerProps} from './transformer';
+import type {PagerProps} from '../pager';
+import type {RenderPageProps} from '../pager/page';
+
export interface Handlers {
onTap?: ImageTransformerProps['onTap'];
onDoubleTap?: ImageTransformerProps['onDoubleTap'];
diff --git a/app/screens/gallery/index.tsx b/app/screens/gallery/index.tsx
index de8eb82fa9..6cc1ef0f0d 100644
--- a/app/screens/gallery/index.tsx
+++ b/app/screens/gallery/index.tsx
@@ -5,7 +5,7 @@ import React, {useCallback, useMemo, useRef, useState} from 'react';
import {NativeModules, useWindowDimensions, Platform} from 'react-native';
import {Navigation} from 'react-native-navigation';
-import {Screens} from '@constants';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useIsTablet} from '@hooks/device';
import {useGalleryControls} from '@hooks/gallery';
import {dismissOverlay} from '@screens/navigation';
@@ -16,15 +16,17 @@ import Gallery, {GalleryRef} from './gallery';
import Header from './header';
import type {GalleryItemType} from '@typings/screens/gallery';
+import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
+ componentId: AvailableScreens;
galleryIdentifier: string;
hideActions: boolean;
initialIndex: number;
items: GalleryItemType[];
}
-const GalleryScreen = ({galleryIdentifier, hideActions, initialIndex, items}: Props) => {
+const GalleryScreen = ({componentId, galleryIdentifier, hideActions, initialIndex, items}: Props) => {
const dim = useWindowDimensions();
const isTablet = useIsTablet();
const [localIndex, setLocalIndex] = useState(initialIndex);
@@ -55,7 +57,7 @@ const GalleryScreen = ({galleryIdentifier, hideActions, initialIndex, items}: Pr
}
freezeOtherScreens(false);
requestAnimationFrame(async () => {
- dismissOverlay(Screens.GALLERY);
+ dismissOverlay(componentId);
});
}, [isTablet]);
@@ -63,6 +65,8 @@ const GalleryScreen = ({galleryIdentifier, hideActions, initialIndex, items}: Pr
setLocalIndex(index);
}, []);
+ useAndroidHardwareBackHandler(componentId, close);
+
return (
<>
,
diff --git a/app/screens/gallery/viewer/index.tsx b/app/screens/gallery/viewer/index.tsx
index 08002bec67..a805e90dca 100644
--- a/app/screens/gallery/viewer/index.tsx
+++ b/app/screens/gallery/viewer/index.tsx
@@ -5,10 +5,10 @@ import React, {useCallback, useRef} from 'react';
import {runOnJS} from 'react-native-reanimated';
import ImageRenderer, {Handlers, ImageRendererProps} from '../image_renderer';
-import {InteractionType} from '../image_renderer/transformer';
import Pager from '../pager';
-import {RenderPageProps} from '../pager/page';
+import type {InteractionType} from '../image_renderer/transformer';
+import type {RenderPageProps} from '../pager/page';
import type {GalleryItemType} from '@typings/screens/gallery';
export interface GalleryViewerProps extends Handlers {
diff --git a/app/screens/global_threads/global_threads.tsx b/app/screens/global_threads/global_threads.tsx
index 695dc45ac8..a2cc13252c 100644
--- a/app/screens/global_threads/global_threads.tsx
+++ b/app/screens/global_threads/global_threads.tsx
@@ -10,6 +10,7 @@ import {setGlobalThreadsTab} from '@actions/local/systems';
import NavigationHeader from '@components/navigation_header';
import RoundedHeaderContext from '@components/rounded_header_context';
import {useServerUrl} from '@context/server';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useAppState, useIsTablet} from '@hooks/device';
import {useDefaultHeaderHeight} from '@hooks/header';
import {useTeamSwitch} from '@hooks/team_switch';
@@ -17,8 +18,10 @@ import {popTopScreen} from '@screens/navigation';
import ThreadsList from './threads_list';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
- componentId?: string;
+ componentId?: AvailableScreens;
globalThreadsTab: GlobalThreadsTab;
};
@@ -64,6 +67,8 @@ const GlobalThreads = ({componentId, globalThreadsTab}: Props) => {
popTopScreen(componentId);
}, [componentId]);
+ useAndroidHardwareBackHandler(componentId, onBackPress);
+
return (
-
- Test Team!
-
+
+
+ Test Team!
+
+
+
+
+
+
-
-
-
& {
diff --git a/app/screens/home/channel_list/categories_list/categories/categories.test.tsx b/app/screens/home/channel_list/categories_list/categories/categories.test.tsx
index 59b61b50e5..630c439b73 100644
--- a/app/screens/home/channel_list/categories_list/categories/categories.test.tsx
+++ b/app/screens/home/channel_list/categories_list/categories/categories.test.tsx
@@ -1,14 +1,16 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import Database from '@nozbe/watermelondb/Database';
import React from 'react';
+import {act} from 'react-test-renderer';
import {renderWithEverything} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import Categories from '.';
+import type Database from '@nozbe/watermelondb/Database';
+
describe('components/channel_list/categories', () => {
let database: Database;
beforeAll(async () => {
@@ -17,11 +19,15 @@ describe('components/channel_list/categories', () => {
});
it('render without error', () => {
+ jest.useFakeTimers();
const wrapper = renderWithEverything(
,
{database},
);
+ act(() => jest.runAllTimers());
+
expect(wrapper.toJSON()).toBeTruthy();
+ jest.useRealTimers();
});
});
diff --git a/app/screens/home/channel_list/categories_list/categories/header/__snapshots__/header.test.tsx.snap b/app/screens/home/channel_list/categories_list/categories/header/__snapshots__/header.test.tsx.snap
index 04486bdd36..95a4271e43 100644
--- a/app/screens/home/channel_list/categories_list/categories/header/__snapshots__/header.test.tsx.snap
+++ b/app/screens/home/channel_list/categories_list/categories/header/__snapshots__/header.test.tsx.snap
@@ -2,6 +2,23 @@
exports[`components/channel_list/categories/header should match snapshot 1`] = `
{
let database: Database;
diff --git a/app/screens/home/channel_list/categories_list/header/__snapshots__/header.test.tsx.snap b/app/screens/home/channel_list/categories_list/header/__snapshots__/header.test.tsx.snap
index a016dddf93..b032311b6a 100644
--- a/app/screens/home/channel_list/categories_list/header/__snapshots__/header.test.tsx.snap
+++ b/app/screens/home/channel_list/categories_list/header/__snapshots__/header.test.tsx.snap
@@ -19,46 +19,115 @@ exports[`components/channel_list/header Channel List Header Component should mat
-
- Test!
-
+
+
+ Test!
+
+
+
+
+
+
-
-
-
`;
diff --git a/app/screens/home/channel_list/categories_list/header/header.tsx b/app/screens/home/channel_list/categories_list/header/header.tsx
index ea94719e49..c776b97990 100644
--- a/app/screens/home/channel_list/categories_list/header/header.tsx
+++ b/app/screens/home/channel_list/categories_list/header/header.tsx
@@ -26,12 +26,13 @@ import LoadingUnreads from './loading_unreads';
import PlusMenu from './plus_menu';
import {SEPARATOR_HEIGHT} from './plus_menu/separator';
+const PLUS_BUTTON_SIZE = 28;
+
type Props = {
canCreateChannels: boolean;
canJoinChannels: boolean;
canInvitePeople: boolean;
displayName?: string;
- inviteId?: string;
iconPad?: boolean;
onHeaderPress?: () => void;
pushProxyStatus: string;
@@ -60,9 +61,10 @@ const getStyles = makeStyleSheetFromTheme((theme: Theme) => ({
},
plusButton: {
backgroundColor: changeOpacity(theme.sidebarText, 0.08),
- height: 28,
- width: 28,
- borderRadius: 14,
+ height: PLUS_BUTTON_SIZE,
+ width: PLUS_BUTTON_SIZE,
+ borderRadius: PLUS_BUTTON_SIZE / 2,
+ marginTop: PLUS_BUTTON_SIZE / 4,
justifyContent: 'center',
alignItems: 'center',
},
@@ -88,6 +90,13 @@ const getStyles = makeStyleSheetFromTheme((theme: Theme) => ({
justifyContent: 'space-between',
height: 40,
},
+ outsideBox: {
+ flexDirection: 'row',
+ justifyContent: 'space-between',
+ },
+ firstBox: {
+ width: '85%', // ratio derived from the design
+ },
}));
const hitSlop: Insets = {top: 10, bottom: 30, left: 20, right: 20};
@@ -97,7 +106,6 @@ const ChannelListHeader = ({
canJoinChannels,
canInvitePeople,
displayName,
- inviteId,
iconPad,
onHeaderPress,
pushProxyStatus,
@@ -124,8 +132,6 @@ const ChannelListHeader = ({
canCreateChannels={canCreateChannels}
canJoinChannels={canJoinChannels}
canInvitePeople={canInvitePeople}
- displayName={displayName}
- inviteId={inviteId}
/>
);
};
@@ -171,59 +177,63 @@ const ChannelListHeader = ({
let header;
if (displayName) {
header = (
- <>
-
-
-
-
- {displayName}
-
-
-
-
-
-
-
-
-
- {serverDisplayName}
-
- {(pushProxyStatus !== PUSH_PROXY_STATUS_VERIFIED) && (
-
+
+
+
-
-
- )}
-
+
+
+ {displayName}
+
+
+
+
+
+
+ {serverDisplayName}
+
+ {(pushProxyStatus !== PUSH_PROXY_STATUS_VERIFIED) && (
+
+
+
+ )}
+
+
- >
+
+
+
+
);
} else {
header = (
diff --git a/app/screens/home/channel_list/categories_list/header/index.ts b/app/screens/home/channel_list/categories_list/header/index.ts
index 4d638cf3dc..1aa6d23ebf 100644
--- a/app/screens/home/channel_list/categories_list/header/index.ts
+++ b/app/screens/home/channel_list/categories_list/header/index.ts
@@ -52,9 +52,6 @@ const enhanced = withObservables([], ({database}: WithDatabaseArgs) => {
displayName: team.pipe(
switchMap((t) => of$(t?.displayName)),
),
- inviteId: team.pipe(
- switchMap((t) => of$(t?.inviteId)),
- ),
pushProxyStatus: observePushVerificationStatus(database),
};
});
diff --git a/app/screens/home/channel_list/categories_list/header/plus_menu/index.tsx b/app/screens/home/channel_list/categories_list/header/plus_menu/index.tsx
index 4fabba5a9d..61b8a78aab 100644
--- a/app/screens/home/channel_list/categories_list/header/plus_menu/index.tsx
+++ b/app/screens/home/channel_list/categories_list/header/plus_menu/index.tsx
@@ -3,13 +3,9 @@
import React, {useCallback} from 'react';
import {useIntl} from 'react-intl';
-import {Platform} from 'react-native';
-import Share from 'react-native-share';
-import {ShareOptions} from 'react-native-share/lib/typescript/types';
import CompassIcon from '@components/compass_icon';
import {Screens} from '@constants';
-import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {dismissBottomSheet, showModal} from '@screens/navigation';
@@ -20,20 +16,17 @@ type Props = {
canCreateChannels: boolean;
canJoinChannels: boolean;
canInvitePeople: boolean;
- displayName?: string;
- inviteId?: string;
}
-const PlusMenuList = ({canCreateChannels, canJoinChannels, canInvitePeople, displayName, inviteId}: Props) => {
+const PlusMenuList = ({canCreateChannels, canJoinChannels, canInvitePeople}: Props) => {
const intl = useIntl();
const theme = useTheme();
- const serverUrl = useServerUrl();
const browseChannels = useCallback(async () => {
await dismissBottomSheet();
const title = intl.formatMessage({id: 'browse_channels.title', defaultMessage: 'Browse channels'});
- const closeButton = await CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor);
+ const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor);
showModal(Screens.BROWSE_CHANNELS, title, {
closeButton,
@@ -51,64 +44,20 @@ const PlusMenuList = ({canCreateChannels, canJoinChannels, canInvitePeople, disp
await dismissBottomSheet();
const title = intl.formatMessage({id: 'create_direct_message.title', defaultMessage: 'Create Direct Message'});
- const closeButton = await CompassIcon.getImageSource('close', 24, theme.sidebarHeaderTextColor);
+ const closeButton = CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor);
showModal(Screens.CREATE_DIRECT_MESSAGE, title, {
closeButton,
});
}, [intl, theme]);
- const invitePeopleToTeam = async () => {
+ const invitePeopleToTeam = useCallback(async () => {
await dismissBottomSheet();
- const url = `${serverUrl}/signup_user_complete/?id=${inviteId}`;
- const title = intl.formatMessage({id: 'invite_people_to_team.title', defaultMessage: 'Join the {team} team'}, {team: displayName});
- const message = intl.formatMessage({id: 'invite_people_to_team.message', defaultMessage: 'Here’s a link to collaborate and communicate with us on Mattermost.'});
- const icon = 'data:/;base64,';
-
- const options: ShareOptions = Platform.select({
- ios: {
- activityItemSources: [
- {
- placeholderItem: {
- type: 'url',
- content: url,
- },
- item: {
- default: {
- type: 'text',
- content: `${message} ${url}`,
- },
- copyToPasteBoard: {
- type: 'url',
- content: url,
- },
- },
- subject: {
- default: title,
- },
- linkMetadata: {
- originalUrl: url,
- url,
- title,
- icon,
- },
- },
- ],
- },
- default: {
- title,
- subject: title,
- url,
- showAppsToView: true,
- },
- });
-
- Share.open(
- options,
- ).catch(() => {
- // do nothing
- });
- };
+ showModal(
+ Screens.INVITE,
+ intl.formatMessage({id: 'invite.title', defaultMessage: 'Invite'}),
+ );
+ }, [intl, theme]);
return (
<>
diff --git a/app/screens/home/channel_list/categories_list/index.test.tsx b/app/screens/home/channel_list/categories_list/index.test.tsx
index d941a826f3..e6d8f3586a 100644
--- a/app/screens/home/channel_list/categories_list/index.test.tsx
+++ b/app/screens/home/channel_list/categories_list/index.test.tsx
@@ -1,17 +1,19 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import Database from '@nozbe/watermelondb/Database';
import React from 'react';
+import {act} from 'react-test-renderer';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
-import ServerDataOperator from '@database/operator/server_data_operator';
import {getTeamById} from '@queries/servers/team';
import {renderWithEverything} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import CategoriesList from '.';
+import type ServerDataOperator from '@database/operator/server_data_operator';
+import type Database from '@nozbe/watermelondb/Database';
+
describe('components/categories_list', () => {
let database: Database;
let operator: ServerDataOperator;
@@ -41,6 +43,7 @@ describe('components/categories_list', () => {
});
it('should render channel list with thread menu', () => {
+ jest.useFakeTimers();
const wrapper = renderWithEverything(
{
/>,
{database},
);
+ act(() => {
+ jest.runAllTimers();
+ });
expect(wrapper.toJSON()).toBeTruthy();
+ jest.useRealTimers();
});
it('should render team error', async () => {
@@ -59,6 +66,7 @@ describe('components/categories_list', () => {
prepareRecordsOnly: false,
});
+ jest.useFakeTimers();
const wrapper = renderWithEverything(
{
{database},
);
+ act(() => {
+ jest.runAllTimers();
+ });
expect(wrapper.toJSON()).toMatchSnapshot();
+ jest.useRealTimers();
await operator.handleSystem({
systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: TestHelper.basicTeam!.id}],
@@ -77,6 +89,7 @@ describe('components/categories_list', () => {
});
it('should render channels error', () => {
+ jest.useFakeTimers();
const wrapper = renderWithEverything(
{
/>,
{database},
);
+ act(() => {
+ jest.runAllTimers();
+ });
expect(wrapper.toJSON()).toMatchSnapshot();
});
});
diff --git a/app/screens/home/channel_list/categories_list/subheader/search_field/__snapshots__/index.test.tsx.snap b/app/screens/home/channel_list/categories_list/subheader/search_field/__snapshots__/index.test.tsx.snap
index 37c9b7a893..dfc0b22461 100644
--- a/app/screens/home/channel_list/categories_list/subheader/search_field/__snapshots__/index.test.tsx.snap
+++ b/app/screens/home/channel_list/categories_list/subheader/search_field/__snapshots__/index.test.tsx.snap
@@ -2,6 +2,14 @@
exports[`Search Field should match snapshot 1`] = `
{
viewRef.current?.measureInWindow((x, y, w, h) => {
const bounds: TutorialItemBounds = {
- startX: x - 20,
+ startX: x,
startY: y,
- endX: x + w + 20,
+ endX: x + w,
endY: y + h,
};
if (viewRef.current) {
- setShowTutorial(true);
setItemBounds(bounds);
}
});
};
+ const onLayout = useCallback(() => {
+ swipeable.current?.close();
+ startTutorial();
+ }, []);
+
const containerStyle = useMemo(() => {
const style: StyleProp = [styles.container];
if (isActive) {
@@ -344,12 +348,16 @@ const ServerItem = ({
}, [server.lastActiveAt, isActive]);
useEffect(() => {
- let time: NodeJS.Timeout;
if (highlight && !tutorialWatched) {
- time = setTimeout(startTutorial, 650);
+ if (isTablet) {
+ setShowTutorial(true);
+ return;
+ }
+ InteractionManager.runAfterInteractions(() => {
+ setShowTutorial(true);
+ });
}
- return () => clearTimeout(time);
- }, [highlight, tutorialWatched]);
+ }, [highlight, tutorialWatched, isTablet]);
const serverItem = `server_list.server_item.${server.displayName.replace(/ /g, '_').toLocaleLowerCase()}`;
const serverItemTestId = isActive ? `${serverItem}.active` : `${serverItem}.inactive`;
@@ -466,6 +474,8 @@ const ServerItem = ({
itemBounds={itemBounds}
onDismiss={handleDismissTutorial}
onShow={handleShowTutorial}
+ onLayout={onLayout}
+ itemBorderRadius={8}
>
preference.name);
diff --git a/app/screens/home/search/initial/initial.tsx b/app/screens/home/search/initial/initial.tsx
index 76b0a3611f..dc0c8dd4ec 100644
--- a/app/screens/home/search/initial/initial.tsx
+++ b/app/screens/home/search/initial/initial.tsx
@@ -2,15 +2,14 @@
// See LICENSE.txt for license information.
import React, {Dispatch, RefObject, SetStateAction} from 'react';
-import Animated from 'react-native-reanimated';
-
-import {SearchRef} from '@components/search';
-import {TeamModel} from '@database/models/server';
import Modifiers from './modifiers';
import RecentSearches from './recent_searches';
+import type {SearchRef} from '@components/search';
+import type TeamModel from '@typings/database/models/servers/team';
import type TeamSearchHistoryModel from '@typings/database/models/servers/team_search_history';
+import type Animated from 'react-native-reanimated';
type Props = {
recentSearches: TeamSearchHistoryModel[];
diff --git a/app/screens/home/search/initial/modifiers/index.tsx b/app/screens/home/search/initial/modifiers/index.tsx
index 11f73c3ef2..e1896c8100 100644
--- a/app/screens/home/search/initial/modifiers/index.tsx
+++ b/app/screens/home/search/initial/modifiers/index.tsx
@@ -7,9 +7,7 @@ import {View} from 'react-native';
import Animated, {useSharedValue, useAnimatedStyle, withTiming} from 'react-native-reanimated';
import FormattedText from '@components/formatted_text';
-import {SearchRef} from '@components/search';
import {useTheme} from '@context/theme';
-import {TeamModel} from '@database/models/server';
import TeamPickerIcon from '@screens/home/search/team_picker_icon';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
@@ -17,6 +15,9 @@ import {typography} from '@utils/typography';
import Modifier, {ModifierItem} from './modifier';
import ShowMoreButton from './show_more';
+import type {SearchRef} from '@components/search';
+import type TeamModel from '@typings/database/models/servers/team';
+
const MODIFIER_LABEL_HEIGHT = 48;
const TEAM_PICKER_ICON_SIZE = 32;
const NUM_ITEMS_BEFORE_EXPAND = 4;
diff --git a/app/screens/home/search/initial/modifiers/modifier.tsx b/app/screens/home/search/initial/modifiers/modifier.tsx
index bb75cb3f90..de83ed113a 100644
--- a/app/screens/home/search/initial/modifiers/modifier.tsx
+++ b/app/screens/home/search/initial/modifiers/modifier.tsx
@@ -5,9 +5,10 @@ import React, {Dispatch, RefObject, SetStateAction, useCallback} from 'react';
import {Platform, StyleSheet} from 'react-native';
import OptionItem from '@components/option_item';
-import {SearchRef} from '@components/search';
import {preventDoubleTap} from '@utils/tap';
+import type {SearchRef} from '@components/search';
+
const styles = StyleSheet.create({
container: {
marginLeft: 20,
diff --git a/app/screens/home/search/results/file_options/mobile_options.tsx b/app/screens/home/search/results/file_options/mobile_options.tsx
index cb8d305ea1..cd8e784b13 100644
--- a/app/screens/home/search/results/file_options/mobile_options.tsx
+++ b/app/screens/home/search/results/file_options/mobile_options.tsx
@@ -1,16 +1,17 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import React from 'react';
-import {EdgeInsets} from 'react-native-safe-area-context';
import {ITEM_HEIGHT} from '@components/slide_up_panel_item';
import {bottomSheet} from '@screens/navigation';
-import {GalleryAction} from '@typings/screens/gallery';
import {bottomSheetSnapPoint} from '@utils/helpers';
import Header, {HEADER_HEIGHT} from './header';
import OptionMenus from './option_menus';
+import type {GalleryAction} from '@typings/screens/gallery';
+import type {EdgeInsets} from 'react-native-safe-area-context';
+
type Props = {
fileInfo: FileInfo;
insets: EdgeInsets;
diff --git a/app/screens/home/search/results/file_options/option_menus/option_menus.tsx b/app/screens/home/search/results/file_options/option_menus/option_menus.tsx
index ef1a552d46..ce0d2be8ad 100644
--- a/app/screens/home/search/results/file_options/option_menus/option_menus.tsx
+++ b/app/screens/home/search/results/file_options/option_menus/option_menus.tsx
@@ -8,7 +8,8 @@ import OptionItem from '@components/option_item';
import {useServerUrl} from '@context/server';
import {useIsTablet} from '@hooks/device';
import {dismissBottomSheet} from '@screens/navigation';
-import {GalleryAction} from '@typings/screens/gallery';
+
+import type {GalleryAction} from '@typings/screens/gallery';
type Props = {
canDownloadFiles?: boolean;
diff --git a/app/screens/home/search/results/file_options/tablet_options.tsx b/app/screens/home/search/results/file_options/tablet_options.tsx
index 9dc4641c76..d21d7bf20b 100644
--- a/app/screens/home/search/results/file_options/tablet_options.tsx
+++ b/app/screens/home/search/results/file_options/tablet_options.tsx
@@ -5,13 +5,13 @@ import {Overlay} from 'react-native-elements';
import {ITEM_HEIGHT} from '@components/option_item';
import {useTheme} from '@context/theme';
-import {GalleryAction} from '@typings/screens/gallery';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
-import {XyOffset} from '../file_result';
-
import OptionMenus from './option_menus';
+import type {XyOffset} from '../file_result';
+import type {GalleryAction} from '@typings/screens/gallery';
+
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
tablet: {
backgroundColor: theme.centerChannelBg,
diff --git a/app/screens/home/search/results/file_result.tsx b/app/screens/home/search/results/file_result.tsx
index 119612f8c7..9a536e71b0 100644
--- a/app/screens/home/search/results/file_result.tsx
+++ b/app/screens/home/search/results/file_result.tsx
@@ -6,11 +6,12 @@ import {Dimensions, StyleSheet, View} from 'react-native';
import File from '@components/files/file';
import {useIsTablet} from '@hooks/device';
-import {GalleryAction} from '@typings/screens/gallery';
import {getViewPortWidth} from '@utils/images';
import TabletOptions from './file_options/tablet_options';
+import type {GalleryAction} from '@typings/screens/gallery';
+
export type XyOffset = {x: number; y: number} | undefined;
const styles = StyleSheet.create({
diff --git a/app/screens/home/search/results/file_results.tsx b/app/screens/home/search/results/file_results.tsx
index d1e2aa08c6..7912cac365 100644
--- a/app/screens/home/search/results/file_results.tsx
+++ b/app/screens/home/search/results/file_results.tsx
@@ -9,7 +9,6 @@ import NoResultsWithTerm from '@components/no_results_with_term';
import {useTheme} from '@context/theme';
import {useIsTablet} from '@hooks/device';
import {useImageAttachments} from '@hooks/files';
-import {GalleryAction} from '@typings/screens/gallery';
import {
getChannelNamesWithID,
getFileInfosIndexes,
@@ -26,6 +25,7 @@ import Toasts from './file_options/toasts';
import FileResult from './file_result';
import type ChannelModel from '@typings/database/models/servers/channel';
+import type {GalleryAction} from '@typings/screens/gallery';
type Props = {
canDownloadFiles: boolean;
@@ -128,6 +128,8 @@ const FileResults = ({
data={orderedFileInfos}
indicatorStyle='black'
initialNumToRender={10}
+
+ //@ts-expect-error key not defined in types
listKey={'files'}
maxToRenderPerBatch={5}
nestedScrollEnabled={true}
diff --git a/app/screens/home/search/results/header.tsx b/app/screens/home/search/results/header.tsx
index 0ba4fd47fb..17abcdfdb5 100644
--- a/app/screens/home/search/results/header.tsx
+++ b/app/screens/home/search/results/header.tsx
@@ -8,7 +8,6 @@ import {useSafeAreaInsets} from 'react-native-safe-area-context';
import Badge from '@components/badge';
import CompassIcon from '@components/compass_icon';
import {useTheme} from '@context/theme';
-import {TeamModel} from '@database/models/server';
import {useIsTablet} from '@hooks/device';
import {TITLE_SEPARATOR_MARGIN, TITLE_SEPARATOR_MARGIN_TABLET, TITLE_HEIGHT} from '@screens/bottom_sheet/content';
import TeamPickerIcon from '@screens/home/search/team_picker_icon';
@@ -21,6 +20,8 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import Filter, {DIVIDERS_HEIGHT, FILTER_ITEM_HEIGHT, NUMBER_FILTER_ITEMS} from './filter';
import SelectButton from './header_button';
+import type TeamModel from '@typings/database/models/servers/team';
+
type Props = {
onTabSelect: (tab: TabType) => void;
onFilterChanged: (filter: FileFilter) => void;
diff --git a/app/screens/home/search/results/post_results.tsx b/app/screens/home/search/results/post_results.tsx
index 1d92d16ab9..92edfb4a9c 100644
--- a/app/screens/home/search/results/post_results.tsx
+++ b/app/screens/home/search/results/post_results.tsx
@@ -76,6 +76,8 @@ const PostResults = ({
data={orderedPosts}
indicatorStyle='black'
initialNumToRender={5}
+
+ //@ts-expect-error key not defined in types
listKey={'posts'}
maxToRenderPerBatch={5}
nestedScrollEnabled={true}
diff --git a/app/screens/home/search/search.tsx b/app/screens/home/search/search.tsx
index c9aadd2310..ebdaf21d46 100644
--- a/app/screens/home/search/search.tsx
+++ b/app/screens/home/search/search.tsx
@@ -4,7 +4,7 @@
import {useIsFocused, useNavigation} from '@react-navigation/native';
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
-import {FlatList, LayoutChangeEvent, Platform, StyleSheet, ViewProps} from 'react-native';
+import {FlatList, LayoutChangeEvent, Platform, StyleSheet, ViewStyle} from 'react-native';
import Animated, {useAnimatedStyle, useDerivedValue, withTiming} from 'react-native-reanimated';
import {Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
@@ -16,11 +16,9 @@ import FreezeScreen from '@components/freeze_screen';
import Loading from '@components/loading';
import NavigationHeader from '@components/navigation_header';
import RoundedHeaderContext from '@components/rounded_header_context';
-import {SearchRef} from '@components/search';
import {BOTTOM_TAB_HEIGHT} from '@constants/view';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
-import {TeamModel} from '@database/models/server';
import {useKeyboardHeight} from '@hooks/device';
import useDidUpdate from '@hooks/did_update';
import {useCollapsibleHeader} from '@hooks/header';
@@ -31,7 +29,9 @@ import Initial from './initial';
import Results from './results';
import Header from './results/header';
+import type {SearchRef} from '@components/search';
import type PostModel from '@typings/database/models/servers/post';
+import type TeamModel from '@typings/database/models/servers/team';
const EDGES: Edge[] = ['bottom', 'left', 'right'];
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
@@ -227,12 +227,12 @@ const SearchScreen = ({teamId, teams}: Props) => {
handleSearch(newTeamId, lastSearchedValue);
}, [lastSearchedValue, handleSearch]);
- const initialContainerStyle = useMemo(() => {
+ const initialContainerStyle: ViewStyle = useMemo(() => {
return {
paddingTop: scrollPaddingTop,
flexGrow: 1,
justifyContent: (resultsLoading || loading) ? 'center' : 'flex-start',
- } as ViewProps;
+ };
}, [loading, resultsLoading, scrollPaddingTop]);
const renderInitialOrLoadingItem = useCallback(() => {
diff --git a/app/screens/in_app_notification/index.tsx b/app/screens/in_app_notification/index.tsx
index 2e9f718d12..1e2c2e5c23 100644
--- a/app/screens/in_app_notification/index.tsx
+++ b/app/screens/in_app_notification/index.tsx
@@ -20,8 +20,10 @@ import Icon from './icon';
import Server from './server';
import Title from './title';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type InAppNotificationProps = {
- componentId: string;
+ componentId: AvailableScreens;
notification: NotificationWithData;
serverName?: string;
serverUrl: string;
diff --git a/app/screens/index.tsx b/app/screens/index.tsx
index b4249035e1..a95e48dbbe 100644
--- a/app/screens/index.tsx
+++ b/app/screens/index.tsx
@@ -133,6 +133,9 @@ Navigation.setLazyComponentRegistrator((screenName) => {
case Screens.INTERACTIVE_DIALOG:
screen = withServerDatabase(require('@screens/interactive_dialog').default);
break;
+ case Screens.INVITE:
+ screen = withServerDatabase(require('@screens/invite').default);
+ break;
case Screens.IN_APP_NOTIFICATION: {
const notificationScreen = require('@screens/in_app_notification').default;
Navigation.registerComponent(Screens.IN_APP_NOTIFICATION, () =>
diff --git a/app/screens/integration_selector/channel_list_row/__snapshots__/index.test.tsx.snap b/app/screens/integration_selector/channel_list_row/__snapshots__/index.test.tsx.snap
index cda0c91b2c..f27cb3e51c 100644
--- a/app/screens/integration_selector/channel_list_row/__snapshots__/index.test.tsx.snap
+++ b/app/screens/integration_selector/channel_list_row/__snapshots__/index.test.tsx.snap
@@ -12,6 +12,23 @@ exports[`components/integration_selector/channel_list_row should match snapshot
}
>
{
let database: Database;
const channel: Channel = {
diff --git a/app/screens/integration_selector/custom_list/index.test.tsx b/app/screens/integration_selector/custom_list/index.test.tsx
index 66cd540c09..a02dea405d 100644
--- a/app/screens/integration_selector/custom_list/index.test.tsx
+++ b/app/screens/integration_selector/custom_list/index.test.tsx
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import Database from '@nozbe/watermelondb/Database';
import React from 'react';
import {Text} from 'react-native';
@@ -11,6 +10,8 @@ import TestHelper from '@test/test_helper';
import CustomList from '.';
+import type Database from '@nozbe/watermelondb/Database';
+
describe('components/integration_selector/custom_list', () => {
let database: Database;
beforeAll(async () => {
diff --git a/app/screens/integration_selector/custom_list_row/__snapshots__/index.test.tsx.snap b/app/screens/integration_selector/custom_list_row/__snapshots__/index.test.tsx.snap
index 17dfeb003e..a3b3a1a3d4 100644
--- a/app/screens/integration_selector/custom_list_row/__snapshots__/index.test.tsx.snap
+++ b/app/screens/integration_selector/custom_list_row/__snapshots__/index.test.tsx.snap
@@ -2,6 +2,23 @@
exports[`components/integration_selector/custom_list_row should match snapshot 1`] = `
{
let database: Database;
beforeAll(async () => {
diff --git a/app/screens/integration_selector/integration_selector.tsx b/app/screens/integration_selector/integration_selector.tsx
index 06339c6ac9..2a29f6ab59 100644
--- a/app/screens/integration_selector/integration_selector.tsx
+++ b/app/screens/integration_selector/integration_selector.tsx
@@ -14,6 +14,7 @@ import {General, View as ViewConstants} from '@constants';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
import {debounce} from '@helpers/api/general';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {t} from '@i18n';
import {
@@ -29,6 +30,8 @@ import CustomList from './custom_list';
import OptionListRow from './option_list_row';
import SelectedOptions from './selected_options';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type DataType = DialogOption | Channel | UserProfile;
type DataTypeList = DialogOption[] | Channel[] | UserProfile[];
type Selection = DataType | DataTypeList;
@@ -115,7 +118,7 @@ export type Props = {
selected: SelectedDialogValue;
theme: Theme;
teammateNameDisplay: string;
- componentId: string;
+ componentId: AvailableScreens;
}
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
@@ -344,6 +347,7 @@ function IntegrationSelector(
// Effects
useNavButtonPressed(SUBMIT_BUTTON_ID, componentId, onHandleMultiselectSubmit, [onHandleMultiselectSubmit]);
+ useAndroidHardwareBackHandler(componentId, close);
useEffect(() => {
return () => {
diff --git a/app/screens/integration_selector/option_list_row/__snapshots__/index.test.tsx.snap b/app/screens/integration_selector/option_list_row/__snapshots__/index.test.tsx.snap
index ef481625d8..04e4e0e5a2 100644
--- a/app/screens/integration_selector/option_list_row/__snapshots__/index.test.tsx.snap
+++ b/app/screens/integration_selector/option_list_row/__snapshots__/index.test.tsx.snap
@@ -13,6 +13,23 @@ exports[`components/integration_selector/option_list_row should match snapshot f
}
>
{
let database: Database;
beforeAll(async () => {
diff --git a/app/screens/integration_selector/selected_option/__snapshots__/index.test.tsx.snap b/app/screens/integration_selector/selected_option/__snapshots__/index.test.tsx.snap
index 86293ea8ba..32747e02c6 100644
--- a/app/screens/integration_selector/selected_option/__snapshots__/index.test.tsx.snap
+++ b/app/screens/integration_selector/selected_option/__snapshots__/index.test.tsx.snap
@@ -31,6 +31,23 @@ exports[`components/integration_selector/selected_option should match snapshot f
channel
{
let database: Database;
beforeAll(async () => {
diff --git a/app/screens/integration_selector/selected_options/__snapshots__/index.test.tsx.snap b/app/screens/integration_selector/selected_options/__snapshots__/index.test.tsx.snap
index 57e7383a07..c975db49aa 100644
--- a/app/screens/integration_selector/selected_options/__snapshots__/index.test.tsx.snap
+++ b/app/screens/integration_selector/selected_options/__snapshots__/index.test.tsx.snap
@@ -51,6 +51,23 @@ exports[`components/integration_selector/selected_options should match snapshot
channel
{
let database: Database;
beforeAll(async () => {
diff --git a/app/screens/interactive_dialog/dialog_element.tsx b/app/screens/interactive_dialog/dialog_element.tsx
index 1b29c664e4..573c80b825 100644
--- a/app/screens/interactive_dialog/dialog_element.tsx
+++ b/app/screens/interactive_dialog/dialog_element.tsx
@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import React, {useCallback} from 'react';
-import {KeyboardTypeOptions} from 'react-native';
import AutocompleteSelector from '@components/autocomplete_selector';
import BoolSetting from '@components/settings/bool_setting';
@@ -10,6 +9,8 @@ import RadioSetting from '@components/settings/radio_setting';
import TextSetting from '@components/settings/text_setting';
import {selectKeyboardType as selectKB} from '@utils/integrations';
+import type {KeyboardTypeOptions} from 'react-native';
+
const TEXT_DEFAULT_MAX_LENGTH = 150;
const TEXTAREA_DEFAULT_MAX_LENGTH = 3000;
diff --git a/app/screens/interactive_dialog/index.tsx b/app/screens/interactive_dialog/index.tsx
index b89f2a646f..d8f56a3cc9 100644
--- a/app/screens/interactive_dialog/index.tsx
+++ b/app/screens/interactive_dialog/index.tsx
@@ -12,6 +12,7 @@ import CompassIcon from '@components/compass_icon';
import ErrorText from '@components/error_text';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {buildNavigationButton, dismissModal, setButtons} from '@screens/navigation';
import {checkDialogElementForError, checkIfErrorsMatchElements} from '@utils/integrations';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@@ -19,6 +20,8 @@ import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import DialogElement from './dialog_element';
import DialogIntroductionText from './dialog_introduction_text';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
return {
container: {
@@ -40,7 +43,7 @@ const getStyleFromTheme = makeStyleSheetFromTheme((theme) => {
type Props = {
config: InteractiveDialogConfig;
- componentId: string;
+ componentId: AvailableScreens;
}
const close = () => {
@@ -217,6 +220,8 @@ function InteractiveDialog({
};
}, [serverUrl, url, callbackId, state, handleSubmit, submitting]);
+ useAndroidHardwareBackHandler(componentId, close);
+
return (
{
+ const team = observeCurrentTeam(database);
+
+ return {
+ teamId: team.pipe(
+ switchMap((t) => of$(t?.id)),
+ ),
+ teamDisplayName: team.pipe(
+ switchMap((t) => of$(t?.displayName)),
+ ),
+ teamLastIconUpdate: team.pipe(
+ switchMap((t) => of$(t?.lastTeamIconUpdatedAt)),
+ ),
+ teamInviteId: team.pipe(
+ switchMap((t) => of$(t?.inviteId)),
+ ),
+ teammateNameDisplay: observeTeammateNameDisplay(database),
+ isAdmin: observeCurrentUser(database).pipe(
+ map((user) => isSystemAdmin(user?.roles || '')),
+ distinctUntilChanged(),
+ ),
+ };
+});
+
+export default withDatabase(enhanced(Invite));
diff --git a/app/screens/invite/invite.tsx b/app/screens/invite/invite.tsx
new file mode 100644
index 0000000000..8f8640fea1
--- /dev/null
+++ b/app/screens/invite/invite.tsx
@@ -0,0 +1,419 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {useCallback, useEffect, useState, useRef} from 'react';
+import {IntlShape, useIntl} from 'react-intl';
+import {Keyboard, View, LayoutChangeEvent} from 'react-native';
+import {SafeAreaView} from 'react-native-safe-area-context';
+
+import {getTeamMembersByIds, addUsersToTeam, sendEmailInvitesToTeam} from '@actions/remote/team';
+import {searchProfiles} from '@actions/remote/user';
+import CompassIcon from '@components/compass_icon';
+import Loading from '@components/loading';
+import {ServerErrors} from '@constants';
+import {useServerUrl} from '@context/server';
+import {useTheme} from '@context/theme';
+import {useModalPosition} from '@hooks/device';
+import useNavButtonPressed from '@hooks/navigation_button_pressed';
+import {dismissModal, setButtons} from '@screens/navigation';
+import {isEmail} from '@utils/helpers';
+import {mergeNavigationOptions} from '@utils/navigation';
+import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme';
+import {isGuest} from '@utils/user';
+
+import Selection from './selection';
+import Summary from './summary';
+
+import type {AvailableScreens, NavButtons} from '@typings/screens/navigation';
+import type {OptionsTopBarButton} from 'react-native-navigation';
+
+const CLOSE_BUTTON_ID = 'close-invite';
+const SEND_BUTTON_ID = 'send-invite';
+const TIMEOUT_MILLISECONDS = 200;
+const DEFAULT_RESULT = {sent: [], notSent: []};
+
+const makeLeftButton = (theme: Theme): OptionsTopBarButton => ({
+ id: CLOSE_BUTTON_ID,
+ icon: CompassIcon.getImageSourceSync('close', 24, theme.sidebarHeaderTextColor),
+ testID: 'invite.close.button',
+});
+
+const makeRightButton = (theme: Theme, formatMessage: IntlShape['formatMessage'], enabled: boolean): OptionsTopBarButton => ({
+ id: SEND_BUTTON_ID,
+ text: formatMessage({id: 'invite.send_invite', defaultMessage: 'Send'}),
+ showAsAction: 'always',
+ testID: 'invite.send.button',
+ color: theme.sidebarHeaderTextColor,
+ disabledColor: changeOpacity(theme.sidebarHeaderTextColor, 0.4),
+ enabled,
+});
+
+const closeModal = async () => {
+ Keyboard.dismiss();
+ await dismissModal();
+};
+
+const getStyleSheet = makeStyleSheetFromTheme(() => {
+ return {
+ container: {
+ flex: 1,
+ flexDirection: 'column',
+ },
+ loadingContainer: {
+ flex: 1,
+ justifyContent: 'center',
+ alignItems: 'center',
+ },
+ };
+});
+
+export type EmailInvite = string;
+
+export type SearchResult = UserProfile|EmailInvite;
+
+export type InviteResult = {
+ userId: string;
+ reason: string;
+};
+
+export type Result = {
+ sent: InviteResult[];
+ notSent: InviteResult[];
+}
+
+enum Stage {
+ SELECTION = 'selection',
+ RESULT = 'result',
+ LOADING = 'loading',
+}
+
+type InviteProps = {
+ componentId: AvailableScreens;
+ teamId: string;
+ teamDisplayName: string;
+ teamLastIconUpdate: number;
+ teamInviteId: string;
+ teammateNameDisplay: string;
+ isAdmin: boolean;
+}
+
+export default function Invite({
+ componentId,
+ teamId,
+ teamDisplayName,
+ teamLastIconUpdate,
+ teamInviteId,
+ teammateNameDisplay,
+ isAdmin,
+}: InviteProps) {
+ const intl = useIntl();
+ const {formatMessage, locale} = intl;
+ const theme = useTheme();
+ const styles = getStyleSheet(theme);
+ const serverUrl = useServerUrl();
+ const mainView = useRef(null);
+ const modalPosition = useModalPosition(mainView);
+
+ const searchTimeoutId = useRef(null);
+ const retryTimeoutId = useRef(null);
+
+ const [term, setTerm] = useState('');
+ const [searchResults, setSearchResults] = useState([]);
+ const [selectedIds, setSelectedIds] = useState<{[id: string]: SearchResult}>({});
+ const [loading, setLoading] = useState(false);
+ const [result, setResult] = useState(DEFAULT_RESULT);
+ const [wrapperHeight, setWrapperHeight] = useState(0);
+ const [stage, setStage] = useState(Stage.SELECTION);
+ const [sendError, setSendError] = useState('');
+
+ const selectedCount = Object.keys(selectedIds).length;
+
+ const onLayoutWrapper = useCallback((e: LayoutChangeEvent) => {
+ setWrapperHeight(e.nativeEvent.layout.height);
+ }, []);
+
+ const searchUsers = useCallback(async (searchTerm: string) => {
+ if (searchTerm === '') {
+ handleClearSearch();
+ return;
+ }
+
+ const {data} = await searchProfiles(serverUrl, searchTerm.toLowerCase());
+ const results: SearchResult[] = data ?? [];
+
+ if (!results.length && isEmail(searchTerm.trim())) {
+ results.push(searchTerm.trim() as EmailInvite);
+ }
+
+ setSearchResults(results);
+ }, [serverUrl, teamId]);
+
+ const handleReset = () => {
+ setStage(Stage.LOADING);
+ setSendError('');
+ setTerm('');
+ setSearchResults([]);
+ setResult(DEFAULT_RESULT);
+ setStage(Stage.SELECTION);
+ };
+
+ const handleClearSearch = useCallback(() => {
+ setTerm('');
+ setSearchResults([]);
+ }, []);
+
+ const handleSearchChange = useCallback((text: string) => {
+ setLoading(true);
+ setTerm(text);
+
+ if (searchTimeoutId.current) {
+ clearTimeout(searchTimeoutId.current);
+ }
+
+ searchTimeoutId.current = setTimeout(async () => {
+ await searchUsers(text);
+ setLoading(false);
+ }, TIMEOUT_MILLISECONDS);
+ }, [searchUsers]);
+
+ const handleSelectItem = useCallback((item: SearchResult) => {
+ const email = typeof item === 'string';
+ const id = email ? item : (item as UserProfile).id;
+ const newSelectedIds = Object.assign({}, selectedIds);
+
+ if (!selectedIds[id]) {
+ newSelectedIds[id] = item;
+ }
+
+ setSelectedIds(newSelectedIds);
+
+ handleClearSearch();
+ }, [selectedIds, handleClearSearch]);
+
+ const handleRetry = () => {
+ setSendError('');
+ setStage(Stage.LOADING);
+
+ retryTimeoutId.current = setTimeout(() => {
+ handleSend();
+ }, TIMEOUT_MILLISECONDS);
+ };
+
+ const handleSendError = () => {
+ setSendError(formatMessage({id: 'invite.send_error', defaultMessage: 'Something went wrong while trying to send invitations. Please check your network connection and try again.'}));
+ setResult(DEFAULT_RESULT);
+ setStage(Stage.RESULT);
+ };
+
+ const handleSend = async () => {
+ if (!selectedCount) {
+ return;
+ }
+
+ setStage(Stage.LOADING);
+
+ const userIds = [];
+ const emails = [];
+
+ for (const [id, item] of Object.entries(selectedIds)) {
+ if (typeof item === 'string') {
+ emails.push(item);
+ } else {
+ userIds.push(id);
+ }
+ }
+
+ const currentMemberIds = new Set();
+
+ if (userIds.length) {
+ const {members: currentTeamMembers = [], error: getTeamMembersByIdsError} = await getTeamMembersByIds(serverUrl, teamId, userIds);
+
+ if (getTeamMembersByIdsError) {
+ handleSendError();
+ return;
+ }
+
+ for (const {user_id: currentMemberId} of currentTeamMembers) {
+ currentMemberIds.add(currentMemberId);
+ }
+ }
+
+ const sent: InviteResult[] = [];
+ const notSent: InviteResult[] = [];
+ const usersToAdd = [];
+
+ for (const userId of userIds) {
+ if (isGuest((selectedIds[userId] as UserProfile).roles)) {
+ notSent.push({userId, reason: formatMessage({id: 'invite.members.user_is_guest', defaultMessage: 'Contact your admin to make this guest a full member'})});
+ } else if (currentMemberIds.has(userId)) {
+ notSent.push({userId, reason: formatMessage({id: 'invite.members.already_member', defaultMessage: 'This person is already a team member'})});
+ } else {
+ usersToAdd.push(userId);
+ }
+ }
+
+ if (usersToAdd.length) {
+ const {members, error: addUsersToTeamError} = await addUsersToTeam(serverUrl, teamId, usersToAdd);
+
+ if (addUsersToTeamError) {
+ handleSendError();
+ return;
+ }
+
+ if (members) {
+ const membersWithError: Record = {};
+ for (const {user_id, error} of members) {
+ if (error) {
+ membersWithError[user_id] = error.message;
+ }
+ }
+
+ for (const userId of usersToAdd) {
+ if (membersWithError[userId]) {
+ notSent.push({userId, reason: membersWithError[userId]});
+ } else {
+ sent.push({userId, reason: formatMessage({id: 'invite.summary.member_invite', defaultMessage: 'Invited as a member of {teamDisplayName}'}, {teamDisplayName})});
+ }
+ }
+ }
+ }
+
+ if (emails.length) {
+ const {members, error: sendEmailInvitesToTeamError} = await sendEmailInvitesToTeam(serverUrl, teamId, emails);
+
+ if (sendEmailInvitesToTeamError) {
+ handleSendError();
+ return;
+ }
+
+ if (members) {
+ const membersWithError: Record = {};
+ for (const {email, error} of members) {
+ if (error) {
+ membersWithError[email] = isAdmin && error.server_error_id === ServerErrors.SEND_EMAIL_WITH_DEFAULTS_ERROR ? (
+ formatMessage({id: 'invite.summary.smtp_failure', defaultMessage: 'SMTP is not configured in System Console'})
+ ) : (
+ error.message
+ );
+ }
+ }
+
+ for (const email of emails) {
+ if (membersWithError[email]) {
+ notSent.push({userId: email, reason: membersWithError[email]});
+ } else {
+ sent.push({userId: email, reason: formatMessage({id: 'invite.summary.email_invite', defaultMessage: 'An invitation email has been sent'})});
+ }
+ }
+ }
+ }
+
+ setResult({sent, notSent});
+ setStage(Stage.RESULT);
+ };
+
+ useNavButtonPressed(CLOSE_BUTTON_ID, componentId, closeModal, [closeModal]);
+ useNavButtonPressed(SEND_BUTTON_ID, componentId, handleSend, [handleSend]);
+
+ useEffect(() => {
+ const buttons: NavButtons = {
+ leftButtons: [makeLeftButton(theme)],
+ rightButtons: stage === Stage.SELECTION ? [makeRightButton(theme, formatMessage, selectedCount > 0)] : [],
+ };
+
+ setButtons(componentId, buttons);
+ }, [theme, locale, componentId, selectedCount > 0, stage === Stage.SELECTION, sendError]);
+
+ useEffect(() => {
+ mergeNavigationOptions(componentId, {
+ topBar: {
+ title: {
+ color: theme.sidebarHeaderTextColor,
+ text: stage === Stage.RESULT ? (
+ formatMessage({id: 'invite.title.summary', defaultMessage: 'Invite summary'})
+ ) : (
+ formatMessage({id: 'invite.title', defaultMessage: 'Invite'})
+ ),
+ },
+ },
+ });
+ }, [componentId, locale, theme, stage === Stage.RESULT]);
+
+ useEffect(() => {
+ return () => {
+ if (searchTimeoutId.current) {
+ clearTimeout(searchTimeoutId.current);
+ }
+
+ if (retryTimeoutId.current) {
+ clearTimeout(retryTimeoutId.current);
+ }
+ };
+ }, []);
+
+ const handleRemoveItem = useCallback((id: string) => {
+ const newSelectedIds = Object.assign({}, selectedIds);
+
+ Reflect.deleteProperty(newSelectedIds, id);
+
+ setSelectedIds(newSelectedIds);
+ }, [selectedIds]);
+
+ const renderContent = () => {
+ switch (stage) {
+ case Stage.LOADING:
+ return (
+
+ );
+ case Stage.RESULT:
+ return (
+
+ );
+ default:
+ return (
+
+ );
+ }
+ };
+
+ return (
+
+ {renderContent()}
+
+ );
+}
diff --git a/app/screens/invite/selection.tsx b/app/screens/invite/selection.tsx
new file mode 100644
index 0000000000..b31bccbd67
--- /dev/null
+++ b/app/screens/invite/selection.tsx
@@ -0,0 +1,349 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {useCallback, useState, useMemo} from 'react';
+import {
+ Keyboard,
+ Platform,
+ View,
+ LayoutChangeEvent,
+ useWindowDimensions,
+ FlatList,
+ ListRenderItemInfo,
+ ScrollView,
+} from 'react-native';
+import Animated, {useAnimatedStyle, useDerivedValue} from 'react-native-reanimated';
+import {useSafeAreaInsets} from 'react-native-safe-area-context';
+
+import SelectedChip from '@components/selected_chip';
+import SelectedUser from '@components/selected_users/selected_user';
+import TouchableWithFeedback from '@components/touchable_with_feedback';
+import UserItem from '@components/user_item';
+import {MAX_LIST_HEIGHT, MAX_LIST_TABLET_DIFF} from '@constants/autocomplete';
+import {useTheme} from '@context/theme';
+import {useAutocompleteDefaultAnimatedValues} from '@hooks/autocomplete';
+import {useIsTablet, useKeyboardHeight} from '@hooks/device';
+import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme';
+
+import SelectionSearchBar from './selection_search_bar';
+import SelectionTeamBar from './selection_team_bar';
+import TextItem, {TextItemType} from './text_item';
+
+import type {SearchResult} from './invite';
+
+const AUTOCOMPLETE_ADJUST = 5;
+const KEYBOARD_HEIGHT_ADJUST = 3;
+
+const INITIAL_BATCH_TO_RENDER = 15;
+const SCROLL_EVENT_THROTTLE = 60;
+
+const keyboardDismissProp = Platform.select({
+ android: {
+ onScrollBeginDrag: Keyboard.dismiss,
+ },
+ ios: {
+ keyboardDismissMode: 'on-drag' as const,
+ },
+});
+
+const keyExtractor = (item: SearchResult) => (
+ typeof item === 'string' ? item : (item as UserProfile).id
+);
+
+const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
+ return {
+ container: {
+ display: 'flex',
+ flex: 1,
+ },
+ searchList: {
+ left: 20,
+ right: 20,
+ position: 'absolute',
+ bottom: Platform.select({ios: 'auto', default: undefined}),
+ },
+ searchListBorder: {
+ borderWidth: 1,
+ borderColor: changeOpacity(theme.centerChannelColor, 0.2),
+ borderRadius: 4,
+ elevation: 3,
+ },
+ searchListPadding: {
+ paddingVertical: 8,
+ },
+ searchListShadow: {
+ shadowColor: '#000',
+ shadowOpacity: 0.12,
+ shadowRadius: 6,
+ shadowOffset: {
+ width: 0,
+ height: 6,
+ },
+ borderRadius: 4,
+ backgroundColor: theme.centerChannelBg,
+ },
+ searchListFlatList: {
+ backgroundColor: theme.centerChannelBg,
+ borderRadius: 4,
+ },
+ selectedItems: {
+ display: 'flex',
+ flexGrowth: 1,
+ },
+ selectedItemsContainer: {
+ alignItems: 'flex-start',
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ marginHorizontal: 20,
+ marginVertical: 16,
+ },
+ };
+});
+
+type SelectionProps = {
+ teamId: string;
+ teamDisplayName: string;
+ teamLastIconUpdate: number;
+ teamInviteId: string;
+ teammateNameDisplay: string;
+ serverUrl: string;
+ term: string;
+ searchResults: SearchResult[];
+ selectedIds: {[id: string]: SearchResult};
+ modalPosition: number;
+ wrapperHeight: number;
+ loading: boolean;
+ testID: string;
+ onSearchChange: (text: string) => void;
+ onSelectItem: (item: SearchResult) => void;
+ onRemoveItem: (id: string) => void;
+ onClose: () => Promise;
+}
+
+export default function Selection({
+ teamId,
+ teamDisplayName,
+ teamLastIconUpdate,
+ teamInviteId,
+ teammateNameDisplay,
+ serverUrl,
+ term,
+ searchResults,
+ selectedIds,
+ modalPosition,
+ wrapperHeight,
+ loading,
+ testID,
+ onSearchChange,
+ onSelectItem,
+ onRemoveItem,
+ onClose,
+}: SelectionProps) {
+ const theme = useTheme();
+ const styles = getStyleSheet(theme);
+ const dimensions = useWindowDimensions();
+ const insets = useSafeAreaInsets();
+ const isTablet = useIsTablet();
+ const keyboardHeight = useKeyboardHeight();
+
+ const [teamBarHeight, setTeamBarHeight] = useState(0);
+ const [searchBarHeight, setSearchBarHeight] = useState(0);
+
+ const onLayoutSelectionTeamBar = useCallback((e: LayoutChangeEvent) => {
+ setTeamBarHeight(e.nativeEvent.layout.height);
+ }, []);
+
+ const onLayoutSearchBar = useCallback((e: LayoutChangeEvent) => {
+ setSearchBarHeight(e.nativeEvent.layout.height);
+ }, []);
+
+ const handleOnRemoveItem = (id: string) => {
+ onRemoveItem(id);
+ };
+
+ const bottomSpace = dimensions.height - wrapperHeight - modalPosition;
+ const otherElementsSize = teamBarHeight + searchBarHeight;
+ const insetsAdjust = (keyboardHeight + KEYBOARD_HEIGHT_ADJUST) || insets.bottom;
+
+ const keyboardOverlap = Platform.select({
+ ios: isTablet ? (
+ Math.max(0, keyboardHeight - bottomSpace)
+ ) : (
+ insetsAdjust
+ ),
+ default: 0,
+ });
+ const keyboardAdjust = Platform.select({
+ ios: isTablet ? keyboardOverlap : insetsAdjust,
+ default: 0,
+ });
+
+ const workingSpace = wrapperHeight - keyboardOverlap;
+ const spaceOnTop = otherElementsSize - AUTOCOMPLETE_ADJUST;
+ const spaceOnBottom = workingSpace - (otherElementsSize + keyboardAdjust);
+ const autocompletePosition = spaceOnBottom > spaceOnTop ? (
+ otherElementsSize
+ ) : (
+ workingSpace - otherElementsSize
+ );
+ const autocompleteAvailableSpace = spaceOnBottom > spaceOnTop ? spaceOnBottom : spaceOnTop;
+ const isLandscape = dimensions.width > dimensions.height;
+ const maxHeightAdjust = (isTablet && isLandscape) ? MAX_LIST_TABLET_DIFF : 0;
+ const defaultMaxHeight = MAX_LIST_HEIGHT - maxHeightAdjust;
+
+ const [animatedAutocompletePosition, animatedAutocompleteAvailableSpace] = useAutocompleteDefaultAnimatedValues(autocompletePosition, autocompleteAvailableSpace);
+
+ const maxHeight = useDerivedValue(() => {
+ return Math.min(animatedAutocompleteAvailableSpace.value, defaultMaxHeight);
+ }, [animatedAutocompleteAvailableSpace, defaultMaxHeight]);
+
+ const searchListContainerAnimatedStyle = useAnimatedStyle(() => ({
+ top: animatedAutocompletePosition.value,
+ maxHeight: maxHeight.value,
+ }), [animatedAutocompletePosition, maxHeight]);
+
+ const searchListContainerStyle = useMemo(() => {
+ const style = [];
+
+ style.push(
+ styles.searchList,
+ searchListContainerAnimatedStyle,
+ );
+
+ if (Platform.OS === 'ios') {
+ style.push(styles.searchListShadow);
+ }
+
+ return style;
+ }, [searchResults, styles, searchListContainerAnimatedStyle]);
+
+ const searchListFlatListStyle = useMemo(() => {
+ const style = [];
+
+ style.push(styles.searchListFlatList);
+
+ if (searchResults.length) {
+ style.push(styles.searchListBorder, styles.searchListPadding);
+ }
+
+ return style;
+ }, [searchResults, styles]);
+
+ const renderNoResults = useCallback(() => {
+ if (!term || loading) {
+ return null;
+ }
+
+ return (
+
+
+
+ );
+ }, [term, loading]);
+
+ const renderItem = useCallback(({item}: ListRenderItemInfo) => {
+ const key = keyExtractor(item);
+
+ return (
+ onSelectItem(item)}
+ underlayColor={changeOpacity(theme.buttonBg, 0.08)}
+ type='native'
+ testID={`invite.search_list_item.${key}`}
+ >
+ {typeof item === 'string' ? (
+
+ ) : (
+
+ )}
+
+ );
+ }, [searchResults, onSelectItem]);
+
+ const renderSelectedItems = useMemo(() => {
+ const selectedItems = [];
+
+ for (const id of Object.keys(selectedIds)) {
+ const selectedItem = selectedIds[id];
+
+ selectedItems.push(typeof selectedItem === 'string' ? (
+
+ ) : (
+
+ ));
+ }
+
+ return selectedItems;
+ }, [selectedIds]);
+
+ return (
+
+
+
+ {Object.keys(selectedIds).length > 0 && (
+
+ {renderSelectedItems}
+
+ )}
+
+
+
+
+ );
+}
diff --git a/app/screens/invite/selection_search_bar.tsx b/app/screens/invite/selection_search_bar.tsx
new file mode 100644
index 0000000000..ad5f9b5e68
--- /dev/null
+++ b/app/screens/invite/selection_search_bar.tsx
@@ -0,0 +1,131 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {useCallback, useState, useMemo} from 'react';
+import {useIntl} from 'react-intl';
+import {View, TextInput, LayoutChangeEvent} from 'react-native';
+
+import FormattedText from '@components/formatted_text';
+import {useTheme} from '@context/theme';
+import {makeStyleSheetFromTheme, changeOpacity, getKeyboardAppearanceFromTheme} from '@utils/theme';
+import {typography} from '@utils/typography';
+
+const SEARCH_BAR_TITLE_MARGIN_TOP = 24;
+const SEARCH_BAR_MARGIN_TOP = 16;
+
+const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
+ return {
+ container: {
+ display: 'flex',
+ },
+ searchBarTitleText: {
+ marginHorizontal: 20,
+ marginTop: SEARCH_BAR_TITLE_MARGIN_TOP,
+ color: theme.centerChannelColor,
+ ...typography('Heading', 700, 'SemiBold'),
+ },
+ searchBar: {
+ marginHorizontal: 20,
+ marginTop: SEARCH_BAR_MARGIN_TOP,
+ },
+ searchInput: {
+ height: 48,
+ backgroundColor: 'transparent',
+ ...typography('Body', 200, 'Regular'),
+ lineHeight: 20,
+ color: theme.centerChannelColor,
+ borderWidth: 1,
+ borderColor: changeOpacity(theme.centerChannelColor, 0.16),
+ borderRadius: 4,
+ paddingHorizontal: 16,
+ },
+ searchInputPlaceholder: {
+ color: changeOpacity(theme.centerChannelColor, 0.64),
+ },
+ };
+});
+
+type SelectionSearchBarProps = {
+ term: string;
+ onSearchChange: (text: string) => void;
+ onLayoutContainer: (e: LayoutChangeEvent) => void;
+}
+
+export default function SelectionSearchBar({
+ term,
+ onSearchChange,
+ onLayoutContainer,
+}: SelectionSearchBarProps) {
+ const {formatMessage} = useIntl();
+ const theme = useTheme();
+ const styles = getStyleSheet(theme);
+ const [isFocused, setIsFocused] = useState(false);
+
+ const onLayoutSearchBar = useCallback((e: LayoutChangeEvent) => {
+ onLayoutContainer(e);
+ }, [onLayoutContainer]);
+
+ const onTextInputFocus = () => {
+ setIsFocused(true);
+ };
+
+ const onTextInputBlur = () => {
+ setIsFocused(false);
+ };
+
+ const handleSearchChange = (text: string) => {
+ onSearchChange(text);
+ };
+
+ const searchInputStyle = useMemo(() => {
+ const style = [];
+
+ style.push(styles.searchInput);
+
+ if (isFocused) {
+ style.push({
+ borderWidth: 2,
+ borderColor: theme.buttonBg,
+ });
+ }
+
+ return style;
+ }, [isFocused, styles]);
+
+ return (
+
+
+
+
+
+
+ );
+}
diff --git a/app/screens/invite/selection_team_bar.tsx b/app/screens/invite/selection_team_bar.tsx
new file mode 100644
index 0000000000..0a1dd3f0b7
--- /dev/null
+++ b/app/screens/invite/selection_team_bar.tsx
@@ -0,0 +1,216 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {useCallback} from 'react';
+import {useIntl} from 'react-intl';
+import {
+ Platform,
+ View,
+ Text,
+ TouchableOpacity,
+ LayoutChangeEvent,
+} from 'react-native';
+import Share from 'react-native-share';
+
+import CompassIcon from '@components/compass_icon';
+import FormattedText from '@components/formatted_text';
+import TeamIcon from '@components/team_sidebar/team_list/team_item/team_icon';
+import {useServerDisplayName} from '@context/server';
+import {useTheme} from '@context/theme';
+import {preventDoubleTap} from '@utils/tap';
+import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme';
+import {typography} from '@utils/typography';
+
+import type {ShareOptions} from 'react-native-share/lib/typescript/types';
+
+const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
+ return {
+ container: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ width: '100%',
+ paddingVertical: 16,
+ paddingHorizontal: 20,
+ backgroundColor: changeOpacity(theme.centerChannelColor, 0.04),
+ },
+ iconContainer: {
+ width: 40,
+ height: 40,
+ },
+ textContainer: {
+ display: 'flex',
+ flexDirection: 'column',
+ },
+ teamText: {
+ color: theme.centerChannelColor,
+ marginLeft: 12,
+ ...typography('Body', 200, 'SemiBold'),
+ },
+ serverText: {
+ color: changeOpacity(theme.centerChannelColor, 0.72),
+ marginLeft: 12,
+ ...typography('Body', 75, 'Regular'),
+ },
+ shareLink: {
+ display: 'flex',
+ marginLeft: 'auto',
+ },
+ shareLinkButton: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ height: 40,
+ paddingHorizontal: 20,
+ backgroundColor: changeOpacity(theme.buttonBg, 0.08),
+ borderRadius: 4,
+ },
+ shareLinkText: {
+ color: theme.buttonBg,
+ ...typography('Body', 100, 'SemiBold'),
+ paddingLeft: 7,
+ },
+ shareLinkIcon: {
+ color: theme.buttonBg,
+ },
+ };
+});
+
+type SelectionTeamBarProps = {
+ teamId: string;
+ teamDisplayName: string;
+ teamLastIconUpdate: number;
+ teamInviteId: string;
+ serverUrl: string;
+ onLayoutContainer: (e: LayoutChangeEvent) => void;
+ onClose: () => Promise;
+}
+
+export default function SelectionTeamBar({
+ teamId,
+ teamDisplayName,
+ teamLastIconUpdate,
+ teamInviteId,
+ serverUrl,
+ onLayoutContainer,
+ onClose,
+}: SelectionTeamBarProps) {
+ const {formatMessage} = useIntl();
+ const theme = useTheme();
+ const styles = getStyleSheet(theme);
+ const serverDisplayName = useServerDisplayName();
+
+ const handleOnLayoutContainer = useCallback((e: LayoutChangeEvent) => {
+ onLayoutContainer(e);
+ }, [onLayoutContainer]);
+
+ const handleOnShareLink = async () => {
+ const url = `${serverUrl}/signup_user_complete/?id=${teamInviteId}`;
+ const title = formatMessage({id: 'invite_people_to_team.title', defaultMessage: 'Join the {team} team'}, {team: teamDisplayName});
+ const message = formatMessage({id: 'invite_people_to_team.message', defaultMessage: 'Here’s a link to collaborate and communicate with us on Mattermost.'});
+ const icon = 'data:/;base64,';
+
+ const options: ShareOptions = Platform.select({
+ ios: {
+ activityItemSources: [
+ {
+ placeholderItem: {
+ type: 'url',
+ content: url,
+ },
+ item: {
+ default: {
+ type: 'text',
+ content: `${message} ${url}`,
+ },
+ copyToPasteBoard: {
+ type: 'url',
+ content: url,
+ },
+ },
+ subject: {
+ default: title,
+ },
+ linkMetadata: {
+ originalUrl: url,
+ url,
+ title,
+ icon,
+ },
+ },
+ ],
+ },
+ default: {
+ title,
+ subject: title,
+ url,
+ showAppsToView: true,
+ },
+ });
+
+ await onClose();
+
+ Share.open(
+ options,
+ ).catch(() => {
+ // do nothing
+ });
+ };
+
+ const handleShareLink = useCallback(preventDoubleTap(() => handleOnShareLink()), []);
+
+ return (
+
+
+
+
+
+
+ {teamDisplayName}
+
+
+ {serverDisplayName}
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/screens/invite/summary.tsx b/app/screens/invite/summary.tsx
new file mode 100644
index 0000000000..d06c64ef59
--- /dev/null
+++ b/app/screens/invite/summary.tsx
@@ -0,0 +1,300 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React, {useCallback, useMemo} from 'react';
+import {useIntl} from 'react-intl';
+import {View, Text, ScrollView} from 'react-native';
+import Button from 'react-native-button';
+
+import CompassIcon from '@components/compass_icon';
+import FormattedText from '@components/formatted_text';
+import AlertSvg from '@components/illustrations/alert';
+import ErrorSvg from '@components/illustrations/error';
+import SuccessSvg from '@components/illustrations/success';
+import {useTheme} from '@context/theme';
+import {t} from '@i18n';
+import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
+import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme';
+import {typography} from '@utils/typography';
+
+import SummaryReport, {SummaryReportType} from './summary_report';
+
+import type {SearchResult, Result} from './invite';
+
+const MAX_WIDTH_CONTENT = 480;
+
+const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
+ return {
+ container: {
+ display: 'flex',
+ flex: 1,
+ },
+ summary: {
+ display: 'flex',
+ flex: 1,
+ },
+ summaryContainer: {
+ display: 'flex',
+ flexGrow: 1,
+ flexDirection: 'row',
+ justifyContent: 'center',
+ alignItems: 'stretch',
+ marginTop: 20,
+ marginHorizontal: 20,
+ paddingBottom: 20,
+ },
+ summaryContent: {
+ flexGrow: 1,
+ flexDirection: 'column',
+ justifyContent: 'center',
+ maxWidth: MAX_WIDTH_CONTENT,
+ },
+ summarySvg: {
+ marginBottom: 20,
+ alignSelf: 'center',
+ },
+ summaryMessageText: {
+ color: theme.centerChannelColor,
+ ...typography('Heading', 700, 'SemiBold'),
+ textAlign: 'center',
+ marginHorizontal: 32,
+ marginBottom: 24,
+ },
+ summaryErrorText: {
+ color: changeOpacity(theme.centerChannelColor, 0.72),
+ ...typography('Body', 200, 'Regular'),
+ textAlign: 'center',
+ },
+ footer: {
+ display: 'flex',
+ flexDirection: 'row',
+ justifyContent: 'center',
+ borderTopWidth: 1,
+ borderTopColor: changeOpacity(theme.centerChannelColor, 0.16),
+ padding: 20,
+ },
+ summaryButtonContainer: {
+ flexGrow: 1,
+ flexDirection: 'row',
+ justifyContent: 'center',
+ },
+ summaryButtonTextContainer: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ height: 24,
+ },
+ summaryButtonIcon: {
+ marginRight: 7,
+ color: theme.buttonColor,
+
+ },
+ };
+});
+
+enum SummaryButtonType {
+ DONE = 'done',
+ RETRY = 'retry',
+ BACK = 'back',
+}
+
+type SummaryProps = {
+ result: Result;
+ selectedIds: {[id: string]: SearchResult};
+ error?: string;
+ testID: string;
+ onClose: () => void;
+ onRetry: () => void;
+ onBack: () => void;
+}
+
+export default function Summary({
+ result,
+ selectedIds,
+ error,
+ testID,
+ onClose,
+ onRetry,
+ onBack,
+}: SummaryProps) {
+ const {formatMessage, locale} = useIntl();
+ const theme = useTheme();
+ const styles = getStyleSheet(theme);
+
+ const {sent, notSent} = result;
+ const sentCount = sent.length;
+ const notSentCount = notSent.length;
+
+ const styleSummaryMessageText = useMemo(() => {
+ const style = [];
+
+ style.push(styles.summaryMessageText);
+
+ if (error) {
+ style.push({marginBottom: 8});
+ }
+
+ return style;
+ }, [error, styles]);
+
+ let svg = <>>;
+ let message = '';
+
+ if (error) {
+ svg = ;
+ message = formatMessage(
+ {
+ id: 'invite.summary.error',
+ defaultMessage: '{invitationsCount, plural, one {Invitation} other {Invitations}} could not be sent successfully',
+ },
+ {invitationsCount: sentCount + notSentCount},
+ );
+ } else if (!sentCount && notSentCount) {
+ svg = ;
+ message = formatMessage(
+ {
+ id: 'invite.summary.not_sent',
+ defaultMessage: '{notSentCount, plural, one {Invitation wasn’t} other {Invitations weren’t}} sent',
+ },
+ {notSentCount},
+ );
+ } else if (sentCount && !notSentCount) {
+ svg = ;
+ message = formatMessage(
+ {
+ id: 'invite.summary.sent',
+ defaultMessage: 'Your {sentCount, plural, one {invitation has} other {invitations have}} been sent',
+ },
+ {sentCount},
+ );
+ } else if (sentCount && notSentCount) {
+ svg = ;
+ message = formatMessage(
+ {
+ id: 'invite.summary.some_not_sent',
+ defaultMessage: '{notSentCount, plural, one {An invitation was} other {Some invitations were}} not sent',
+ },
+ {notSentCount},
+ );
+ }
+
+ const renderButton = useCallback((type: SummaryButtonType) => {
+ let onPress;
+ let iconName = '';
+ let text;
+ let styleButtonText = buttonTextStyle(theme, 'lg', 'primary');
+ let styleButtonBackground = buttonBackgroundStyle(theme, 'lg', 'primary');
+ const styleButtonIcon = [];
+ styleButtonIcon.push(styles.summaryButtonIcon);
+
+ switch (type) {
+ case SummaryButtonType.BACK:
+ onPress = onBack;
+ iconName = 'chevron-left';
+ text = {
+ id: t('invite.summary.back'),
+ defaultMessage: 'Go back',
+ };
+ styleButtonText = buttonTextStyle(theme, 'lg', 'tertiary');
+ styleButtonBackground = [buttonBackgroundStyle(theme, 'lg', 'tertiary'), {marginRight: 8}];
+ styleButtonIcon.push({color: theme.buttonBg});
+ break;
+ case SummaryButtonType.RETRY:
+ onPress = onRetry;
+ iconName = 'refresh';
+ text = {
+ id: t('invite.summary.try_again'),
+ defaultMessage: 'Try again',
+ };
+ break;
+ case SummaryButtonType.DONE:
+ default:
+ onPress = onClose;
+ text = {
+ id: t('invite.summary.done'),
+ defaultMessage: 'Done',
+ };
+ break;
+ }
+
+ return (
+
+
+ {iconName && (
+
+ )}
+
+
+
+ );
+ }, [theme, locale, onClose, onRetry, onBack]);
+
+ return (
+
+
+
+
+ {svg}
+
+
+ {message}
+
+ {error ? (
+
+ {error}
+
+ ) : (
+ <>
+ {notSent.length > 0 && (
+
+ )}
+ {sent.length > 0 && (
+
+ )}
+ >
+ )}
+
+
+
+
+ {error ? (
+ <>
+ {renderButton(SummaryButtonType.BACK)}
+ {renderButton(SummaryButtonType.RETRY)}
+ >
+ ) : (
+ renderButton(SummaryButtonType.DONE)
+ )}
+
+
+
+ );
+}
diff --git a/app/screens/invite/summary_report.tsx b/app/screens/invite/summary_report.tsx
new file mode 100644
index 0000000000..874e002678
--- /dev/null
+++ b/app/screens/invite/summary_report.tsx
@@ -0,0 +1,150 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React from 'react';
+import {useIntl} from 'react-intl';
+import {View, Text} from 'react-native';
+
+import CompassIcon from '@components/compass_icon';
+import UserItem from '@components/user_item';
+import {useTheme} from '@context/theme';
+import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme';
+import {typography} from '@utils/typography';
+
+import TextItem, {TextItemType} from './text_item';
+
+import type {SearchResult, InviteResult} from './invite';
+
+const COLOR_SUCCESS = '#3db887';
+const COLOR_ERROR = '#d24b4e';
+
+const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
+ return {
+ container: {
+ display: 'flex',
+ flexDirection: 'column',
+ borderWidth: 1,
+ borderColor: changeOpacity(theme.centerChannelColor, 0.16),
+ borderRadius: 4,
+ marginBottom: 16,
+ paddingVertical: 8,
+ },
+ title: {
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ paddingHorizontal: 20,
+ paddingVertical: 12,
+ },
+ titleText: {
+ marginLeft: 12,
+ ...typography('Heading', 300, 'SemiBold'),
+ color: theme.centerChannelColor,
+ },
+ item: {
+ display: 'flex',
+ flexDirection: 'column',
+ paddingVertical: 12,
+ },
+ user: {
+ paddingTop: 0,
+ paddingBottom: 0,
+ height: 'auto',
+ },
+ reason: {
+ paddingLeft: 56,
+ paddingRight: 20,
+ ...typography('Body', 75, 'Regular'),
+ color: changeOpacity(theme.centerChannelColor, 0.64),
+ },
+ };
+});
+
+export enum SummaryReportType {
+ SENT = 'sent',
+ NOT_SENT = 'not_sent',
+}
+
+type SummaryReportProps = {
+ type: SummaryReportType;
+ invites: InviteResult[];
+ selectedIds: {[id: string]: SearchResult};
+ testID: string;
+}
+
+export default function SummaryReport({
+ type,
+ invites,
+ selectedIds,
+ testID,
+}: SummaryReportProps) {
+ const {formatMessage} = useIntl();
+ const theme = useTheme();
+ const styles = getStyleSheet(theme);
+
+ const count = invites.length;
+
+ const sent = type === SummaryReportType.SENT;
+ const message = sent ? (
+ formatMessage(
+ {
+ id: 'invite.summary.report.sent',
+ defaultMessage: '{count} successful {count, plural, one {invitation} other {invitations}}',
+ },
+ {count},
+ )
+ ) : (
+ formatMessage(
+ {
+ id: 'invite.summary.report.notSent',
+ defaultMessage: '{count} {count, plural, one {invitation} other {invitations}} not sent',
+ },
+ {count},
+ )
+ );
+
+ return (
+
+
+
+
+ {message}
+
+
+ {invites.map(({userId, reason}) => {
+ const item = selectedIds[userId];
+
+ return (
+
+ {typeof item === 'string' ? (
+
+ ) : (
+
+ )}
+
+ {reason}
+
+
+ );
+ })}
+
+ );
+}
diff --git a/app/screens/invite/text_item.tsx b/app/screens/invite/text_item.tsx
new file mode 100644
index 0000000000..9a14e3ae1c
--- /dev/null
+++ b/app/screens/invite/text_item.tsx
@@ -0,0 +1,111 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import React from 'react';
+import {useIntl} from 'react-intl';
+import {View, Text} from 'react-native';
+
+import CompassIcon from '@components/compass_icon';
+import {useTheme} from '@context/theme';
+import {makeStyleSheetFromTheme, changeOpacity} from '@utils/theme';
+import {typography} from '@utils/typography';
+
+const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
+ return {
+ item: {
+ paddingHorizontal: 20,
+ display: 'flex',
+ flexDirection: 'row',
+ alignItems: 'center',
+ },
+ search: {
+ height: 40,
+ paddingVertical: 8,
+ paddingHorizontal: 16,
+ },
+ itemText: {
+ display: 'flex',
+ ...typography('Body', 200, 'Regular'),
+ color: theme.centerChannelColor,
+ },
+ itemTerm: {
+ display: 'flex',
+ ...typography('Body', 200, 'SemiBold'),
+ color: theme.centerChannelColor,
+ marginLeft: 4,
+ },
+ itemImage: {
+ alignItems: 'center',
+ justifyContent: 'center',
+ height: 24,
+ width: 24,
+ borderRadius: 12,
+ backgroundColor: changeOpacity(theme.centerChannelColor, 0.08),
+ marginRight: 12,
+ },
+ itemIcon: {
+ color: changeOpacity(theme.centerChannelColor, 0.56),
+ },
+ };
+});
+
+export enum TextItemType {
+ SEARCH_INVITE = 'search_invite',
+ SEARCH_NO_RESULTS = 'search_no_results',
+ SUMMARY = 'summary',
+}
+
+type TextItemProps = {
+ text?: string;
+ type: TextItemType;
+ testID: string;
+}
+
+export default function TextItem({
+ text = '',
+ type,
+ testID,
+}: TextItemProps) {
+ const {formatMessage} = useIntl();
+ const theme = useTheme();
+ const styles = getStyleSheet(theme);
+
+ const search = type === TextItemType.SEARCH_INVITE || type === TextItemType.SEARCH_NO_RESULTS;
+ const email = type === TextItemType.SEARCH_INVITE || type === TextItemType.SUMMARY;
+
+ return (
+
+ {email && (
+
+
+ )
+ }
+ {search && (
+
+ {email ? (
+ formatMessage({id: 'invite.search.email_invite', defaultMessage: 'invite'})
+ ) : (
+ formatMessage({id: 'invite.search.no_results', defaultMessage: 'No one found matching'})
+ )}
+
+ )}
+
+ {text}
+
+
+ );
+}
diff --git a/app/screens/join_team/index.ts b/app/screens/join_team/index.ts
index 46b52cdea8..8303c5db6a 100644
--- a/app/screens/join_team/index.ts
+++ b/app/screens/join_team/index.ts
@@ -7,11 +7,11 @@ import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
import {queryMyTeams} from '@queries/servers/team';
-import MyTeamModel from '@typings/database/models/servers/my_team';
import JoinTeam from './join_team';
import type {WithDatabaseArgs} from '@typings/database/database';
+import type MyTeamModel from '@typings/database/models/servers/my_team';
const membershipsToIdSet = (mm: MyTeamModel[]) => {
return new Set(mm.map((m) => m.id));
diff --git a/app/screens/join_team/join_team.tsx b/app/screens/join_team/join_team.tsx
index 68e804957a..b2752b35d3 100644
--- a/app/screens/join_team/join_team.tsx
+++ b/app/screens/join_team/join_team.tsx
@@ -12,6 +12,7 @@ import Loading from '@components/loading';
import TeamList from '@components/team_list';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {dismissModal} from '@screens/navigation';
import {logDebug} from '@utils/log';
@@ -19,11 +20,14 @@ import {alertTeamAddError} from '@utils/navigation';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
joinedIds: Set;
- componentId: string;
+ componentId: AvailableScreens;
closeButtonId: string;
}
+
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
container: {
paddingHorizontal: 10,
@@ -111,6 +115,7 @@ export default function JoinTeam({
}, [componentId]);
useNavButtonPressed(closeButtonId, componentId, onClosePressed, []);
+ useAndroidHardwareBackHandler(componentId, onClosePressed);
const hasOtherTeams = Boolean(otherTeams.length);
diff --git a/app/screens/latex/index.tsx b/app/screens/latex/index.tsx
index 8205a59a5c..aeaa280020 100644
--- a/app/screens/latex/index.tsx
+++ b/app/screens/latex/index.tsx
@@ -7,11 +7,16 @@ import MathView from 'react-native-math-view';
import {SafeAreaView, Edge} from 'react-native-safe-area-context';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
+import {popTopScreen} from '@screens/navigation';
import {splitLatexCodeInLines} from '@utils/markdown/latex';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
+ componentId: AvailableScreens;
content: string;
}
@@ -53,7 +58,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
};
});
-const Latex = ({content}: Props) => {
+const Latex = ({componentId, content}: Props) => {
const theme = useTheme();
const style = getStyleSheet(theme);
const lines = splitLatexCodeInLines(content);
@@ -66,6 +71,10 @@ const Latex = ({content}: Props) => {
return {'Render error: ' + error.message} ;
};
+ useAndroidHardwareBackHandler(componentId, () => {
+ popTopScreen(componentId);
+ });
+
return (
;
diff --git a/app/screens/login/index.tsx b/app/screens/login/index.tsx
index 2bfea2686d..c40c65af97 100644
--- a/app/screens/login/index.tsx
+++ b/app/screens/login/index.tsx
@@ -10,10 +10,12 @@ import {SafeAreaView} from 'react-native-safe-area-context';
import FormattedText from '@components/formatted_text';
import {Screens} from '@constants';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useIsTablet} from '@hooks/device';
+import useNavButtonPressed from '@hooks/navigation_button_pressed';
import NetworkManager from '@managers/network_manager';
import Background from '@screens/background';
-import {dismissModal, goToScreen, loginAnimationOptions} from '@screens/navigation';
+import {dismissModal, goToScreen, loginAnimationOptions, popTopScreen} from '@screens/navigation';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
@@ -23,10 +25,11 @@ import LoginOptionsSeparator from './login_options_separator';
import SsoOptions from './sso_options';
import type {LaunchProps} from '@typings/launch';
+import type {AvailableScreens} from '@typings/screens/navigation';
export interface LoginOptionsProps extends LaunchProps {
closeButtonId?: string;
- componentId: string;
+ componentId: AvailableScreens;
config: ClientConfig;
hasLoginForm: boolean;
license: ClientLicense;
@@ -132,6 +135,14 @@ const LoginOptions = ({
};
}, []);
+ const dismiss = () => {
+ dismissModal({componentId});
+ };
+
+ const pop = () => {
+ popTopScreen(componentId);
+ };
+
useEffect(() => {
const navigationEvents = Navigation.events().registerNavigationButtonPressedListener(({buttonId}) => {
if (closeButtonId && buttonId === closeButtonId) {
@@ -161,6 +172,9 @@ const LoginOptions = ({
return () => unsubscribe.remove();
}, [dimensions]);
+ useNavButtonPressed(closeButtonId || '', componentId, dismiss, []);
+ useAndroidHardwareBackHandler(componentId, pop);
+
let additionalContainerStyle;
if (numberSSOs < 3 || !hasLoginForm || (isTablet && dimensions.height > dimensions.width)) {
additionalContainerStyle = styles.flex;
diff --git a/app/screens/mfa/index.tsx b/app/screens/mfa/index.tsx
index e612d73885..d2f8edefd9 100644
--- a/app/screens/mfa/index.tsx
+++ b/app/screens/mfa/index.tsx
@@ -15,11 +15,11 @@ import ClientError from '@client/rest/error';
import FloatingTextInput from '@components/floating_text_input_label';
import FormattedText from '@components/formatted_text';
import Loading from '@components/loading';
-import {Screens} from '@constants';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useIsTablet} from '@hooks/device';
import {t} from '@i18n';
import Background from '@screens/background';
-import {resetToTeams} from '@screens/navigation';
+import {popTopScreen, resetToTeams} from '@screens/navigation';
import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
import {preventDoubleTap} from '@utils/tap';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
@@ -27,7 +27,10 @@ import {typography} from '@utils/typography';
import Shield from './mfa.svg';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type MFAProps = {
+ componentId: AvailableScreens;
config: Partial;
goToHome: (time: number, error?: never) => void;
license: Partial;
@@ -93,7 +96,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
const AnimatedSafeArea = Animated.createAnimatedComponent(SafeAreaView);
-const MFA = ({config, goToHome, license, loginId, password, serverDisplayName, serverUrl, theme}: MFAProps) => {
+const MFA = ({componentId, config, goToHome, license, loginId, password, serverDisplayName, serverUrl, theme}: MFAProps) => {
const dimensions = useWindowDimensions();
const translateX = useSharedValue(dimensions.width);
const isTablet = useIsTablet();
@@ -176,11 +179,19 @@ const MFA = ({config, goToHome, license, loginId, password, serverDisplayName, s
translateX.value = -dimensions.width;
},
};
- const unsubscribe = Navigation.events().registerComponentListener(listener, Screens.MFA);
+ const unsubscribe = Navigation.events().registerComponentListener(listener, componentId);
return () => unsubscribe.remove();
}, [dimensions]);
+ useEffect(() => {
+ translateX.value = 0;
+ }, []);
+
+ useAndroidHardwareBackHandler(componentId, () => {
+ popTopScreen(componentId);
+ });
+
return (
diff --git a/app/screens/navigation.ts b/app/screens/navigation.ts
index e3698876dc..ed23cffa2d 100644
--- a/app/screens/navigation.ts
+++ b/app/screens/navigation.ts
@@ -19,7 +19,7 @@ import {changeOpacity, setNavigatorStyles} from '@utils/theme';
import type {BottomSheetFooterProps} from '@gorhom/bottom-sheet';
import type {LaunchProps} from '@typings/launch';
-import type {NavButtons} from '@typings/screens/navigation';
+import type {AvailableScreens, NavButtons} from '@typings/screens/navigation';
const {MattermostManaged} = NativeModules;
const isRunningInSplitView = MattermostManaged.isRunningInSplitView;
@@ -67,7 +67,7 @@ function onCommandListener(name: string, params: any) {
function onPoppedListener({componentId}: ScreenPoppedEvent) {
// screen pop does not trigger registerCommandListener, but does trigger screenPoppedListener
- NavigationStore.removeScreenFromStack(componentId);
+ NavigationStore.removeScreenFromStack(componentId as AvailableScreens);
}
function onScreenWillAppear(event: ComponentWillAppearEvent) {
@@ -225,7 +225,7 @@ export function getThemeFromState(): Theme {
// This is a temporary helper function to avoid
// crashes when trying to load a screen that does
// NOT exists, this should be removed for GA
-function isScreenRegistered(screen: string) {
+function isScreenRegistered(screen: AvailableScreens) {
const notImplemented = NOT_READY.includes(screen) || !Object.values(Screens).includes(screen);
if (notImplemented) {
Alert.alert(
@@ -425,7 +425,7 @@ export function resetToTeams() {
});
}
-export function goToScreen(name: string, title: string, passProps = {}, options = {}) {
+export function goToScreen(name: AvailableScreens, title: string, passProps = {}, options = {}) {
if (!isScreenRegistered(name)) {
return '';
}
@@ -475,7 +475,7 @@ export function goToScreen(name: string, title: string, passProps = {}, options
});
}
-export async function popTopScreen(screenId?: string) {
+export async function popTopScreen(screenId?: AvailableScreens) {
try {
if (screenId) {
await Navigation.pop(screenId);
@@ -513,7 +513,7 @@ export async function dismissAllModalsAndPopToRoot() {
* @param passProps Props to pass to the screen
* @param options Navigation options
*/
-export async function dismissAllModalsAndPopToScreen(screenId: string, title: string, passProps = {}, options = {}) {
+export async function dismissAllModalsAndPopToScreen(screenId: AvailableScreens, title: string, passProps = {}, options = {}) {
await dismissAllModals();
if (NavigationStore.getScreensInStack().includes(screenId)) {
let mergeOptions = options;
@@ -539,7 +539,7 @@ export async function dismissAllModalsAndPopToScreen(screenId: string, title: st
}
}
-export function showModal(name: string, title: string, passProps = {}, options: Options = {}) {
+export function showModal(name: AvailableScreens, title: string, passProps = {}, options: Options = {}) {
if (!isScreenRegistered(name)) {
return;
}
@@ -591,7 +591,7 @@ export function showModal(name: string, title: string, passProps = {}, options:
});
}
-export function showModalOverCurrentContext(name: string, passProps = {}, options: Options = {}) {
+export function showModalOverCurrentContext(name: AvailableScreens, passProps = {}, options: Options = {}) {
const title = '';
let animations;
switch (Platform.OS) {
@@ -650,7 +650,7 @@ export function showModalOverCurrentContext(name: string, passProps = {}, option
showModal(name, title, passProps, mergeOptions);
}
-export async function dismissModal(options?: Options & { componentId: string}) {
+export async function dismissModal(options?: Options & { componentId: AvailableScreens}) {
if (!NavigationStore.hasModalsOpened()) {
return;
}
@@ -693,7 +693,7 @@ export const buildNavigationButton = (id: string, testID: string, icon?: ImageRe
text,
});
-export function setButtons(componentId: string, buttons: NavButtons = {leftButtons: [], rightButtons: []}) {
+export function setButtons(componentId: AvailableScreens, buttons: NavButtons = {leftButtons: [], rightButtons: []}) {
const options = {
topBar: {
...buttons,
@@ -703,7 +703,7 @@ export function setButtons(componentId: string, buttons: NavButtons = {leftButto
mergeNavigationOptions(componentId, options);
}
-export function showOverlay(name: string, passProps = {}, options: Options = {}) {
+export function showOverlay(name: AvailableScreens, passProps = {}, options: Options = {}) {
if (!isScreenRegistered(name)) {
return;
}
@@ -728,7 +728,7 @@ export function showOverlay(name: string, passProps = {}, options: Options = {})
});
}
-export async function dismissOverlay(componentId: string) {
+export async function dismissOverlay(componentId: AvailableScreens) {
try {
await Navigation.dismissOverlay(componentId);
} catch (error) {
@@ -769,7 +769,7 @@ export async function bottomSheet({title, renderContent, footerComponent, snapPo
}
}
-export async function dismissBottomSheet(alternativeScreen = Screens.BOTTOM_SHEET) {
+export async function dismissBottomSheet(alternativeScreen: AvailableScreens = Screens.BOTTOM_SHEET) {
DeviceEventEmitter.emit(Events.CLOSE_BOTTOM_SHEET);
await NavigationStore.waitUntilScreensIsRemoved(alternativeScreen);
}
@@ -777,7 +777,7 @@ export async function dismissBottomSheet(alternativeScreen = Screens.BOTTOM_SHEE
type AsBottomSheetArgs = {
closeButtonId: string;
props?: Record;
- screen: typeof Screens[keyof typeof Screens];
+ screen: AvailableScreens;
theme: Theme;
title: string;
}
diff --git a/app/screens/onboarding/illustrations/calls.tsx b/app/screens/onboarding/illustrations/calls.tsx
index 183a9ffc7b..56c532f511 100644
--- a/app/screens/onboarding/illustrations/calls.tsx
+++ b/app/screens/onboarding/illustrations/calls.tsx
@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import React from 'react';
-import {StyleProp, ViewStyle} from 'react-native';
import Svg, {
Ellipse,
Path,
@@ -10,6 +9,8 @@ import Svg, {
G,
} from 'react-native-svg';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
theme: Theme;
styles: StyleProp;
diff --git a/app/screens/onboarding/illustrations/chat.tsx b/app/screens/onboarding/illustrations/chat.tsx
index 4126a79ae1..91f8b65b5a 100644
--- a/app/screens/onboarding/illustrations/chat.tsx
+++ b/app/screens/onboarding/illustrations/chat.tsx
@@ -2,13 +2,14 @@
// See LICENSE.txt for license information.
import * as React from 'react';
-import {StyleProp, ViewStyle} from 'react-native';
import Svg, {
G,
Path,
Ellipse,
} from 'react-native-svg';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
theme: Theme;
styles: StyleProp;
diff --git a/app/screens/onboarding/illustrations/integrations.tsx b/app/screens/onboarding/illustrations/integrations.tsx
index 17fad9ac7b..56c9c584bf 100644
--- a/app/screens/onboarding/illustrations/integrations.tsx
+++ b/app/screens/onboarding/illustrations/integrations.tsx
@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import React from 'react';
-import {StyleProp, ViewStyle} from 'react-native';
import Svg, {
Rect,
Path,
@@ -15,6 +14,8 @@ import Svg, {
Stop,
} from 'react-native-svg';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
theme: Theme;
styles: StyleProp;
diff --git a/app/screens/onboarding/illustrations/team_communication.tsx b/app/screens/onboarding/illustrations/team_communication.tsx
index d5ec426c79..95edb40149 100644
--- a/app/screens/onboarding/illustrations/team_communication.tsx
+++ b/app/screens/onboarding/illustrations/team_communication.tsx
@@ -2,7 +2,6 @@
// See LICENSE.txt for license information.
import React from 'react';
-import {StyleProp, ViewStyle} from 'react-native';
import Svg, {
Ellipse,
Path,
@@ -10,6 +9,8 @@ import Svg, {
G,
} from 'react-native-svg';
+import type {StyleProp, ViewStyle} from 'react-native';
+
type Props = {
theme: Theme;
styles: StyleProp;
diff --git a/app/screens/onboarding/index.tsx b/app/screens/onboarding/index.tsx
index 4aea8fab10..3010b4a687 100644
--- a/app/screens/onboarding/index.tsx
+++ b/app/screens/onboarding/index.tsx
@@ -11,6 +11,7 @@ import {
Platform,
NativeSyntheticEvent,
NativeScrollEvent,
+ BackHandler,
} from 'react-native';
import {Navigation} from 'react-native-navigation';
import Animated, {useAnimatedStyle, useDerivedValue, useSharedValue, withTiming} from 'react-native-reanimated';
@@ -111,6 +112,19 @@ const Onboarding = ({
};
}, []);
+ useEffect(() => {
+ const listener = BackHandler.addEventListener('hardwareBackPress', () => {
+ if (!currentIndex.value) {
+ return false;
+ }
+
+ moveToSlide(currentIndex.value - 1);
+ return true;
+ });
+
+ return () => listener.remove();
+ }, []);
+
return (
{
diff --git a/app/screens/post_options/options/delete_post_option.tsx b/app/screens/post_options/options/delete_post_option.tsx
index 6ef2e478db..08fc88fa8f 100644
--- a/app/screens/post_options/options/delete_post_option.tsx
+++ b/app/screens/post_options/options/delete_post_option.tsx
@@ -7,15 +7,15 @@ import {Alert} from 'react-native';
import {deletePost} from '@actions/remote/post';
import {BaseOption} from '@components/common_post_options';
-import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
import type PostModel from '@typings/database/models/servers/post';
+import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
combinedPost?: Post | PostModel;
post: PostModel;
}
diff --git a/app/screens/post_options/options/edit_option.tsx b/app/screens/post_options/options/edit_option.tsx
index d444d10d94..d7ff22c1c2 100644
--- a/app/screens/post_options/options/edit_option.tsx
+++ b/app/screens/post_options/options/edit_option.tsx
@@ -12,9 +12,10 @@ import {t} from '@i18n';
import {dismissBottomSheet, showModal} from '@screens/navigation';
import type PostModel from '@typings/database/models/servers/post';
+import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
post: PostModel;
canDelete: boolean;
}
diff --git a/app/screens/post_options/options/mark_unread_option/mark_unread_option.tsx b/app/screens/post_options/options/mark_unread_option/mark_unread_option.tsx
index 79b2573c96..caa0ac6cbd 100644
--- a/app/screens/post_options/options/mark_unread_option/mark_unread_option.tsx
+++ b/app/screens/post_options/options/mark_unread_option/mark_unread_option.tsx
@@ -12,11 +12,12 @@ import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
import type PostModel from '@typings/database/models/servers/post';
+import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
isCRTEnabled: boolean;
- sourceScreen: typeof Screens[keyof typeof Screens];
+ sourceScreen: AvailableScreens;
post: PostModel;
teamId: string;
}
diff --git a/app/screens/post_options/options/pin_channel_option.tsx b/app/screens/post_options/options/pin_channel_option.tsx
index 1ffb873f9c..b62d495c16 100644
--- a/app/screens/post_options/options/pin_channel_option.tsx
+++ b/app/screens/post_options/options/pin_channel_option.tsx
@@ -5,13 +5,14 @@ import React, {useCallback} from 'react';
import {togglePinPost} from '@actions/remote/post';
import {BaseOption} from '@components/common_post_options';
-import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type PinChannelProps = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
isPostPinned: boolean;
postId: string;
}
diff --git a/app/screens/post_options/post_options.tsx b/app/screens/post_options/post_options.tsx
index bc4572a1d9..e94c3315d3 100644
--- a/app/screens/post_options/post_options.tsx
+++ b/app/screens/post_options/post_options.tsx
@@ -28,6 +28,7 @@ import ReactionBar from './reaction_bar';
import type PostModel from '@typings/database/models/servers/post';
import type ThreadModel from '@typings/database/models/servers/thread';
+import type {AvailableScreens} from '@typings/screens/navigation';
const POST_OPTIONS_BUTTON = 'close-post-options';
@@ -40,10 +41,10 @@ type PostOptionsProps = {
canReply: boolean;
combinedPost?: Post | PostModel;
isSaved: boolean;
- sourceScreen: typeof Screens[keyof typeof Screens];
+ sourceScreen: AvailableScreens;
post: PostModel;
thread?: ThreadModel;
- componentId: string;
+ componentId: AvailableScreens;
bindings: AppBinding[];
serverUrl: string;
};
diff --git a/app/screens/post_options/reaction_bar/reaction_bar.tsx b/app/screens/post_options/reaction_bar/reaction_bar.tsx
index 00663fea6f..93a25af9af 100644
--- a/app/screens/post_options/reaction_bar/reaction_bar.tsx
+++ b/app/screens/post_options/reaction_bar/reaction_bar.tsx
@@ -24,8 +24,10 @@ import {makeStyleSheetFromTheme} from '@utils/theme';
import PickReaction from './pick_reaction';
import Reaction from './reaction';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type QuickReactionProps = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
recentEmojis: string[];
postId: string;
};
diff --git a/app/screens/review_app/index.tsx b/app/screens/review_app/index.tsx
index 9013cd8ed4..b8e5176674 100644
--- a/app/screens/review_app/index.tsx
+++ b/app/screens/review_app/index.tsx
@@ -13,14 +13,17 @@ import CompassIcon from '@components/compass_icon';
import ReviewAppIllustration from '@components/illustrations/review_app';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useBackNavigation from '@hooks/navigate_back';
import {dismissOverlay, showShareFeedbackOverlay} from '@screens/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
hasAskedBefore: boolean;
- componentId: string;
+ componentId: AvailableScreens;
}
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
@@ -151,6 +154,7 @@ const ReviewApp = ({
}, [close, componentId]);
useBackNavigation(onPressClose);
+ useAndroidHardwareBackHandler(componentId, onPressClose);
const doAfterAnimation = useCallback(() => {
executeAfterDone.current();
diff --git a/app/screens/server/form.tsx b/app/screens/server/form.tsx
index faed9cef4d..28b1865c61 100644
--- a/app/screens/server/form.tsx
+++ b/app/screens/server/form.tsx
@@ -5,7 +5,6 @@ import React, {MutableRefObject, useCallback, useEffect, useRef} from 'react';
import {useIntl} from 'react-intl';
import {Keyboard, Platform, useWindowDimensions, View} from 'react-native';
import Button from 'react-native-button';
-import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
import FloatingTextInput, {FloatingTextInputRef} from '@components/floating_text_input_label';
import FormattedText from '@components/formatted_text';
@@ -16,6 +15,8 @@ import {buttonBackgroundStyle, buttonTextStyle} from '@utils/buttonStyles';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
+
type Props = {
autoFocus?: boolean;
buttonDisabled: boolean;
diff --git a/app/screens/server/index.tsx b/app/screens/server/index.tsx
index c45feab09c..9183aa6a17 100644
--- a/app/screens/server/index.tsx
+++ b/app/screens/server/index.tsx
@@ -4,7 +4,7 @@
import {useManagedConfig} from '@mattermost/react-native-emm';
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {useIntl} from 'react-intl';
-import {Alert, Platform, useWindowDimensions, View} from 'react-native';
+import {Alert, BackHandler, Platform, useWindowDimensions, View} from 'react-native';
import {KeyboardAwareScrollView} from 'react-native-keyboard-aware-scroll-view';
import {Navigation} from 'react-native-navigation';
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
@@ -13,15 +13,15 @@ import {SafeAreaView} from 'react-native-safe-area-context';
import {doPing} from '@actions/remote/general';
import {fetchConfigAndLicense} from '@actions/remote/systems';
import LocalConfig from '@assets/config.json';
-import ClientError from '@client/rest/error';
import AppVersion from '@components/app_version';
import {Screens, Launch} from '@constants';
+import useNavButtonPressed from '@hooks/navigation_button_pressed';
import {t} from '@i18n';
import PushNotifications from '@init/push_notifications';
import NetworkManager from '@managers/network_manager';
import {getServerByDisplayName, getServerByIdentifier} from '@queries/app/servers';
import Background from '@screens/background';
-import {dismissModal, goToScreen, loginAnimationOptions} from '@screens/navigation';
+import {dismissModal, goToScreen, loginAnimationOptions, popTopScreen} from '@screens/navigation';
import {getErrorMessage} from '@utils/client_error';
import {canReceiveNotifications} from '@utils/push_proxy';
import {loginOptions} from '@utils/server';
@@ -31,12 +31,14 @@ import {getServerUrlAfterRedirect, isValidUrl, sanitizeUrl} from '@utils/url';
import ServerForm from './form';
import ServerHeader from './header';
+import type ClientError from '@client/rest/error';
import type {DeepLinkWithData, LaunchProps} from '@typings/launch';
+import type {AvailableScreens} from '@typings/screens/navigation';
interface ServerProps extends LaunchProps {
animated?: boolean;
closeButtonId?: string;
- componentId: string;
+ componentId: AvailableScreens;
isModal?: boolean;
theme: Theme;
}
@@ -92,6 +94,11 @@ const Server = ({
const disableServerUrl = Boolean(managedConfig?.allowOtherServers === 'false' && managedConfig?.serverUrl);
const additionalServer = launchType === Launch.AddServerFromDeepLink || launchType === Launch.AddServer;
+ const dismiss = () => {
+ NetworkManager.invalidateClient(url);
+ dismissModal({componentId});
+ };
+
useEffect(() => {
let serverName: string | undefined = defaultDisplayName || managedConfig?.serverName || LocalConfig.DefaultServerName;
let serverUrl: string | undefined = defaultServerUrl || managedConfig?.serverUrl || LocalConfig.DefaultServerUrl;
@@ -157,18 +164,26 @@ const Server = ({
}, [componentId, url, dimensions]);
useEffect(() => {
- const navigationEvents = Navigation.events().registerNavigationButtonPressedListener(({buttonId}) => {
- if (closeButtonId && buttonId === closeButtonId) {
- NetworkManager.invalidateClient(url);
- dismissModal({componentId});
+ const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
+ if (LocalConfig.ShowOnboarding && animated) {
+ popTopScreen(Screens.SERVER);
+ return true;
}
+ if (isModal) {
+ dismiss();
+ return true;
+ }
+
+ return false;
});
PushNotifications.registerIfNeeded();
- return () => navigationEvents.remove();
+ return () => backHandler.remove();
}, []);
+ useNavButtonPressed(closeButtonId || '', componentId, dismiss, []);
+
const displayLogin = (serverUrl: string, config: ClientConfig, license: ClientLicense) => {
const {enabledSSOs, hasLoginForm, numberSSOs, ssoOptions} = loginOptions(config, license);
const passProps = {
diff --git a/app/screens/settings/about/about.tsx b/app/screens/settings/about/about.tsx
index 4f46840b48..e9554a68fb 100644
--- a/app/screens/settings/about/about.tsx
+++ b/app/screens/settings/about/about.tsx
@@ -11,7 +11,9 @@ import CompassIcon from '@components/compass_icon';
import FormattedText from '@components/formatted_text';
import AboutLinks from '@constants/about_links';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {t} from '@i18n';
+import {popTopScreen} from '@screens/navigation';
import SettingContainer from '@screens/settings/setting_container';
import SettingSeparator from '@screens/settings/settings_separator';
import {preventDoubleTap} from '@utils/tap';
@@ -24,6 +26,8 @@ import Subtitle from './subtitle';
import Title from './title';
import TosPrivacyContainer from './tos_privacy';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
const MATTERMOST_BUNDLE_IDS = ['com.mattermost.rnbeta', 'com.mattermost.rn'];
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
@@ -92,10 +96,11 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
});
type AboutProps = {
+ componentId: AvailableScreens;
config: ClientConfig;
license: ClientLicense;
}
-const About = ({config, license}: AboutProps) => {
+const About = ({componentId, config, license}: AboutProps) => {
const intl = useIntl();
const theme = useTheme();
const styles = getStyleSheet(theme);
@@ -162,6 +167,10 @@ const About = ({config, license}: AboutProps) => {
};
}, [config]);
+ useAndroidHardwareBackHandler(componentId, () => {
+ popTopScreen(componentId);
+ });
+
return (
diff --git a/app/screens/settings/advanced/index.tsx b/app/screens/settings/advanced/index.tsx
index 8a9a1a0d99..af67f829e4 100644
--- a/app/screens/settings/advanced/index.tsx
+++ b/app/screens/settings/advanced/index.tsx
@@ -17,6 +17,7 @@ import {makeStyleSheetFromTheme} from '@utils/theme';
import SettingContainer from '../setting_container';
import SettingOption from '../setting_option';
+import type {AvailableScreens} from '@typings/screens/navigation';
import type {ReadDirItem} from 'react-native-fs';
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
@@ -31,7 +32,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => {
const EMPTY_FILES: ReadDirItem[] = [];
type AdvancedSettingsProps = {
- componentId: string;
+ componentId: AvailableScreens;
};
const AdvancedSettings = ({componentId}: AdvancedSettingsProps) => {
const theme = useTheme();
diff --git a/app/screens/settings/config.ts b/app/screens/settings/config.ts
index 84d477468c..9e65b269c5 100644
--- a/app/screens/settings/config.ts
+++ b/app/screens/settings/config.ts
@@ -5,6 +5,7 @@ import {t} from '@i18n';
import {goToScreen} from '@screens/navigation';
import {typography} from '@utils/typography';
+import type {AvailableScreens} from '@typings/screens/navigation';
import type {IntlShape} from 'react-intl';
export const getSaveButton = (buttonId: string, intl: IntlShape, color: string) => ({
@@ -17,7 +18,7 @@ export const getSaveButton = (buttonId: string, intl: IntlShape, color: string)
...typography('Body', 100, 'SemiBold'),
});
-export const gotoSettingsScreen = (screen: string, title: string) => {
+export const gotoSettingsScreen = (screen: AvailableScreens, title: string) => {
const passProps = {};
const options = {
topBar: {
diff --git a/app/screens/settings/display/display.tsx b/app/screens/settings/display/display.tsx
index b6b5d9a45a..d957c521cc 100644
--- a/app/screens/settings/display/display.tsx
+++ b/app/screens/settings/display/display.tsx
@@ -6,8 +6,9 @@ import {useIntl} from 'react-intl';
import {Screens} from '@constants';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {t} from '@i18n';
-import {goToScreen} from '@screens/navigation';
+import {goToScreen, popTopScreen} from '@screens/navigation';
import {gotoSettingsScreen} from '@screens/settings/config';
import {preventDoubleTap} from '@utils/tap';
import {getUserTimezoneProps} from '@utils/user';
@@ -16,6 +17,7 @@ import SettingContainer from '../setting_container';
import SettingItem from '../setting_item';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
const TIME_FORMAT = [
{
@@ -40,12 +42,13 @@ const TIMEZONE_FORMAT = [
];
type DisplayProps = {
+ componentId: AvailableScreens;
currentUser: UserModel;
hasMilitaryTimeFormat: boolean;
isThemeSwitchingEnabled: boolean;
isTimezoneEnabled: boolean;
}
-const Display = ({currentUser, hasMilitaryTimeFormat, isThemeSwitchingEnabled, isTimezoneEnabled}: DisplayProps) => {
+const Display = ({componentId, currentUser, hasMilitaryTimeFormat, isThemeSwitchingEnabled, isTimezoneEnabled}: DisplayProps) => {
const intl = useIntl();
const theme = useTheme();
const timezone = useMemo(() => getUserTimezoneProps(currentUser), [currentUser.timezone]);
@@ -68,6 +71,10 @@ const Display = ({currentUser, hasMilitaryTimeFormat, isThemeSwitchingEnabled, i
gotoSettingsScreen(screen, title);
});
+ useAndroidHardwareBackHandler(componentId, () => {
+ popTopScreen(componentId);
+ });
+
return (
{isThemeSwitchingEnabled && (
diff --git a/app/screens/settings/display_clock/display_clock.tsx b/app/screens/settings/display_clock/display_clock.tsx
index 71b195e651..812510b07b 100644
--- a/app/screens/settings/display_clock/display_clock.tsx
+++ b/app/screens/settings/display_clock/display_clock.tsx
@@ -16,13 +16,15 @@ import SettingContainer from '../setting_container';
import SettingOption from '../setting_option';
import SettingSeparator from '../settings_separator';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
const CLOCK_TYPE = {
NORMAL: 'NORMAL',
MILITARY: 'MILITARY',
} as const;
type DisplayClockProps = {
- componentId: string;
+ componentId: AvailableScreens;
currentUserId: string;
hasMilitaryTimeFormat: boolean;
}
diff --git a/app/screens/settings/display_theme/display_theme.tsx b/app/screens/settings/display_theme/display_theme.tsx
index 7af4775e77..e5de3ec359 100644
--- a/app/screens/settings/display_theme/display_theme.tsx
+++ b/app/screens/settings/display_theme/display_theme.tsx
@@ -15,9 +15,11 @@ import SettingContainer from '../setting_container';
import CustomTheme from './custom_theme';
import {ThemeTiles} from './theme_tiles';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type DisplayThemeProps = {
allowedThemeKeys: string[];
- componentId: string;
+ componentId: AvailableScreens;
currentTeamId: string;
currentUserId: string;
}
diff --git a/app/screens/settings/display_timezone/display_timezone.tsx b/app/screens/settings/display_timezone/display_timezone.tsx
index bd45432655..9e8e0b4983 100644
--- a/app/screens/settings/display_timezone/display_timezone.tsx
+++ b/app/screens/settings/display_timezone/display_timezone.tsx
@@ -19,10 +19,11 @@ import SettingOption from '../setting_option';
import SettingSeparator from '../settings_separator';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
type DisplayTimezoneProps = {
currentUser: UserModel;
- componentId: string;
+ componentId: AvailableScreens;
}
const DisplayTimezone = ({currentUser, componentId}: DisplayTimezoneProps) => {
const intl = useIntl();
diff --git a/app/screens/settings/display_timezone_select/index.tsx b/app/screens/settings/display_timezone_select/index.tsx
index 10edbded25..967fb54b2a 100644
--- a/app/screens/settings/display_timezone_select/index.tsx
+++ b/app/screens/settings/display_timezone_select/index.tsx
@@ -18,6 +18,8 @@ import {getTimezoneRegion} from '@utils/user';
import TimezoneRow from './timezone_row';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
flexGrow: {
@@ -54,7 +56,7 @@ const getItemLayout = (_data: string[], index: number) => ({
});
type SelectTimezonesProps = {
- componentId: string;
+ componentId: AvailableScreens;
onBack: (tz: string) => void;
currentTimezone: string;
}
diff --git a/app/screens/settings/notification_auto_responder/notification_auto_responder.tsx b/app/screens/settings/notification_auto_responder/notification_auto_responder.tsx
index aff5d93b80..157c58f045 100644
--- a/app/screens/settings/notification_auto_responder/notification_auto_responder.tsx
+++ b/app/screens/settings/notification_auto_responder/notification_auto_responder.tsx
@@ -23,6 +23,7 @@ import SettingOption from '../setting_option';
import SettingSeparator from '../settings_separator';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
const label = {
id: t('notification_settings.auto_responder.message'),
@@ -57,7 +58,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
});
type NotificationAutoResponderProps = {
- componentId: string;
+ componentId: AvailableScreens;
currentUser: UserModel;
}
const NotificationAutoResponder = ({currentUser, componentId}: NotificationAutoResponderProps) => {
diff --git a/app/screens/settings/notification_email/notification_email.tsx b/app/screens/settings/notification_email/notification_email.tsx
index a94de6655f..c88e12c118 100644
--- a/app/screens/settings/notification_email/notification_email.tsx
+++ b/app/screens/settings/notification_email/notification_email.tsx
@@ -24,6 +24,7 @@ import SettingOption from '../setting_option';
import SettingSeparator from '../settings_separator';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
return {
@@ -54,7 +55,7 @@ const emailFooterCRTText = {
};
type NotificationEmailProps = {
- componentId: string;
+ componentId: AvailableScreens;
currentUser: UserModel;
emailInterval: string;
enableEmailBatching: boolean;
diff --git a/app/screens/settings/notification_mention/mention_settings.tsx b/app/screens/settings/notification_mention/mention_settings.tsx
index 03b7316d20..90885d8bce 100644
--- a/app/screens/settings/notification_mention/mention_settings.tsx
+++ b/app/screens/settings/notification_mention/mention_settings.tsx
@@ -23,6 +23,7 @@ import SettingOption from '../setting_option';
import SettingSeparator from '../settings_separator';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
const mentionHeaderText = {
id: t('notification_settings.mentions.keywords_mention'),
@@ -72,7 +73,7 @@ const getMentionProps = (currentUser: UserModel) => {
};
type MentionSectionProps = {
- componentId: string;
+ componentId: AvailableScreens;
currentUser: UserModel;
isCRTEnabled: boolean;
}
diff --git a/app/screens/settings/notification_mention/notification_mention.tsx b/app/screens/settings/notification_mention/notification_mention.tsx
index 2642522b93..45a362775a 100644
--- a/app/screens/settings/notification_mention/notification_mention.tsx
+++ b/app/screens/settings/notification_mention/notification_mention.tsx
@@ -8,9 +8,10 @@ import SettingContainer from '../setting_container';
import MentionSettings from './mention_settings';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
type NotificationMentionProps = {
- componentId: string;
+ componentId: AvailableScreens;
currentUser: UserModel;
isCRTEnabled: boolean;
}
diff --git a/app/screens/settings/notification_push/notification_push.tsx b/app/screens/settings/notification_push/notification_push.tsx
index 4075108b6a..02251b393a 100644
--- a/app/screens/settings/notification_push/notification_push.tsx
+++ b/app/screens/settings/notification_push/notification_push.tsx
@@ -19,9 +19,10 @@ import MobilePushStatus from './push_status';
import MobilePushThread from './push_thread';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
type NotificationMobileProps = {
- componentId: string;
+ componentId: AvailableScreens;
currentUser: UserModel;
isCRTEnabled: boolean;
sendPushNotifications: boolean;
diff --git a/app/screens/settings/notifications/notifications.tsx b/app/screens/settings/notifications/notifications.tsx
index e7bbd92a4b..d687d9bd37 100644
--- a/app/screens/settings/notifications/notifications.tsx
+++ b/app/screens/settings/notifications/notifications.tsx
@@ -5,7 +5,9 @@ import React, {useCallback, useMemo} from 'react';
import {useIntl} from 'react-intl';
import {General, Screens} from '@constants';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {t} from '@i18n';
+import {popTopScreen} from '@screens/navigation';
import {gotoSettingsScreen} from '@screens/settings/config';
import {getEmailInterval, getEmailIntervalTexts, getNotificationProps} from '@utils/user';
@@ -13,6 +15,7 @@ import SettingContainer from '../setting_container';
import SettingItem from '../setting_item';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
const mentionTexts = {
crtOn: {
@@ -26,6 +29,7 @@ const mentionTexts = {
};
type NotificationsProps = {
+ componentId: AvailableScreens;
currentUser: UserModel;
emailInterval: string;
enableAutoResponder: boolean;
@@ -34,6 +38,7 @@ type NotificationsProps = {
sendEmailNotifications: boolean;
}
const Notifications = ({
+ componentId,
currentUser,
emailInterval,
enableAutoResponder,
@@ -86,6 +91,10 @@ const Notifications = ({
gotoSettingsScreen(screen, title);
}, []);
+ useAndroidHardwareBackHandler(componentId, () => {
+ popTopScreen(componentId);
+ });
+
return (
{
@@ -40,7 +42,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
});
type SettingsProps = {
- componentId: string;
+ componentId: AvailableScreens;
helpLink: string;
showHelp: boolean;
siteName: string;
@@ -75,7 +77,6 @@ const Settings = ({componentId, helpLink, showHelp, siteName}: SettingsProps) =>
}, []);
useAndroidHardwareBackHandler(componentId, close);
-
useNavButtonPressed(CLOSE_BUTTON_ID, componentId, close, []);
const goToNotifications = preventDoubleTap(() => {
diff --git a/app/screens/share_feedback/index.tsx b/app/screens/share_feedback/index.tsx
index 50269f4838..65a87f3e4c 100644
--- a/app/screens/share_feedback/index.tsx
+++ b/app/screens/share_feedback/index.tsx
@@ -12,13 +12,16 @@ import CompassIcon from '@components/compass_icon';
import ShareFeedbackIllustration from '@components/illustrations/share_feedback';
import {useServerUrl} from '@context/server';
import {useTheme} from '@context/theme';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import useBackNavigation from '@hooks/navigate_back';
import {dismissOverlay} from '@screens/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
- componentId: string;
+ componentId: AvailableScreens;
}
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
@@ -117,6 +120,7 @@ const ShareFeedback = ({
}, [close, componentId]);
useBackNavigation(onPressNo);
+ useAndroidHardwareBackHandler(componentId, onPressNo);
const doAfterAnimation = useCallback(() => {
executeAfterDone.current();
diff --git a/app/screens/snack_bar/index.tsx b/app/screens/snack_bar/index.tsx
index 9d28a2b6fa..ec218850b9 100644
--- a/app/screens/snack_bar/index.tsx
+++ b/app/screens/snack_bar/index.tsx
@@ -27,10 +27,21 @@ import {dismissOverlay} from '@screens/navigation';
import {makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
+type SnackBarProps = {
+ componentId: AvailableScreens;
+ onAction?: () => void;
+ barType: keyof typeof SNACK_BAR_TYPE;
+ sourceScreen: AvailableScreens;
+}
+
const SNACK_BAR_WIDTH = 96;
const SNACK_BAR_HEIGHT = 56;
const SNACK_BAR_BOTTOM_RATIO = 0.04;
+const caseScreens: AvailableScreens[] = [Screens.PERMALINK, Screens.MENTIONS, Screens.SAVED_MESSAGES];
+
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
return {
text: {
@@ -70,13 +81,6 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
};
});
-type SnackBarProps = {
- componentId: string;
- onAction?: () => void;
- barType: keyof typeof SNACK_BAR_TYPE;
- sourceScreen: typeof Screens[keyof typeof Screens];
-}
-
const SnackBar = ({barType, componentId, onAction, sourceScreen}: SnackBarProps) => {
const [showSnackBar, setShowSnackBar] = useState();
const intl = useIntl();
@@ -115,7 +119,7 @@ const SnackBar = ({barType, componentId, onAction, sourceScreen}: SnackBarProps)
width: (SNACK_BAR_WIDTH / 100) * diffWidth,
};
break;
- case [Screens.PERMALINK, Screens.MENTIONS, Screens.SAVED_MESSAGES].includes(sourceScreen):
+ case caseScreens.includes(sourceScreen):
tabletStyle = {
marginBottom: 0,
marginLeft: 0,
diff --git a/app/screens/sso/index.tsx b/app/screens/sso/index.tsx
index 0718d53752..84e0338aeb 100644
--- a/app/screens/sso/index.tsx
+++ b/app/screens/sso/index.tsx
@@ -11,19 +11,22 @@ import {SafeAreaView} from 'react-native-safe-area-context';
import {ssoLogin} from '@actions/remote/session';
import ClientError from '@client/rest/error';
import {Screens, Sso} from '@constants';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
+import useNavButtonPressed from '@hooks/navigation_button_pressed';
import NetworkManager from '@managers/network_manager';
import Background from '@screens/background';
-import {dismissModal, resetToHome, resetToTeams} from '@screens/navigation';
+import {dismissModal, popTopScreen, resetToHome, resetToTeams} from '@screens/navigation';
import {logWarning} from '@utils/log';
import SSOWithRedirectURL from './sso_with_redirect_url';
import SSOWithWebView from './sso_with_webview';
import type {LaunchProps} from '@typings/launch';
+import type {AvailableScreens} from '@typings/screens/navigation';
interface SSOProps extends LaunchProps {
closeButtonId?: string;
- componentId: string;
+ componentId: AvailableScreens;
config: Partial;
license: Partial;
ssoType: string;
@@ -114,6 +117,13 @@ const SSO = ({
resetToHome({extra, launchError: hasError, launchType, serverUrl, time});
};
+ const dismiss = () => {
+ if (serverUrl) {
+ NetworkManager.invalidateClient(serverUrl);
+ }
+ dismissModal({componentId});
+ };
+
const transform = useAnimatedStyle(() => {
const duration = Platform.OS === 'android' ? 250 : 350;
return {
@@ -136,18 +146,19 @@ const SSO = ({
}, [dimensions]);
useEffect(() => {
- const navigationEvents = Navigation.events().registerNavigationButtonPressedListener(({buttonId}) => {
- if (closeButtonId && buttonId === closeButtonId) {
- if (serverUrl) {
- NetworkManager.invalidateClient(serverUrl);
- }
- dismissModal({componentId});
- }
- });
-
- return () => navigationEvents.remove();
+ translateX.value = 0;
}, []);
+ useNavButtonPressed(closeButtonId || '', componentId, dismiss, []);
+ useAndroidHardwareBackHandler(componentId, () => {
+ if (closeButtonId) {
+ dismiss();
+ return;
+ }
+
+ popTopScreen(componentId);
+ });
+
const props = {
doSSOLogin,
loginError,
diff --git a/app/screens/sso/sso.test.tsx b/app/screens/sso/sso.test.tsx
index 7fd6adaaaf..69ec1fd965 100644
--- a/app/screens/sso/sso.test.tsx
+++ b/app/screens/sso/sso.test.tsx
@@ -3,7 +3,7 @@
import React from 'react';
-import {Preferences} from '@constants';
+import {Preferences, Screens} from '@constants';
import LaunchType from '@constants/launch';
import {renderWithIntl} from '@test/intl-test-helper';
@@ -23,7 +23,7 @@ jest.mock('@utils/url', () => {
describe('SSO', () => {
const baseProps = {
- componentId: 'SSO',
+ componentId: Screens.SSO,
license: {
IsLicensed: 'true',
},
diff --git a/app/screens/sso/sso_with_webview.tsx b/app/screens/sso/sso_with_webview.tsx
index 2f70cc7ab1..0a58643734 100644
--- a/app/screens/sso/sso_with_webview.tsx
+++ b/app/screens/sso/sso_with_webview.tsx
@@ -6,12 +6,6 @@ import React, {useEffect} from 'react';
import {useIntl} from 'react-intl';
import {Alert, Platform, Text, View} from 'react-native';
import {WebView} from 'react-native-webview';
-import {
- WebViewErrorEvent,
- WebViewMessageEvent,
- WebViewNavigation,
- WebViewNavigationEvent,
-} from 'react-native-webview/lib/WebViewTypes';
import urlParse from 'url-parse';
import Loading from '@components/loading';
@@ -19,6 +13,13 @@ import {Sso} from '@constants';
import {popTopScreen} from '@screens/navigation';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
+import type {
+ WebViewErrorEvent,
+ WebViewMessageEvent,
+ WebViewNavigation,
+ WebViewNavigationEvent,
+} from 'react-native-webview/lib/WebViewTypes';
+
interface SSOWithWebViewProps {
completeUrlPath: string;
doSSOLogin: (bearerToken: string, csrfToken: string) => void;
diff --git a/app/screens/table/index.tsx b/app/screens/table/index.tsx
index 7b870a1058..5343d6d217 100644
--- a/app/screens/table/index.tsx
+++ b/app/screens/table/index.tsx
@@ -5,7 +5,13 @@ import React from 'react';
import {Platform, ScrollView, StyleSheet} from 'react-native';
import {SafeAreaView} from 'react-native-safe-area-context';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
+import {popTopScreen} from '@screens/navigation';
+
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
+ componentId: AvailableScreens;
renderAsFlex: boolean;
renderRows: (isFullView: boolean) => JSX.Element|null;
width: number;
@@ -30,10 +36,14 @@ const styles = StyleSheet.create({
},
});
-const Table = ({renderAsFlex, renderRows, width}: Props) => {
+const Table = ({componentId, renderAsFlex, renderRows, width}: Props) => {
const content = renderRows(true);
const viewStyle = renderAsFlex ? styles.displayFlex : {width};
+ useAndroidHardwareBackHandler(componentId, () => {
+ popTopScreen(componentId);
+ });
+
if (Platform.OS === 'android') {
return (
diff --git a/app/screens/terms_of_service/terms_of_service.tsx b/app/screens/terms_of_service/terms_of_service.tsx
index 09cfe737f2..be3360621a 100644
--- a/app/screens/terms_of_service/terms_of_service.tsx
+++ b/app/screens/terms_of_service/terms_of_service.tsx
@@ -26,10 +26,12 @@ import {getMarkdownTextStyles, getMarkdownBlockStyles} from '@utils/markdown';
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
import {typography} from '@utils/typography';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
siteName?: string;
showToS: boolean;
- componentId: string;
+ componentId: AvailableScreens;
}
const getStyleSheet = makeStyleSheetFromTheme((theme) => {
diff --git a/app/screens/thread/thread.tsx b/app/screens/thread/thread.tsx
index 148a9d05d2..4f91220736 100644
--- a/app/screens/thread/thread.tsx
+++ b/app/screens/thread/thread.tsx
@@ -3,7 +3,6 @@
import React, {useCallback, useEffect, useRef, useState} from 'react';
import {LayoutChangeEvent, StyleSheet, View} from 'react-native';
-import {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
import {Edge, SafeAreaView} from 'react-native-safe-area-context';
import CurrentCallBar from '@calls/components/current_call_bar';
@@ -13,6 +12,7 @@ import PostDraft from '@components/post_draft';
import RoundedHeaderContext from '@components/rounded_header_context';
import {Screens} from '@constants';
import {THREAD_ACCESSORIES_CONTAINER_NATIVE_ID} from '@constants/post_draft';
+import useAndroidHardwareBackHandler from '@hooks/android_back_handler';
import {useAppState} from '@hooks/device';
import useDidUpdate from '@hooks/did_update';
import {useKeyboardTrackingPaused} from '@hooks/keyboard_tracking';
@@ -22,9 +22,11 @@ import EphemeralStore from '@store/ephemeral_store';
import ThreadPostList from './thread_post_list';
import type PostModel from '@typings/database/models/servers/post';
+import type {AvailableScreens} from '@typings/screens/navigation';
+import type {KeyboardTrackingViewRef} from 'react-native-keyboard-tracking-view';
type ThreadProps = {
- componentId: string;
+ componentId: AvailableScreens;
rootPost?: PostModel;
isInACall: boolean;
};
@@ -42,7 +44,12 @@ const Thread = ({componentId, rootPost, isInACall}: ThreadProps) => {
const [containerHeight, setContainerHeight] = useState(0);
const rootId = rootPost?.id || '';
+ const close = () => {
+ popTopScreen(componentId);
+ };
+
useKeyboardTrackingPaused(postDraftRef, rootId, trackKeyboardForScreens);
+ useAndroidHardwareBackHandler(componentId, close);
useEffect(() => {
return () => {
@@ -52,7 +59,7 @@ const Thread = ({componentId, rootPost, isInACall}: ThreadProps) => {
useDidUpdate(() => {
if (!rootPost) {
- popTopScreen(componentId);
+ close();
}
}, [componentId, rootPost]);
diff --git a/app/screens/thread/thread_post_list/index.ts b/app/screens/thread/thread_post_list/index.ts
index cdf3401fbd..81ecda79f7 100644
--- a/app/screens/thread/thread_post_list/index.ts
+++ b/app/screens/thread/thread_post_list/index.ts
@@ -3,7 +3,6 @@
import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider';
import withObservables from '@nozbe/with-observables';
-import {AppStateStatus} from 'react-native';
import {of as of$} from 'rxjs';
import {switchMap} from 'rxjs/operators';
@@ -16,6 +15,7 @@ import ThreadPostList from './thread_post_list';
import type {WithDatabaseArgs} from '@typings/database/database';
import type PostModel from '@typings/database/models/servers/post';
+import type {AppStateStatus} from 'react-native';
type Props = WithDatabaseArgs & {
forceQueryAfterAppState: AppStateStatus;
diff --git a/app/screens/thread_options/options/mark_as_unread_option.tsx b/app/screens/thread_options/options/mark_as_unread_option.tsx
index 9cc462d2ed..bb99285d35 100644
--- a/app/screens/thread_options/options/mark_as_unread_option.tsx
+++ b/app/screens/thread_options/options/mark_as_unread_option.tsx
@@ -5,15 +5,15 @@ import React, {useCallback} from 'react';
import {markThreadAsRead, markThreadAsUnread} from '@actions/remote/thread';
import {BaseOption} from '@components/common_post_options';
-import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
import type ThreadModel from '@typings/database/models/servers/thread';
+import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
teamId: string;
thread: ThreadModel;
}
diff --git a/app/screens/thread_options/options/open_in_channel_option.tsx b/app/screens/thread_options/options/open_in_channel_option.tsx
index b0df2b0339..a666c16d1e 100644
--- a/app/screens/thread_options/options/open_in_channel_option.tsx
+++ b/app/screens/thread_options/options/open_in_channel_option.tsx
@@ -6,13 +6,14 @@ import {useIntl} from 'react-intl';
import {showPermalink} from '@actions/remote/permalink';
import {BaseOption} from '@components/common_post_options';
-import {Screens} from '@constants';
import {useServerUrl} from '@context/server';
import {t} from '@i18n';
import {dismissBottomSheet} from '@screens/navigation';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type Props = {
- bottomSheetId: typeof Screens[keyof typeof Screens];
+ bottomSheetId: AvailableScreens;
threadId: string;
}
const OpenInChannelOption = ({bottomSheetId, threadId}: Props) => {
diff --git a/app/screens/user_profile/title/index.tsx b/app/screens/user_profile/title/index.tsx
index f961c7e3a0..4253f7bc6d 100644
--- a/app/screens/user_profile/title/index.tsx
+++ b/app/screens/user_profile/title/index.tsx
@@ -98,8 +98,9 @@ const UserProfileTitle = ({
uri: imageUrl,
width: 400,
height: 400,
+ lastPictureUpdate: user.lastPictureUpdate,
name: displayName,
- mime_type: 'images/png',
+ mime_type: 'image/png',
authorId: user.id,
type: 'avatar',
};
diff --git a/app/screens/user_profile/user_profile.tsx b/app/screens/user_profile/user_profile.tsx
index e0f1eaf780..dcaf576faf 100644
--- a/app/screens/user_profile/user_profile.tsx
+++ b/app/screens/user_profile/user_profile.tsx
@@ -21,6 +21,7 @@ import UserProfileOptions, {OptionsType} from './options';
import UserProfileTitle from './title';
import type UserModel from '@typings/database/models/servers/user';
+import type {AvailableScreens} from '@typings/screens/navigation';
type Props = {
channelId?: string;
@@ -34,7 +35,7 @@ type Props = {
isMilitaryTime: boolean;
isSystemAdmin: boolean;
isTeamAdmin: boolean;
- location: string;
+ location: AvailableScreens;
teamId: string;
teammateDisplayName: string;
user: UserModel;
@@ -46,6 +47,7 @@ const TITLE_HEIGHT = 118;
const OPTIONS_HEIGHT = 82;
const SINGLE_OPTION_HEIGHT = 68;
const LABEL_HEIGHT = 58;
+const channelContextScreens: AvailableScreens[] = [Screens.CHANNEL, Screens.THREAD];
const UserProfile = ({
channelId, closeButtonId, currentUserId, enablePostIconOverride, enablePostUsernameOverride,
@@ -56,7 +58,7 @@ const UserProfile = ({
const {formatMessage, locale} = useIntl();
const serverUrl = useServerUrl();
const {bottom} = useSafeAreaInsets();
- const channelContext = [Screens.CHANNEL, Screens.THREAD].includes(location);
+ const channelContext = channelContextScreens.includes(location);
const showOptions: OptionsType = channelContext && !user.isBot ? 'all' : 'message';
const override = Boolean(userIconOverride || usernameOverride);
const timezone = getUserTimezone(user);
diff --git a/app/store/navigation_store.ts b/app/store/navigation_store.ts
index 3681c26079..2f19fce4e3 100644
--- a/app/store/navigation_store.ts
+++ b/app/store/navigation_store.ts
@@ -1,19 +1,21 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import type {AvailableScreens} from '@typings/screens/navigation';
+
class NavigationStore {
- private screensInStack: string[] = [];
- private modalsInStack: string[] = [];
+ private screensInStack: AvailableScreens[] = [];
+ private modalsInStack: AvailableScreens[] = [];
private visibleTab = 'Home';
private tosOpen = false;
- addModalToStack = (modalId: string) => {
+ addModalToStack = (modalId: AvailableScreens) => {
this.removeModalFromStack(modalId);
this.addScreenToStack(modalId);
this.modalsInStack.unshift(modalId);
};
- addScreenToStack = (screenId: string) => {
+ addScreenToStack = (screenId: AvailableScreens) => {
this.removeScreenFromStack(screenId);
this.screensInStack.unshift(screenId);
};
@@ -36,21 +38,21 @@ class NavigationStore {
isToSOpen = () => this.tosOpen;
- popTo = (screenId: string) => {
+ popTo = (screenId: AvailableScreens) => {
const index = this.screensInStack.indexOf(screenId);
if (index > -1) {
this.screensInStack.splice(0, index);
}
};
- removeScreenFromStack = (screenId: string) => {
+ removeScreenFromStack = (screenId: AvailableScreens) => {
const index = this.screensInStack.indexOf(screenId);
if (index > -1) {
this.screensInStack.splice(index, 1);
}
};
- removeModalFromStack = (modalId: string) => {
+ removeModalFromStack = (modalId: AvailableScreens) => {
const indexInStack = this.screensInStack.indexOf(modalId);
if (indexInStack > -1) {
// This removes all the screens that were on top of the modal
@@ -78,7 +80,7 @@ class NavigationStore {
* and can easily run forever if the screen is never prevesented.
* @param screenId string
*/
- waitUntilScreenHasLoaded = async (screenId: string) => {
+ waitUntilScreenHasLoaded = async (screenId: AvailableScreens) => {
let found = false;
while (!found) {
// eslint-disable-next-line no-await-in-loop
@@ -94,7 +96,7 @@ class NavigationStore {
* this function will run until the screen is in the top
* @param screenId string
*/
- waitUntilScreenIsTop = async (screenId: string) => {
+ waitUntilScreenIsTop = async (screenId: AvailableScreens) => {
let found = false;
while (!found) {
// eslint-disable-next-line no-await-in-loop
@@ -111,7 +113,7 @@ class NavigationStore {
* and can easily run forever if the screen is never removed.
* @param screenId string
*/
- waitUntilScreensIsRemoved = async (screenId: string) => {
+ waitUntilScreensIsRemoved = async (screenId: AvailableScreens) => {
let found = false;
while (!found) {
// eslint-disable-next-line no-await-in-loop
diff --git a/app/utils/channel/index.ts b/app/utils/channel/index.ts
index a87dd6b61d..d1ed84125b 100644
--- a/app/utils/channel/index.ts
+++ b/app/utils/channel/index.ts
@@ -1,6 +1,5 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
import {Channel, General, Permissions} from '@constants';
import {t, DEFAULT_LOCALE} from '@i18n';
@@ -10,6 +9,7 @@ import {generateId} from '../general';
import {cleanUpUrlable} from '../url';
import type ChannelModel from '@typings/database/models/servers/channel';
+import type {IntlShape} from 'react-intl';
export function getDirectChannelName(id: string, otherId: string): string {
let handle;
diff --git a/app/utils/client_error.ts b/app/utils/client_error.ts
index b7103e25fa..111e72cd23 100644
--- a/app/utils/client_error.ts
+++ b/app/utils/client_error.ts
@@ -1,10 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
-
import {cleanUrlForLogging} from '@utils/url';
+import type {IntlShape} from 'react-intl';
+
export class ClientError extends Error {
details: Error;
intl?: {defaultMessage?: string; id: string} | { defaultMessage?: string; id: string } | { id: string; defaultMessage?: string; values: any } | { id: string; defaultMessage?: string };
diff --git a/app/utils/deep_link/index.ts b/app/utils/deep_link/index.ts
index 61c03acf62..6ae6080824 100644
--- a/app/utils/deep_link/index.ts
+++ b/app/utils/deep_link/index.ts
@@ -14,7 +14,7 @@ import DatabaseManager from '@database/manager';
import {DEFAULT_LOCALE, getTranslations} from '@i18n';
import {getActiveServerUrl} from '@queries/app/servers';
import {getCurrentUser, queryUsersByUsername} from '@queries/servers/user';
-import {dismissAllModalsAndPopToRoot, showModal} from '@screens/navigation';
+import {dismissAllModalsAndPopToRoot} from '@screens/navigation';
import EphemeralStore from '@store/ephemeral_store';
import NavigationStore from '@store/navigation_store';
import {errorBadChannel, errorUnkownUser} from '@utils/draft';
@@ -23,7 +23,10 @@ import {escapeRegex} from '@utils/markdown';
import {addNewServer} from '@utils/server';
import {removeProtocol} from '@utils/url';
-import type {DeepLinkChannel, DeepLinkDM, DeepLinkGM, DeepLinkPermalink, DeepLinkPlugin, DeepLinkWithData, LaunchProps} from '@typings/launch';
+import type {DeepLinkChannel, DeepLinkDM, DeepLinkGM, DeepLinkPermalink, DeepLinkWithData, LaunchProps} from '@typings/launch';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
+const deepLinkScreens: AvailableScreens[] = [Screens.HOME, Screens.CHANNEL, Screens.GLOBAL_THREADS, Screens.THREAD];
export async function handleDeepLink(deepLinkUrl: string, intlShape?: IntlShape, location?: string) {
try {
@@ -88,21 +91,25 @@ export async function handleDeepLink(deepLinkUrl: string, intlShape?: IntlShape,
}
case DeepLink.Permalink: {
const deepLinkData = parsed.data as DeepLinkPermalink;
- if (NavigationStore.hasModalsOpened() || ![Screens.HOME, Screens.CHANNEL, Screens.GLOBAL_THREADS, Screens.THREAD].includes(NavigationStore.getVisibleScreen())) {
+ if (
+ NavigationStore.hasModalsOpened() ||
+ !deepLinkScreens.includes(NavigationStore.getVisibleScreen())
+ ) {
await dismissAllModalsAndPopToRoot();
}
showPermalink(existingServerUrl, deepLinkData.teamName, deepLinkData.postId);
break;
}
case DeepLink.Plugin: {
- const deepLinkData = parsed.data as DeepLinkPlugin;
- showModal('PluginInternal', deepLinkData.id, {link: location});
+ // https://mattermost.atlassian.net/browse/MM-49846
+ // const deepLinkData = parsed.data as DeepLinkPlugin;
+ // showModal('PluginInternal', deepLinkData.id, {link: location});
break;
}
}
return {error: false};
} catch (error) {
- logError('Failed to open channel from deeplink', error);
+ logError('Failed to open channel from deeplink', error, location);
return {error: true};
}
}
diff --git a/app/utils/document/index.ts b/app/utils/document/index.ts
index 48f3a9df8e..ac8e723f80 100644
--- a/app/utils/document/index.ts
+++ b/app/utils/document/index.ts
@@ -1,9 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
import {Alert} from 'react-native';
+import type {IntlShape} from 'react-intl';
+
export function alertFailedToOpenDocument(file: FileInfo, intl: IntlShape) {
Alert.alert(
intl.formatMessage({
diff --git a/app/utils/draft/index.ts b/app/utils/draft/index.ts
index ff95beee1f..d3760ea81f 100644
--- a/app/utils/draft/index.ts
+++ b/app/utils/draft/index.ts
@@ -1,13 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {MessageDescriptor} from '@formatjs/intl/src/types';
import {Alert, AlertButton} from 'react-native';
import {General} from '@constants';
import {CODE_REGEX} from '@constants/autocomplete';
import {t} from '@i18n';
+import type {MessageDescriptor} from '@formatjs/intl/src/types';
import type {IntlShape} from 'react-intl';
type AlertCallback = (value?: string) => void;
diff --git a/app/utils/emoji/helpers.ts b/app/utils/emoji/helpers.ts
index 148d82e6b6..26ef3ff632 100644
--- a/app/utils/emoji/helpers.ts
+++ b/app/utils/emoji/helpers.ts
@@ -2,13 +2,13 @@
// See LICENSE.txt for license information.
import emojiRegex from 'emoji-regex';
-import Fuse from 'fuse.js';
import SystemModel from '@database/models/server/system';
import {Emojis, EmojiIndicesByAlias, EmojiIndicesByUnicode} from '.';
import type CustomEmojiModel from '@typings/database/models/servers/custom_emoji';
+import type Fuse from 'fuse.js';
const UNICODE_REGEX = /\p{Emoji}/u;
diff --git a/app/utils/error_handling.ts b/app/utils/error_handling.ts
index 3a17a1ff07..f2b612c7f9 100644
--- a/app/utils/error_handling.ts
+++ b/app/utils/error_handling.ts
@@ -10,7 +10,6 @@ import {
import {DEFAULT_LOCALE, getTranslations, t} from '@i18n';
import {dismissAllModals} from '@screens/navigation';
-import {ClientError} from '@utils/client_error';
import {isBetaApp} from '@utils/general';
import {
captureException,
@@ -20,6 +19,8 @@ import {
import {logWarning} from './log';
+import type {ClientError} from '@utils/client_error';
+
class JavascriptAndNativeErrorHandler {
initializeErrorHandling = () => {
initializeSentry();
diff --git a/app/utils/file/file_picker/index.ts b/app/utils/file/file_picker/index.ts
index 2cbfb6c4da..dcfbef5d03 100644
--- a/app/utils/file/file_picker/index.ts
+++ b/app/utils/file/file_picker/index.ts
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
import {Alert, NativeModules, Platform, StatusBar} from 'react-native';
import AndroidOpenSettings from 'react-native-android-open-settings';
import DeviceInfo from 'react-native-device-info';
@@ -11,7 +10,9 @@ import Permissions from 'react-native-permissions';
import {dismissBottomSheet} from '@screens/navigation';
import {extractFileInfo, lookupMimeType} from '@utils/file';
-import {logError} from '@utils/log';
+import {logWarning} from '@utils/log';
+
+import type {IntlShape} from 'react-intl';
const MattermostManaged = NativeModules.MattermostManaged;
@@ -46,7 +47,7 @@ export default class FilePickerUtil {
id: 'mobile.camera_photo_permission_denied_description',
defaultMessage:
'Take photos and upload them to your server or save them to your device. Open Settings to grant {applicationName} read and write access to your camera.',
- }),
+ }, {applicationName}),
},
storage: {
title: formatMessage(
@@ -61,7 +62,7 @@ export default class FilePickerUtil {
id: 'mobile.storage_permission_denied_description',
defaultMessage:
'Upload files to your server. Open Settings to grant {applicationName} Read and Write access to files on this device.',
- }),
+ }, {applicationName}),
},
denied_ios: {
title: formatMessage(
@@ -76,7 +77,7 @@ export default class FilePickerUtil {
id: 'mobile.ios.photos_permission_denied_description',
defaultMessage:
'Upload photos and videos to your server or save them to your device. Open Settings to grant {applicationName} Read and Write access to your photo and video library.',
- }),
+ }, {applicationName}),
},
denied_android: {
title: formatMessage(
@@ -91,7 +92,7 @@ export default class FilePickerUtil {
id: 'mobile.android.photos_permission_denied_description',
defaultMessage:
'Upload photos to your server or save them to your device. Open Settings to grant {applicationName} Read and Write access to your photo library.',
- }),
+ }, {applicationName}),
},
};
@@ -117,7 +118,7 @@ export default class FilePickerUtil {
private getFilesFromResponse = async (response: ImagePickerResponse): Promise => {
if (!response?.assets?.length) {
- logError('no assets in response');
+ logWarning('no assets in response');
return [];
}
@@ -138,7 +139,7 @@ export default class FilePickerUtil {
if (uri) {
files.push({...file, fileName, uri, type, width: file.width, height: file.height});
} else {
- logError('attaching file reponse return empty uri', file);
+ logWarning('attaching file reponse return empty uri', file);
}
}
})));
@@ -187,40 +188,39 @@ export default class FilePickerUtil {
};
private hasStoragePermission = async () => {
- if (Platform.OS === 'ios') {
- return true;
- }
+ if (Platform.OS === 'android' && Platform.Version < 32) {
+ const storagePermission = Permissions.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
+ let permissionRequest;
+ const hasPermissionToStorage = await Permissions.check(storagePermission);
+ switch (hasPermissionToStorage) {
+ case Permissions.RESULTS.DENIED:
+ permissionRequest = await Permissions.request(storagePermission);
+ return permissionRequest === Permissions.RESULTS.GRANTED;
+ case Permissions.RESULTS.BLOCKED: {
+ const {title, text} = this.getPermissionDeniedMessage();
- const storagePermission = Permissions.PERMISSIONS.ANDROID.READ_EXTERNAL_STORAGE;
- let permissionRequest;
- const hasPermissionToStorage = await Permissions.check(storagePermission);
- switch (hasPermissionToStorage) {
- case Permissions.RESULTS.DENIED:
- permissionRequest = await Permissions.request(storagePermission);
- return permissionRequest === Permissions.RESULTS.GRANTED;
- break;
- case Permissions.RESULTS.BLOCKED: {
- const {title, text} = this.getPermissionDeniedMessage();
-
- Alert.alert(title, text, [
- {
- text: this.intl.formatMessage({
- id: 'mobile.permission_denied_dismiss',
- defaultMessage: "Don't Allow",
- }),
- },
- {
- text: this.intl.formatMessage({
- id: 'mobile.permission_denied_retry',
- defaultMessage: 'Settings',
- }),
- onPress: () => AndroidOpenSettings.appDetailsSettings(),
- },
- ]);
- return false;
+ Alert.alert(title, text, [
+ {
+ text: this.intl.formatMessage({
+ id: 'mobile.permission_denied_dismiss',
+ defaultMessage: "Don't Allow",
+ }),
+ },
+ {
+ text: this.intl.formatMessage({
+ id: 'mobile.permission_denied_retry',
+ defaultMessage: 'Settings',
+ }),
+ onPress: () => AndroidOpenSettings.appDetailsSettings(),
+ },
+ ]);
+ return false;
+ }
+ default: return true;
}
- default: return true;
}
+
+ return true;
};
private buildUri = async (doc: DocumentPickerResponse) => {
@@ -228,10 +228,14 @@ export default class FilePickerUtil {
if (Platform.OS === 'android') {
// For android we need to retrieve the realPath in case the file being imported is from the cloud
- const newUri = await MattermostManaged.getFilePath(doc.uri);
- uri = newUri?.filePath;
- if (uri === undefined) {
- return {doc: undefined};
+ if (doc.fileCopyUri) {
+ uri = doc.fileCopyUri;
+ } else {
+ const newUri = await MattermostManaged.getFilePath(doc.uri);
+ uri = newUri?.filePath;
+ if (uri === undefined) {
+ return {doc: undefined};
+ }
}
doc.uri = uri;
@@ -272,7 +276,7 @@ export default class FilePickerUtil {
if (hasPermission) {
try {
- const docResponse = (await DocumentPicker.pick({allowMultiSelection, type: [fileType]}));
+ const docResponse = (await DocumentPicker.pick({allowMultiSelection, type: [fileType], copyTo: 'cachesDirectory'}));
const proDocs = docResponse.map(async (d: DocumentPickerResponse) => {
const {doc} = await this.buildUri(d);
return doc;
@@ -302,7 +306,7 @@ export default class FilePickerUtil {
launchImageLibrary(options, async (response: ImagePickerResponse) => {
StatusBar.setHidden(false);
if (response.errorMessage || response.didCancel) {
- logError('Attach failed', response.errorMessage || (response.didCancel ? 'cancelled' : ''));
+ logWarning('Attach failed', response.errorMessage || (response.didCancel ? 'cancelled' : ''));
return;
}
diff --git a/app/utils/file/index.ts b/app/utils/file/index.ts
index 348a156181..8b1e124cce 100644
--- a/app/utils/file/index.ts
+++ b/app/utils/file/index.ts
@@ -1,16 +1,12 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {PastedFile} from '@mattermost/react-native-paste-input';
import Model from '@nozbe/watermelondb/Model';
import mimeDB from 'mime-db';
-import {IntlShape} from 'react-intl';
import {Alert, Platform} from 'react-native';
import AndroidOpenSettings from 'react-native-android-open-settings';
import DeviceInfo from 'react-native-device-info';
-import {DocumentPickerResponse} from 'react-native-document-picker';
import FileSystem from 'react-native-fs';
-import {Asset} from 'react-native-image-picker';
import Permissions, {PERMISSIONS} from 'react-native-permissions';
import {Files} from '@constants';
@@ -20,7 +16,11 @@ import {logError} from '@utils/log';
import {deleteEntititesFile, getIOSAppGroupDetails} from '@utils/mattermost_managed';
import {urlSafeBase64Encode} from '@utils/security';
+import type {PastedFile} from '@mattermost/react-native-paste-input';
import type FileModel from '@typings/database/models/servers/file';
+import type {IntlShape} from 'react-intl';
+import type {DocumentPickerResponse} from 'react-native-document-picker';
+import type {Asset} from 'react-native-image-picker';
const EXTRACT_TYPE_REGEXP = /^\s*([^;\s]*)(?:;|\s|$)/;
const CONTENT_DISPOSITION_REGEXP = /inline;filename=".*\.([a-z]+)";/i;
@@ -477,52 +477,52 @@ export const fileExists = async (path: string) => {
};
export const hasWriteStoragePermission = async (intl: IntlShape) => {
- if (Platform.OS === 'ios') {
- return true;
- }
-
- const storagePermission = PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE;
- let permissionRequest;
- const hasPermissionToStorage = await Permissions.check(storagePermission);
- switch (hasPermissionToStorage) {
- case Permissions.RESULTS.DENIED:
- permissionRequest = await Permissions.request(storagePermission);
- return permissionRequest === Permissions.RESULTS.GRANTED;
- case Permissions.RESULTS.BLOCKED: {
- const applicationName = DeviceInfo.getApplicationName();
- const title = intl.formatMessage(
- {
- id: 'mobile.storage_permission_denied_title',
+ if (Platform.OS === 'android' && Platform.Version < 33) {
+ const storagePermission = PERMISSIONS.ANDROID.WRITE_EXTERNAL_STORAGE;
+ let permissionRequest;
+ const hasPermissionToStorage = await Permissions.check(storagePermission);
+ switch (hasPermissionToStorage) {
+ case Permissions.RESULTS.DENIED:
+ permissionRequest = await Permissions.request(storagePermission);
+ return permissionRequest === Permissions.RESULTS.GRANTED;
+ case Permissions.RESULTS.BLOCKED: {
+ const applicationName = DeviceInfo.getApplicationName();
+ const title = intl.formatMessage(
+ {
+ id: 'mobile.storage_permission_denied_title',
+ defaultMessage:
+ '{applicationName} would like to access your files',
+ },
+ {applicationName},
+ );
+ const text = intl.formatMessage({
+ id: 'mobile.write_storage_permission_denied_description',
defaultMessage:
- '{applicationName} would like to access your files',
- },
- {applicationName},
- );
- const text = intl.formatMessage({
- id: 'mobile.write_storage_permission_denied_description',
- defaultMessage:
- 'Save files to your device. Open Settings to grant {applicationName} write access to files on this device.',
- });
+ 'Save files to your device. Open Settings to grant {applicationName} write access to files on this device.',
+ });
- Alert.alert(title, text, [
- {
- text: intl.formatMessage({
- id: 'mobile.permission_denied_dismiss',
- defaultMessage: "Don't Allow",
- }),
- },
- {
- text: intl.formatMessage({
- id: 'mobile.permission_denied_retry',
- defaultMessage: 'Settings',
- }),
- onPress: () => AndroidOpenSettings.appDetailsSettings(),
- },
- ]);
- return false;
+ Alert.alert(title, text, [
+ {
+ text: intl.formatMessage({
+ id: 'mobile.permission_denied_dismiss',
+ defaultMessage: "Don't Allow",
+ }),
+ },
+ {
+ text: intl.formatMessage({
+ id: 'mobile.permission_denied_retry',
+ defaultMessage: 'Settings',
+ }),
+ onPress: () => AndroidOpenSettings.appDetailsSettings(),
+ },
+ ]);
+ return false;
+ }
+ default: return true;
}
- default: return true;
}
+
+ return true;
};
export const getAllFilesInCachesDirectory = async (serverUrl: string) => {
diff --git a/app/utils/files.tsx b/app/utils/files.tsx
index d8375da910..b100f6c37e 100644
--- a/app/utils/files.tsx
+++ b/app/utils/files.tsx
@@ -1,9 +1,10 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {ChannelModel} from '@database/models/server';
import {fileToGalleryItem} from '@utils/gallery';
+import type ChannelModel from '@typings/database/models/servers/channel';
+
export const getNumberFileMenuOptions = (canDownloadFiles: boolean, publicLinkEnabled: boolean) => {
let numberItems = 1;
numberItems += canDownloadFiles ? 1 : 0;
@@ -42,3 +43,7 @@ export const getOrderedGalleryItems = (orderedFileInfos: FileInfo[]) => {
return orderedFileInfos.map((f) => fileToGalleryItem(f, f.user_id));
};
+export const pathWithPrefix = (prefix: string, path: string) => {
+ const p = path.startsWith(prefix) ? '' : prefix;
+ return `${p}${path}`;
+};
diff --git a/app/utils/gallery/index.ts b/app/utils/gallery/index.ts
index 856886ee06..94f04f662d 100644
--- a/app/utils/gallery/index.ts
+++ b/app/utils/gallery/index.ts
@@ -28,7 +28,7 @@ export const clampVelocity = (velocity: number, minVelocity: number, maxVelocity
return Math.max(Math.min(velocity, -minVelocity), -maxVelocity);
};
-export const fileToGalleryItem = (file: FileInfo, authorId?: string): GalleryItemType => {
+export const fileToGalleryItem = (file: FileInfo, authorId?: string, lastPictureUpdate = 0): GalleryItemType => {
let type: GalleryItemType['type'] = 'file';
if (isVideo(file)) {
type = 'video';
@@ -41,6 +41,7 @@ export const fileToGalleryItem = (file: FileInfo, authorId?: string): GalleryIte
extension: file.extension,
height: file.height,
id: file.id || generateId('uid'),
+ lastPictureUpdate,
mime_type: file.mime_type,
name: file.name,
posterUri: type === 'video' ? file.mini_preview : undefined, // set the video poster to the mini_preview
@@ -105,10 +106,10 @@ export function measureItem(ref: React.RefObject, sharedValues: GalleryMana
try {
const measurements = measure(ref);
- sharedValues.x.value = measurements.pageX;
- sharedValues.y.value = measurements.pageY;
- sharedValues.width.value = measurements.width;
- sharedValues.height.value = measurements.height;
+ sharedValues.x.value = measurements?.pageX || 999999;
+ sharedValues.y.value = measurements?.pageY || 999999;
+ sharedValues.width.value = measurements?.width || 0;
+ sharedValues.height.value = measurements?.height || 0;
} catch (err) {
sharedValues.x.value = 999999;
sharedValues.y.value = 999999;
diff --git a/app/utils/integrations.ts b/app/utils/integrations.ts
index 3cde2f69bd..7fe8092e07 100644
--- a/app/utils/integrations.ts
+++ b/app/utils/integrations.ts
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {KeyboardTypeOptions} from 'react-native';
+import type {KeyboardTypeOptions} from 'react-native';
type DialogError = {
id: string;
diff --git a/app/utils/markdown/index.ts b/app/utils/markdown/index.ts
index ca0d283d54..486a80371f 100644
--- a/app/utils/markdown/index.ts
+++ b/app/utils/markdown/index.ts
@@ -30,6 +30,7 @@ export const getMarkdownTextStyles = makeStyleSheetFromTheme((theme: Theme) => {
},
strong: {
fontFamily: 'OpenSans-SemiBold',
+ fontWeight: '600',
},
del: {
textDecorationLine: 'line-through',
@@ -213,30 +214,6 @@ export function escapeRegex(text: string) {
return text.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&');
}
-export function switchKeyboardForCodeBlocks(value: string, cursorPosition: number) {
- if (Platform.OS === 'ios' && parseInt(Platform.Version, 10) >= 12) {
- const regexForCodeBlock = /^```$(.*?)^```$|^```$(.*)/gms;
-
- const matches = [];
- let nextMatch;
- while ((nextMatch = regexForCodeBlock.exec(value)) !== null) {
- matches.push({
- startOfMatch: regexForCodeBlock.lastIndex - nextMatch[0].length,
- endOfMatch: regexForCodeBlock.lastIndex + 1,
- });
- }
-
- const cursorIsInsideCodeBlock = matches.some((match) => cursorPosition >= match.startOfMatch && cursorPosition <= match.endOfMatch);
-
- // 'email-address' keyboardType prevents iOS emdash autocorrect
- if (cursorIsInsideCodeBlock) {
- return 'email-address';
- }
- }
-
- return 'default';
-}
-
export const getMarkdownImageSize = (
isReplyPost: boolean,
isTablet: boolean,
diff --git a/app/utils/navigation/index.ts b/app/utils/navigation/index.ts
index eb50c96081..7f813af833 100644
--- a/app/utils/navigation/index.ts
+++ b/app/utils/navigation/index.ts
@@ -1,14 +1,16 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
import {Alert} from 'react-native';
import {Navigation, Options} from 'react-native-navigation';
import {Screens, ServerErrors} from '@constants';
import {isServerError} from '@utils/errors';
-export const appearanceControlledScreens = new Set([
+import type {AvailableScreens} from '@typings/screens/navigation';
+import type {IntlShape} from 'react-intl';
+
+export const appearanceControlledScreens = new Set([
Screens.ONBOARDING,
Screens.SERVER,
Screens.LOGIN,
diff --git a/app/utils/push_proxy.ts b/app/utils/push_proxy.ts
index 999504742e..e207c9841e 100644
--- a/app/utils/push_proxy.ts
+++ b/app/utils/push_proxy.ts
@@ -1,12 +1,13 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
import {Alert} from 'react-native';
import {PUSH_PROXY_RESPONSE_NOT_AVAILABLE, PUSH_PROXY_RESPONSE_UNKNOWN, PUSH_PROXY_STATUS_NOT_AVAILABLE, PUSH_PROXY_STATUS_UNKNOWN, PUSH_PROXY_STATUS_VERIFIED} from '@constants/push_proxy';
import EphemeralStore from '@store/ephemeral_store';
+import type {IntlShape} from 'react-intl';
+
export function canReceiveNotifications(serverUrl: string, verification: string, intl: IntlShape) {
switch (verification) {
case PUSH_PROXY_RESPONSE_NOT_AVAILABLE:
diff --git a/app/utils/sentry.ts b/app/utils/sentry.ts
index 188a36cd43..4017a38be5 100644
--- a/app/utils/sentry.ts
+++ b/app/utils/sentry.ts
@@ -1,8 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {Database} from '@nozbe/watermelondb';
-import {Breadcrumb, Event} from '@sentry/types';
import {Platform} from 'react-native';
import {Navigation} from 'react-native-navigation';
@@ -15,6 +13,9 @@ import {isBetaApp} from '@utils/general';
import {ClientError} from './client_error';
import {logError, logWarning} from './log';
+import type {Database} from '@nozbe/watermelondb';
+import type {Breadcrumb, Event} from '@sentry/types';
+
export const BREADCRUMB_UNCAUGHT_APP_ERROR = 'uncaught-app-error';
export const BREADCRUMB_UNCAUGHT_NON_ERROR = 'uncaught-non-error';
diff --git a/app/utils/server/index.ts b/app/utils/server/index.ts
index debff00faf..b284076cdc 100644
--- a/app/utils/server/index.ts
+++ b/app/utils/server/index.ts
@@ -1,7 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {IntlShape} from 'react-intl';
import {Alert, AlertButton} from 'react-native';
import CompassIcon from '@components/compass_icon';
@@ -14,6 +13,7 @@ import {tryOpenURL} from '@utils/url';
import type ServersModel from '@typings/database/models/app/servers';
import type {DeepLinkWithData} from '@typings/launch';
+import type {IntlShape} from 'react-intl';
export function isSupportedServer(currentVersion: string) {
return isMinimumServerVersion(currentVersion, SupportedServer.MAJOR_VERSION, SupportedServer.MIN_VERSION, SupportedServer.PATCH_VERSION);
diff --git a/app/utils/snack_bar/index.ts b/app/utils/snack_bar/index.ts
index 0ccbc70e54..62f8afdbec 100644
--- a/app/utils/snack_bar/index.ts
+++ b/app/utils/snack_bar/index.ts
@@ -4,10 +4,12 @@ import {Screens} from '@constants';
import {SNACK_BAR_TYPE} from '@constants/snack_bar';
import {showOverlay} from '@screens/navigation';
+import type {AvailableScreens} from '@typings/screens/navigation';
+
type ShowSnackBarArgs = {
barType: keyof typeof SNACK_BAR_TYPE;
onAction?: () => void;
- sourceScreen?: typeof Screens[keyof typeof Screens];
+ sourceScreen?: AvailableScreens;
};
export const showSnackBar = (passProps: ShowSnackBarArgs) => {
diff --git a/app/utils/theme/index.ts b/app/utils/theme/index.ts
index 519b3fcae4..e10f307037 100644
--- a/app/utils/theme/index.ts
+++ b/app/utils/theme/index.ts
@@ -10,9 +10,9 @@ import {Preferences} from '@constants';
import {MODAL_SCREENS_WITHOUT_BACK, SCREENS_AS_BOTTOM_SHEET, SCREENS_WITH_TRANSPARENT_BACKGROUND} from '@constants/screens';
import EphemeralStore from '@store/ephemeral_store';
import NavigationStore from '@store/navigation_store';
-import {NamedStyles} from '@typings/global/styles';
import {appearanceControlledScreens, mergeNavigationOptions} from '@utils/navigation';
+import type {NamedStyles} from '@typings/global/styles';
import type {Options} from 'react-native-navigation';
const rgbPattern = /^rgba?\((\d+),(\d+),(\d+)(?:,([\d.]+))?\)$/;
diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json
index 565aca508b..f7ee276f50 100644
--- a/assets/base/i18n/en.json
+++ b/assets/base/i18n/en.json
@@ -327,6 +327,28 @@
"intro.welcome.public": "Add some more team members to the channel or start a conversation below.",
"invite_people_to_team.message": "Here’s a link to collaborate and communicate with us on Mattermost.",
"invite_people_to_team.title": "Join the {team} team",
+ "invite.members.already_member": "This person is already a team member",
+ "invite.members.user_is_guest": "Contact your admin to make this guest a full member",
+ "invite.search.email_invite": "invite",
+ "invite.search.no_results": "No one found matching",
+ "invite.searchPlaceholder": "Type a name or email address…",
+ "invite.send_error": "Something went wrong while trying to send invitations. Please check your network connection and try again.",
+ "invite.send_invite": "Send",
+ "invite.sendInvitationsTo": "Send invitations to…",
+ "invite.shareLink": "Share link",
+ "invite.summary.done": "Done",
+ "invite.summary.email_invite": "An invitation email has been sent",
+ "invite.summary.error": "{invitationsCount, plural, one {Invitation} other {Invitations}} could not be sent successfully",
+ "invite.summary.member_invite": "Invited as a member of {teamDisplayName}",
+ "invite.summary.not_sent": "{notSentCount, plural, one {Invitation wasn’t} other {Invitations weren’t}} sent",
+ "invite.summary.report.notSent": "{count} {count, plural, one {invitation} other {invitations}} not sent",
+ "invite.summary.report.sent": "{count} successful {count, plural, one {invitation} other {invitations}}",
+ "invite.summary.sent": "Your {sentCount, plural, one {invitation has} other {invitations have}} been sent",
+ "invite.summary.smtp_failure": "SMTP is not configured in System Console",
+ "invite.summary.some_not_sent": "{notSentCount, plural, one {An invitation was} other {Some invitations were}} not sent",
+ "invite.summary.try_again": "Try again",
+ "invite.title": "Invite",
+ "invite.title.summary": "Invite summary",
"join_team.error.group_error": "You need to be a member of a linked group to join this team.",
"join_team.error.message": "There has been an error joining the team",
"join_team.error.title": "Error joining a team",
@@ -408,6 +430,7 @@
"mobile.calls_not_available_msg": "Please contact your System Admin to enable the feature.",
"mobile.calls_not_available_option": "(Not available)",
"mobile.calls_not_available_title": "Calls is not enabled",
+ "mobile.calls_not_connected": "You're not connected to a call in the current channel.",
"mobile.calls_ok": "OK",
"mobile.calls_okay": "Okay",
"mobile.calls_open_channel": "Open Channel",
@@ -423,6 +446,7 @@
"mobile.calls_see_logs": "See server logs",
"mobile.calls_speaker": "Speaker",
"mobile.calls_start_call": "Start Call",
+ "mobile.calls_start_call_exists": "A call is already ongoing in the channel.",
"mobile.calls_stop_recording": "Stop Recording",
"mobile.calls_unmute": "Unmute",
"mobile.calls_viewing_screen": "You are viewing {name}'s screen",
@@ -503,7 +527,9 @@
"mobile.login_options.sso_continue": "Continue with",
"mobile.managed.blocked_by": "Blocked by {vendor}",
"mobile.managed.exit": "Exit",
- "mobile.managed.jailbreak": "Jailbroken devices are not trusted by {vendor}, please exit the app.",
+ "mobile.managed.jailbreak": "Jailbroken devices are not trusted by {vendor}.\n\nReason {reason}\n\n\n\nDebug info: {debug}\n\nPlease exit the app.",
+ "mobile.managed.jailbreak_no_debug_info": "Not available",
+ "mobile.managed.jailbreak_no_reason": "Not available",
"mobile.managed.not_secured.android": "This device must be secured with a screen lock to use Mattermost.",
"mobile.managed.not_secured.ios": "This device must be secured with a passcode to use Mattermost.\n\nGo to Settings > Face ID & Passcode.",
"mobile.managed.not_secured.ios.touchId": "This device must be secured with a passcode to use Mattermost.\n\nGo to Settings > Touch ID & Passcode.",
diff --git a/assets/base/i18n/en_AU.json b/assets/base/i18n/en_AU.json
index beef334f8e..0c43c80aaf 100644
--- a/assets/base/i18n/en_AU.json
+++ b/assets/base/i18n/en_AU.json
@@ -937,5 +937,7 @@
"connection_banner.connecting": "Connecting...",
"skintone_selector.tooltip.title": "Choose your default skin tone",
"skintone_selector.tooltip.description": "You can now choose the skin tone you prefer to use for your emojis.",
- "default_skin_tone": "Default Skin Tone"
+ "default_skin_tone": "Default Skin Tone",
+ "mobile.calls_rec": "rec",
+ "mobile.calls_host": "host"
}
diff --git a/assets/base/i18n/nl.json b/assets/base/i18n/nl.json
index 286cba2e26..c42c4df830 100644
--- a/assets/base/i18n/nl.json
+++ b/assets/base/i18n/nl.json
@@ -1,17 +1,17 @@
{
"about.date": "Compilatiedatum:",
- "about.enterpriseEditione1": "Enterprise-Editie",
- "about.enterpriseEditionLearn": "Meer informatie over de Enterprise-Editie op ",
+ "about.enterpriseEditione1": "Enterprise-editie",
+ "about.enterpriseEditionLearn": "Meer informatie over de Enterprise-editie op ",
"about.enterpriseEditionSt": "Moderne communicatie achter jouw eigen firewall.",
"about.hash": "Compilatiehash:",
"about.hashee": "EE Compilatiehash:",
"about.teamEditionLearn": "Word lid van de Mattermost-gemeenschap op ",
"about.teamEditionSt": "Alle team-communicatie op één plaats, doorzoekbaar en van overal bereikbaar.",
"about.teamEditiont0": "Team Editie",
- "about.teamEditiont1": "Enterprise Editie",
+ "about.teamEditiont1": "Enterprise-editie",
"api.channel.add_guest.added": "{addedUsername} werd toegevoegd aan het kanaal als gast door {username}.",
"api.channel.add_member.added": "{addedUsername} is toegevoegd aan het kanaal door {username}.",
- "api.channel.guest_join_channel.post_and_forget": "{username} is toegetreden tot het kanaal als gast.",
+ "api.channel.guest_join_channel.post_and_forget": "{username} is toegetreden tot het kanaal als gastgebruiker.",
"apps.error": "Fout: {error}",
"apps.error.command.field_missing": "Verplichte velden ontbreken: `{fieldName}`.",
"apps.error.command.same_channel": "Kanaal herhaald voor veld `{fieldName}`: `{option}`.",
@@ -55,16 +55,16 @@
"apps.error.responses.unexpected_error": "Een onverwachte fout ontvangen.",
"apps.error.responses.unknown_field_error": "Fout ontvangen voor een onbekend veld. Veldnaam: `{field}`. Fout:`{error}`.",
"apps.error.responses.unknown_type": "Het app-antwoordtype wordt niet ondersteund. Type antwoord: {type}.",
- "apps.error.unknown": "Er is een onbekende fout opgetreden.",
+ "apps.error.unknown": "Onbekende fout opgetreden.",
"apps.suggestion.dynamic.error": "Dynamische selectiefout",
"apps.suggestion.errors.parser_error": "Fout bij het parsen",
"apps.suggestion.no_dynamic": "Geen gegevens ontvangen voor dynamische suggesties",
"apps.suggestion.no_static": "Geen passende opties.",
"apps.suggestion.no_suggestion": "Geen passende suggesties.",
"archivedChannelMessage": "Je bekijkt een **gearchiveerd kanaal**. Er kunnen geen nieuwe berichten worden geplaatst.",
- "camera_type.photo.option": "Foto maken",
- "camera_type.video.option": "Video opnemen",
- "center_panel.archived.closeChannel": "Kanaal sluiten",
+ "camera_type.photo.option": "Maak foto",
+ "camera_type.video.option": "Neem video op",
+ "center_panel.archived.closeChannel": "Sluit kanaal",
"channel_info.header": "Kop:",
"channel_loader.someone": "Iemand",
"channel_modal.descriptionHelp": "Beschrijf het doel van dit kanaal.",
@@ -124,10 +124,10 @@
"custom_status.suggestions.on_a_vacation": "Op vakantie",
"custom_status.suggestions.out_for_lunch": "Lunch",
"custom_status.suggestions.out_sick": "Ziek",
- "custom_status.suggestions.working_from_home": "Thuiswerk",
+ "custom_status.suggestions.working_from_home": "Thuiswerken",
"date_separator.today": "Vandaag",
"date_separator.yesterday": "Gisteren",
- "edit_post.editPost": "Bewerk het bericht...",
+ "edit_post.editPost": "Wijzig het bericht...",
"edit_post.save": "Opslaan",
"emoji_picker.activities": "Activiteiten",
"emoji_picker.animals-nature": "Dieren & Natuur",
@@ -155,19 +155,19 @@
"friendly_date.yearsAgo": "{count} {count, plural, one {jaar} other {jaren}} geleden",
"friendly_date.yesterday": "Gisteren",
"gallery.footer.channel_name": "Gedeeld in {channelName}",
- "gallery.open_file": "Bestand openen",
+ "gallery.open_file": "Open bestand",
"get_post_link_modal.title": "Kopieer link",
- "global_threads.allThreads": "Al je draadjes",
- "global_threads.emptyThreads.message": "Alle draadjes waarin je bent genoemd of waaraan jehebt deelgenomen, worden hier getoond, samen met alle threads die je hebt gevolgd.",
+ "global_threads.allThreads": "Al je chatgesprekken",
+ "global_threads.emptyThreads.message": "Alle chatgesprekken waarin je bent genoemd of waaraan je hebt deelgenomen, worden hier getoond, samen met alle threads die je hebt gevolgd.",
"global_threads.emptyThreads.title": "Nog geen gevolgde draadjes",
- "global_threads.emptyUnreads.message": "Het lijkt erop dat je weer helemaal mee bent.",
- "global_threads.emptyUnreads.title": "Geen ongelezen draadjes",
- "global_threads.markAllRead.cancel": "Annuleren",
- "global_threads.markAllRead.markRead": "Als gelezen markeren",
+ "global_threads.emptyUnreads.message": "Zo te zien ben je helemaal bij.",
+ "global_threads.emptyUnreads.title": "Geen ongelezen chatgesprekken",
+ "global_threads.markAllRead.cancel": "Annuleer",
+ "global_threads.markAllRead.markRead": "Markeer als gelezen",
"global_threads.markAllRead.message": "Dit zal alle ongelezen status verwijderen voor al je threads die hier getoond worden",
"global_threads.markAllRead.title": "Weet je zeker dat je alle onderwerpen als gelezen wilt markeren?",
"global_threads.options.mark_as_read": "Markeer als gelezen",
- "global_threads.options.open_in_channel": "Openen in kanaal",
+ "global_threads.options.open_in_channel": "Open in kanaal",
"global_threads.unreads": "Ongelezen",
"last_users_message.added_to_channel.type": "is **aan het kanaal toegevoegd** door {actor}.",
"last_users_message.added_to_team.type": "is **aan het team toegevoegd** door {actor}.",
@@ -179,7 +179,7 @@
"last_users_message.others": "{numOthers} anderen ",
"last_users_message.removed_from_channel.type": "werd **verwijderd uit het kanaal**.",
"last_users_message.removed_from_team.type": "werd **verwijderd uit het team**.",
- "login_mfa.tokenReq": "Geef een MFA token op",
+ "login_mfa.tokenReq": "Voer een MFA-token in",
"login.email": "E-mail",
"login.ldapUsername": "AD/LDAP Gebruikersnaam",
"login.or": "of",
@@ -188,30 +188,30 @@
"mobile.about.appVersion": "Appversie: {version} (Build {number})",
"mobile.account.settings.save": "Opslaan",
"mobile.action_menu.select": "Selecteer een optie",
- "mobile.android.back_handler_exit": "Klik nogmaals op Terug om te sluiten",
+ "mobile.android.back_handler_exit": "Tik nogmaals op Terug om te sluiten",
"mobile.android.photos_permission_denied_title": "{applicationName} wil toegang tot jouw foto's",
"mobile.camera_photo_permission_denied_title": "{applicationName} wil toegang tot jouw camera",
"mobile.channel_info.alertNo": "Nee",
"mobile.channel_info.alertYes": "Ja",
"mobile.commands.error_title": "Fout bij uitvoeren van opdracht",
"mobile.components.select_server_view.connect": "Verbinden",
- "mobile.components.select_server_view.enterServerUrl": "Server-URL opgeven",
+ "mobile.components.select_server_view.enterServerUrl": "Voer server-url in",
"mobile.components.select_server_view.proceed": "Verdergaan",
"mobile.create_channel": "Aanmaken",
"mobile.custom_status.choose_emoji": "Kies een emoticon",
"mobile.custom_status.clear_after": "Wis na",
"mobile.custom_status.modal_confirm": "Klaar",
"mobile.display_settings.theme": "Thema",
- "mobile.document_preview.failed_description": "Er is een fout opgetreden tijdens het openen van het document. Zorg ervoor dat je een {fileType} - viewer geïnstalleerd en probeer het opnieuw. \n",
- "mobile.document_preview.failed_title": "Openen van document is mislukt",
- "mobile.downloader.disabled_description": "File downloads zijn uitgeschakeld op deze server. Neem contact op met uw Systeembeheerder voor meer informatie.\n",
+ "mobile.document_preview.failed_description": "Er is een fout opgetreden tijdens het openen van het document. Zorg ervoor dat je een {fileType}-viewer geïnstalleerd en probeer het opnieuw.\n",
+ "mobile.document_preview.failed_title": "Openen document mislukt",
+ "mobile.downloader.disabled_description": "File downloads zijn uitgeschakeld op deze server. Neem contact op met je systeembeheerder voor meer info.\n",
"mobile.downloader.disabled_title": "Downloaden uitgeschakeld",
- "mobile.downloader.failed_description": "Er is een fout opgetreden tijdens het downloaden van het bestand. Controleer uw internetverbinding en probeer het opnieuw.\n",
+ "mobile.downloader.failed_description": "Er is een fout opgetreden tijdens het downloaden van het bestand. Controleer je internetverbinding en probeer het nog eens.\n",
"mobile.downloader.failed_title": "Downloaden mislukt",
- "mobile.edit_channel": "Opslaan",
+ "mobile.edit_channel": "Bewaren",
"mobile.edit_post.title": "Bericht bewerken",
"mobile.error_handler.button": "Opnieuw starten",
- "mobile.error_handler.description": "\nTik op opnieuw starten om de app opnieuw te openen. Nadat deze opnieuw is opgestart, kunt je het probleem melden in het menu instellingen.\n",
+ "mobile.error_handler.description": "\nTik op opnieuw starten om de app opnieuw te openen. Nadat deze opnieuw is opgestart, kunt je het probleem melden in het menu Instellingen.\n",
"mobile.error_handler.title": "Onvoorziene fout opgetreden",
"mobile.file_upload.disabled2": "Bestanden opladen van op mobiele toestellen is uitgeschakeld.",
"mobile.file_upload.max_warning": "Uploads beperkt tot maximaal {count} bestanden.",
@@ -225,16 +225,16 @@
"mobile.managed.blocked_by": "Geblokkeerd door {vendor}",
"mobile.managed.exit": "Afsluiten",
"mobile.managed.jailbreak": "Jailbroken apparaten worden niet vertrouwd door {vendor}, sluit de app af.",
- "mobile.managed.not_secured.android": "Dit apparaat moet beveiligd zijn met een schermvergrendeling om Mattermost te gebruiken.",
- "mobile.managed.not_secured.ios": "Dit apparaat moet worden beveiligd met een toegangscode om Mattermost te gebruiken.\n\nGa naar Instellingen > Face ID & Wachtwoord.",
- "mobile.managed.not_secured.ios.touchId": "Dit apparaat moet worden beveiligd met een toegangscode om Mattermost te gebruiken.\n\nGa naar Instellingen > Touch ID & Wachtwoord.",
+ "mobile.managed.not_secured.android": "Dit apparaat moet eerst beveiligd worden met een schermvergrendeling, zodat je Mattermost kunt gebruiken.",
+ "mobile.managed.not_secured.ios": "Dit apparaat moet worden beveiligd met een toegangscode om Mattermost te gebruiken.\n\nGa naar Instellingen > Biometrie en wachtwoord.",
+ "mobile.managed.not_secured.ios.touchId": "Dit apparaat moet worden beveiligd met een toegangscode om Mattermost te gebruiken.\n\nGa naar Instellingen > Vingerafruk-id en wachtwoord.",
"mobile.managed.secured_by": "Beveiligd door {vendor}",
"mobile.managed.settings": "Ga naar instellingen",
- "mobile.markdown.code.copy_code": "Kopieer Code",
+ "mobile.markdown.code.copy_code": "Kopieer code",
"mobile.markdown.code.plusMoreLines": "+{count, number} meer {count, plural, one {line} other {lines}}",
"mobile.markdown.image.too_large": "Afbeelding overschrijdt de maximumgrootte van {maxWidth} op {maxHeight}:",
"mobile.markdown.link.copy_url": "Kopieer URL",
- "mobile.mention.copy_mention": "Kopieer Vermelding",
+ "mobile.mention.copy_mention": "Kopieer vermelding",
"mobile.message_length.message": "Je huidige bericht is te lang. Huidige aantal tekens: {count}/{max}",
"mobile.message_length.message_split_left": "Bericht overschrijdt het maximum aantal karakters",
"mobile.message_length.title": "Berichtlengte",
@@ -252,7 +252,7 @@
"mobile.post_info.reply": "Antwoord",
"mobile.post_info.unpin": "Losmaken van Kanaal",
"mobile.post_pre_header.pinned": "Vastgemaakt",
- "mobile.post_textbox.entire_channel_here.message": "Door @here te gebruiken ga je berichten sturen naar maximaal {totalMembers, number} {totalMembers, plural, one {persoon} other {mensen}}.. Weet je zeker dat je dit wilt doen?",
+ "mobile.post_textbox.entire_channel_here.message": "Door @here te gebruiken ga je berichten sturen naar maximaal {totalMembers, number} {totalMembers, plural, one {persoon} other {mensen}}. Weet je zeker dat je dit wilt doen?",
"mobile.post_textbox.entire_channel_here.message.with_timezones": "Bij gebruik van @all of @channel verstuur je meldingen naar {totalMembers, number} {totalMembers, plural, one {persoon} other {mensen}} in {timezones, number} {timezones, plural, one {tijdzone} other {tijdzones}}. Weet je zeker dat je dit wil doen?",
"mobile.post_textbox.entire_channel.cancel": "Annuleren",
"mobile.post_textbox.entire_channel.confirm": "Bevestigen",
@@ -264,12 +264,12 @@
"mobile.post_textbox.uploadFailedTitle": "Bijlagefout",
"mobile.post.cancel": "Annuleren",
"mobile.post.delete_question": "Weet je zeker dat je deze bericht wil wissen?",
- "mobile.post.delete_title": "Verwijder Bericht",
- "mobile.post.failed_delete": "Verwijder Bericht",
- "mobile.post.failed_retry": "Probeer Opnieuw",
+ "mobile.post.delete_title": "Verwijder bericht",
+ "mobile.post.failed_delete": "Verwijder bericht",
+ "mobile.post.failed_retry": "Probeer opnieuw",
"mobile.privacy_link": "Privacybeleid",
"mobile.push_notification_reply.button": "Verzenden",
- "mobile.push_notification_reply.placeholder": "Schrijf een antwoord...",
+ "mobile.push_notification_reply.placeholder": "Schrijf een reactie...",
"mobile.push_notification_reply.title": "Antwoord",
"mobile.rename_channel.display_name_maxLength": "Kanaalnaam moet kleiner zijn dan {maxLength, number} tekens",
"mobile.rename_channel.display_name_minLength": "Kanaalnaam moet {minLength, number} of meer tekens zijn",
@@ -282,8 +282,8 @@
"mobile.routes.custom_status": "Een aangepaste status instellen",
"mobile.routes.table": "Tabel",
"mobile.routes.user_profile": "Profiel",
- "mobile.search.jump": "Naar recente berichten gaan",
- "mobile.server_link.error.text": "De link is niet gevonden op deze server.",
+ "mobile.search.jump": "Ga naar recente berichten",
+ "mobile.server_link.error.text": "De link werd niet gevonden op deze server.",
"mobile.server_link.error.title": "Foute Link",
"mobile.server_link.unreachable_channel.error": "Deze link behoort tot een gewist kanaal of tot een kanaal waartoe je geen toegang hebt.",
"mobile.server_link.unreachable_team.error": "Deze link behoort tot een gewist team of tot een team waartoe je geen toegang hebt.",
@@ -461,8 +461,8 @@
"intro.townsquare": "Welkom op {name}. Iedereen wordt automatisch lid van dit kanaal als ze bij het team komen.",
"intro.public_channel": "Publiek kanaal",
"intro.private_channel": "Privé-kanaal",
- "intro.group_message": "Dit is het begin van jouw gesprek met deze groep. Berichten en bestanden die hier gedeeld worden, worden aan niemand buiten de groep getoond.",
- "intro.direct_message": "Dit is het begin van jouw gesprek met {teammate}. Berichten en bestanden die hier gedeeld worden, worden aan niemand anders getoond.",
+ "intro.group_message": "Dit is het begin van je gesprek met deze groep. Berichten en bestanden die hier gedeeld worden, worden aan niemand buiten de groep getoond.",
+ "intro.direct_message": "Dit is het begin van je gesprek met {teammate}. Berichten en bestanden die hier gedeeld worden, worden aan niemand anders getoond.",
"intro.created_by": "gemaakt door {creator} op {date}.",
"intro.channel_info": "Info",
"intro.add_people": "Mensen toevoegen",
@@ -590,7 +590,7 @@
"channel_modal.headerHelp": "Specificeer tekst die in de koptekst van het kanaal moet verschijnen naast de naam van het kanaal. Neem bijvoorbeeld veelgebruikte links op door linktekst [Linktitel](http://voorbeeld.nl) te typen.",
"channel_modal.headerEx": "Markdown gebruiken om koptekst op te maken",
"channel_list.find_channels": "Kanalen zoeken...",
- "mobile.post_pre_header.saved": "Bewaard",
+ "mobile.post_pre_header.saved": "Opgeslagen",
"mobile.post_pre_header.pinned_saved": "Vastgemaakt en bewaard",
"mobile.post_info.unsave": "Niet langer bewaren",
"mobile.post_info.save": "Bewaren",
@@ -727,7 +727,7 @@
"server.tutorial.swipe": "Veeg naar links op een server om meer acties te zien",
"server.remove.alert_title": "Weet je zeker dat je {displayName} wilt verwijderen?",
"server.remove.alert_description": "Dit zal de server verwijderen uit jouw lijst van servers. Alle bijbehorende gegevens worden verwijderd",
- "server.logout.alert_title": "Weet je zeker dat je je wilt afmelden bij {displayName}?",
+ "server.logout.alert_title": "Weet je zeker dat je wilt uitloggen bij {displayName}?",
"server.logout.alert_description": "Alle bijbehorende gegevens worden verwijderd",
"server_list.push_proxy_unknown": "Meldingen konden niet worden ontvangen van deze server vanwege de configuratie. Log uit en log opnieuw in om het opnieuw te proberen.",
"server_list.push_proxy_error": "Meldingen kunnen niet worden ontvangen van deze server vanwege de configuratie. Neem contact op met jouw systeembeheerder.",
@@ -842,7 +842,7 @@
"notification_settings.auto_responder.message": "Bericht",
"mobile.onboarding.sign_in_to_get_started": "Meld je aan om van start te gaan",
"mobile.onboarding.sign_in": "Aanmelden",
- "mobile.onboarding.next": "Volgende",
+ "mobile.onboarding.next": "Ga verder",
"mobile.integration_selector.loading_options": "Opties aan het laden...",
"mobile.integration_selector.loading_channels": "Kanalen aan het laden...",
"mobile.custom_list.no_results": "Geen resultaten",
@@ -905,7 +905,7 @@
"share_extension.max_resolution": "Afbeelding overschrijdt de maximum afmeting van 7680 x 4320 px",
"share_extension.file_limit.single": "Het bestand moet kleiner zijn dan {size}",
"share_extension.file_limit.multiple": "Elk bestand moet minder dan {size}",
- "share_extension.count_limit": "Je kan alleen {count, number} {count, plural, one {bestand} other {bestanden}} delen op deze server",
+ "share_extension.count_limit": "Je kan slechts {count, number} {count, plural, one {bestand} other {bestanden}} delen op deze server",
"share_extension.channel_label": "Kanaal",
"share_extension.channel_error": "Je bent geen lid van een team op de geselecteerde server. Selecteer een andere server of open Mattermost om lid te worden van een team.",
"settings.advanced.delete_message.confirmation": "\nDit zal alle bestanden verwijderen die via de app voor deze server zijn gedownload. Gelieve te bevestigen om verder te gaan.\n",
diff --git a/assets/base/i18n/sv.json b/assets/base/i18n/sv.json
index 0f5135cad0..59fa977bbc 100644
--- a/assets/base/i18n/sv.json
+++ b/assets/base/i18n/sv.json
@@ -936,5 +936,8 @@
"user_status.away": "Tillfälligt borta",
"mobile.camera_type.title": "Alternativ för kameran",
"join_team.error.title": "Fel vid anslutning till teamet",
- "join_team.error.message": "Det har uppstått ett fel när du skulle anslutas till teamet"
+ "join_team.error.message": "Det har uppstått ett fel när du skulle anslutas till teamet",
+ "skintone_selector.tooltip.title": "Välj standard-hudton",
+ "skintone_selector.tooltip.description": "Du kan nu välja vilken hudton du vill använda för dina emojis.",
+ "default_skin_tone": "Standard hudton"
}
diff --git a/assets/base/i18n/tr.json b/assets/base/i18n/tr.json
index c03a78b140..bed103a98a 100644
--- a/assets/base/i18n/tr.json
+++ b/assets/base/i18n/tr.json
@@ -876,5 +876,68 @@
"join_team.error.title": "Bir takıma katılınırken sorun çıktı",
"join_team.error.message": "Takıma katılınırken bir sorun çıktı",
"join_team.error.group_error": "Bu takıma katılmak için ilişkilendirilmiş bir grubun üyesi olmalısınız.",
- "connection_banner.connecting": "Bağlantı kuruluyor..."
+ "connection_banner.connecting": "Bağlantı kuruluyor...",
+ "share_extension.file_limit.single": "Dosya {size} boyutundan küçük olmalıdır",
+ "share_extension.file_limit.multiple": "Her bir dosya {size} boyutundan küçük olmalıdır",
+ "share_extension.count_limit": "Bu sunucuda yalnızca {count, number} {count, plural, one {dosya} other {dosya}} paylaşabilirsiniz",
+ "share_extension.channel_label": "Kanal",
+ "share_extension.channel_error": "Seçilmiş sunucuda bir takımın üyesi değilsiniz. Başka bir sunucu seçin ya da bir takıma katılmak için Mattermost uygulamasını açın.",
+ "settings.advanced.delete_message.confirmation": "\nBu işlem, bu sunucuya uygulama ile indirilmiş tüm dosyaları siler. Lütfen ilerlemek istiyorsanız onaylayın.\n",
+ "settings.advanced.delete_data": "Yerel dosyaları sil",
+ "settings.advanced.delete": "Sil",
+ "settings.advanced.cancel": "İptal",
+ "rate.title": "Mattermost hoşunuza gidiyor mu?",
+ "rate.subtitle": "Ne düşündüğünüzü bize iletin.",
+ "rate.error.title": "Hata",
+ "rate.error.text": "Gözden geçirme penceresi açılırken bir sorun çıktı.",
+ "rate.dont_ask_again": "Bir daha sorma",
+ "rate.button.yes": "Bayıldım!",
+ "rate.button.needs_work": "Çalışma gerektiriyor",
+ "post_priority.picker.title": "İleti önceliği",
+ "post_priority.picker.label.urgent": "Acil",
+ "post_priority.picker.label.standard": "Standart",
+ "post_priority.picker.label.important": "Önemli",
+ "post_priority.picker.beta": "BETA",
+ "onboaring.welcome_description": "Mattermost, geliştiriciler arasında işbirliği sağlamayı amaçlayan açık kaynaklı bir platformdur. Güvenlidir, esnektir ve araçlarınızla bütünleşik çalışır.",
+ "onboarding.welcome": "Hoş geldiniz",
+ "onboarding.realtime_collaboration_description": "Kalıcı kanallar, doğrudan iletişim ve dosya paylaşımı sorunsuz bir şekilde çalışır. Böylece nerede olursanız olun bağlantıda kalabilirsiniz.",
+ "onboarding.realtime_collaboration": "Gerçek zamanlı işbirliği yapın",
+ "onboarding.integrations_description": "Ortak geliştirme süreçlerine uygun, sıkı bir şekilde bütünleştirilmiş ürün çözümleriyle sohbetin ötesine geçin.",
+ "onboarding.calls_description": "Yazmak yeterince hızlı olmadığında, tek bir dokunuşla kanal tabanlı sohbetten güvenli sesli aramaya geçin.",
+ "onboarding.calls": "güvenli sesli çağrılar hemen başlatılsın",
+ "default_skin_tone": "Varsayılan cilt tonu",
+ "terms_of_service.acceptButton": "Kabul et",
+ "terms_of_service.terms_declined.text": "Bu sunucuya erişmek için hizmet koşullarını kabul etmelisiniz. Ayrıntılı bilgi almak için sistem yöneticinizle görüşün. Şimdi oturumunuz kapatılacak. Hizmet koşullarını kabul etmek için yeniden oturum açın.",
+ "video.download_description": "Oynatmak için bu görüntüyü indirmelisiniz.",
+ "user.edit_profile.profile_photo.change_photo": "Profil fotoğrafını değiştir",
+ "user_status.title": "Durum",
+ "user_status.online": "Çevrimiçi",
+ "user_status.offline": "Çevrimdışı",
+ "user_status.dnd": "Rahatsız etmeyin",
+ "user_status.away": "Uzakta",
+ "thread.loadingReplies": "Yanıtlar yükleniyor...",
+ "terms_of_service.title": "Hizmet koşulları",
+ "terms_of_service.terms_declined.title": "Hizmet koşullarını kabul etmelisiniz",
+ "terms_of_service.terms_declined.ok": "Tamam",
+ "terms_of_service.error.title": "Hizmet koşulları alınamadı.",
+ "terms_of_service.error.retry": "Yeniden dene",
+ "terms_of_service.error.logout": "Oturumu kapat",
+ "terms_of_service.error.description": "Hizmet koşulları sunucudan alınamadı.",
+ "terms_of_service.decline": "Reddet",
+ "terms_of_service.api_error": "İstek yerine getirilemedi. Sorun sürerse sistem yöneticiniz ile görüşün.",
+ "terms_of_service.alert_retry": "Yeniden dene",
+ "terms_of_service.alert_cancel": "İptal",
+ "skintone_selector.tooltip.title": "Varsayılan cilt tonunuzu seçin",
+ "skintone_selector.tooltip.description": "Artık emojilerinizde kullanmak istediğiniz cilt tonunu seçebilirsiniz.",
+ "share_feedback.title": "Görüşlerinizi paylaşır mısınız?",
+ "share_feedback.subtitle": "Deneyiminizi nasıl daha iyi yapabileceğimizi duymak isteriz.",
+ "share_feedback.button.yes": "Evet",
+ "share_feedback.button.no": "Hayır, teşekkürler",
+ "share_extension.upload_disabled": "Seçilmiş sunucu için dosya yükleme özelliği devre dışı bırakılmış",
+ "share_extension.share_screen.title": "Mattermost ile paylaş",
+ "share_extension.servers_screen.title": "Sunucu seçin",
+ "share_extension.server_label": "Sunucu",
+ "share_extension.multiple_label": "{count, number} ek dosya",
+ "share_extension.message": "Bir ileti yazın (isteğe bağlı)",
+ "share_extension.max_resolution": "Görsel olabilecek en büyük 7680 x 4320 piksel boyutundan büyük"
}
diff --git a/assets/base/i18n/uk.json b/assets/base/i18n/uk.json
index 32f4fe7b88..040a971181 100644
--- a/assets/base/i18n/uk.json
+++ b/assets/base/i18n/uk.json
@@ -251,5 +251,22 @@
"user.settings.general.lastName": "Прізвище",
"user.settings.general.nickname": "Псевдонім",
"user.settings.general.position": "Посада",
- "user.settings.general.username": "Ім'я користувача"
+ "user.settings.general.username": "Ім'я користувача",
+ "alert.push_proxy_error.title": "Сповіщення не можуть бути отримані з цього сервера",
+ "alert.push_proxy_error.description": "Через конфігурацію цього сервера сповіщення не можуть надходити в мобільний додаток. Щоб отримати додаткову інформацію, зверніться до свого системного адміністратора.",
+ "alert.channel_deleted.title": "Канал заархівований",
+ "alert.channel_deleted.description": "Канал {displayName} був заархівований.",
+ "account.your_profile": "Ваш профіль",
+ "account.settings": "Налаштування",
+ "account.logout_from": "Вийти з {serverName}",
+ "account.logout": "Вийти",
+ "announcment_banner.okay": "Добре",
+ "announcment_banner.dismiss": "Відхилити оголошення",
+ "alert.removed_from_team.title": "Видалено з команди",
+ "alert.removed_from_team.description": "Вас було видалино з команди {displayName}.",
+ "alert.removed_from_channel.title": "Видалено з каналу",
+ "alert.removed_from_channel.description": "Вас видалили з каналу {displayName}.",
+ "alert.push_proxy.button": "Добре",
+ "alert.push_proxy_unknown.title": "Сповіщення не може бути отримано з цього сервера",
+ "alert.push_proxy_unknown.description": "З невідомих причин цей сервер не зміг отримати push-нотифікацію. Це буде зроблено знову під час наступного підключення."
}
diff --git a/detox/e2e/support/ui/screen/index.ts b/detox/e2e/support/ui/screen/index.ts
index 891e6d90b6..99497dda6c 100644
--- a/detox/e2e/support/ui/screen/index.ts
+++ b/detox/e2e/support/ui/screen/index.ts
@@ -23,6 +23,7 @@ import EmojiPickerScreen from './emoji_picker';
import FindChannelsScreen from './find_channels';
import GlobalThreadsScreen from './global_threads';
import HomeScreen from './home';
+import Invite from './invite';
import LoginScreen from './login';
import MentionNotificationSettingsScreen from './mention_notification_settings';
import NotificationSettingsScreen from './notification_settings';
@@ -69,6 +70,7 @@ export {
FindChannelsScreen,
GlobalThreadsScreen,
HomeScreen,
+ Invite,
LoginScreen,
MentionNotificationSettingsScreen,
NotificationSettingsScreen,
diff --git a/detox/e2e/support/ui/screen/invite.ts b/detox/e2e/support/ui/screen/invite.ts
new file mode 100644
index 0000000000..3962618fbf
--- /dev/null
+++ b/detox/e2e/support/ui/screen/invite.ts
@@ -0,0 +1,127 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+import {ChannelListScreen} from '@support/ui/screen';
+import {timeouts, wait} from '@support/utils';
+import {expect} from 'detox';
+
+class InviteScreen {
+ testID = {
+ inviteScreen: 'invite.screen',
+ screenSummary: 'invite.screen.summary',
+ screenSelection: 'invite.screen.selection',
+ closeButton: 'invite.close.button',
+ sendButton: 'invite.send.button',
+ teamIcon: 'invite.team_icon',
+ teamDisplayName: 'invite.team_display_name',
+ serverDisplayName: 'invite.server_display_name',
+ shareLinkButton: 'invite.share_link.button',
+ searchBarTitle: 'invite.search_bar_title',
+ searchBarInput: 'invite.search_bar_input',
+ selectedItems: 'invite.selected_items',
+ selectedItemPrefix: 'invite.selected_item',
+ searchList: 'invite.search_list',
+ searchListItemPrefix: 'invite.search_list_item.',
+ searchListTextItemPrefix: 'invite.search_list_text_item',
+ searchListUserItemPrefix: 'invite.search_list_user_item',
+ searchListNoResultsPrefix: 'invite.search_list_no_results',
+ summaryReportPrefix: 'invite.summary_report',
+ summaryReportTextItemPrefix: 'invite.summary_report.text_item',
+ summaryReportUserItemPrefix: 'invite.summary_report.user_item',
+ };
+
+ inviteScreen = element(by.id(this.testID.inviteScreen));
+ screenSummary = element(by.id(this.testID.screenSummary));
+ screenSelection = element(by.id(this.testID.screenSelection));
+ closeButton = element(by.id(this.testID.closeButton));
+ sendButton = element(by.id(this.testID.sendButton));
+ teamIcon = element(by.id(this.testID.teamIcon));
+ teamDisplayName = element(by.id(this.testID.teamDisplayName));
+ serverDisplayName = element(by.id(this.testID.serverDisplayName));
+ shareLinkButton = element(by.id(this.testID.shareLinkButton));
+ searchBarTitle = element(by.id(this.testID.searchBarTitle));
+ searchBarInput = element(by.id(this.testID.searchBarInput));
+ selectedItems = element(by.id(this.testID.selectedItems));
+ selectedItemPrefix = element(by.id(this.testID.selectedItemPrefix));
+ searchList = element(by.id(this.testID.searchList));
+ searchListItemPrefix = element(by.id(this.testID.searchListItemPrefix));
+ searchListTextItemPrefix = element(by.id(this.testID.searchListTextItemPrefix));
+ searchListUserItemPrefix = element(by.id(this.testID.searchListUserItemPrefix));
+ searchListNoResultsPrefix = element(by.id(this.testID.searchListNoResultsPrefix));
+ summaryReportTextItemPrefix = element(by.id(this.testID.summaryReportTextItemPrefix));
+ summaryReportUserItemPrefix = element(by.id(this.testID.summaryReportUserItemPrefix));
+
+ getSearchListTextItem = (id: string) => {
+ return element(by.id(`${this.testID.searchListTextItemPrefix}.${id}`));
+ };
+
+ getSearchListTextItemText = (id: string) => {
+ return element(by.id(`${this.testID.searchListTextItemPrefix}.text.${id}`));
+ };
+
+ getSearchListUserItem = (id: string) => {
+ return element(by.id(`${this.testID.searchListUserItemPrefix}.${id}`));
+ };
+
+ getSearchListUserItemText = (id: string) => {
+ return element(by.id(`${this.testID.searchListUserItemPrefix}.${id}.username`));
+ };
+
+ getSearchListNoResults = (id: string) => {
+ return element(by.id(`${this.testID.searchListNoResultsPrefix}.${id}`));
+ };
+
+ getSearchListNoResultsText = (id: string) => {
+ return element(by.id(`${this.testID.searchListNoResultsPrefix}.text.${id}`));
+ };
+
+ getSelectedItem = (id: string) => {
+ return element(by.id(`${this.testID.selectedItemPrefix}.${id}`));
+ };
+
+ getSummaryReportSent = () => {
+ return element(by.id(`${this.testID.summaryReportPrefix}.sent`));
+ };
+
+ getSummaryReportNotSent = () => {
+ return element(by.id(`${this.testID.summaryReportPrefix}.not_sent`));
+ };
+
+ getSummaryReportTextItem = (id: string) => {
+ return element(by.id(`${this.testID.summaryReportTextItemPrefix}.${id}`));
+ };
+
+ getSummaryReportTextItemText = (id: string) => {
+ return element(by.id(`${this.testID.summaryReportTextItemPrefix}.text.${id}`));
+ };
+
+ getSummaryReportUserItem = (id: string) => {
+ return element(by.id(`${this.testID.summaryReportUserItemPrefix}.${id}`));
+ };
+
+ getSummaryReportUserItemText = (id: string) => {
+ return element(by.id(`${this.testID.summaryReportUserItemPrefix}.${id}.username`));
+ };
+
+ toBeVisible = async () => {
+ await waitFor(this.inviteScreen).toExist().withTimeout(timeouts.TEN_SEC);
+
+ return this.inviteScreen;
+ };
+
+ open = async () => {
+ await ChannelListScreen.headerPlusButton.tap();
+ await wait(timeouts.ONE_SEC);
+ await ChannelListScreen.invitePeopleToTeamItem.tap();
+
+ return this.toBeVisible();
+ };
+
+ close = async () => {
+ await this.closeButton.tap();
+ await expect(this.inviteScreen).not.toBeVisible();
+ };
+}
+
+const inviteScreen = new InviteScreen();
+export default inviteScreen;
diff --git a/detox/e2e/support/ui/screen/server.ts b/detox/e2e/support/ui/screen/server.ts
index 61f5966fbb..6bac98f927 100644
--- a/detox/e2e/support/ui/screen/server.ts
+++ b/detox/e2e/support/ui/screen/server.ts
@@ -45,6 +45,7 @@ class ServerScreen {
connectToServer = async (serverUrl: string, serverDisplayName: string) => {
await this.toBeVisible();
await this.serverUrlInput.replaceText(serverUrl);
+ await this.serverUrlInput.tapReturnKey();
await this.serverDisplayNameInput.replaceText(serverDisplayName);
await this.connectButton.tap();
};
diff --git a/detox/e2e/test/teams/invite_people.e2e.ts b/detox/e2e/test/teams/invite_people.e2e.ts
index f325701d7e..fc0faeaeaf 100644
--- a/detox/e2e/test/teams/invite_people.e2e.ts
+++ b/detox/e2e/test/teams/invite_people.e2e.ts
@@ -7,32 +7,34 @@
// - Use element testID when selecting an element. Create one if none.
// *******************************************************************
-import {Setup} from '@support/server_api';
+import {Setup, User} from '@support/server_api';
import {
serverOneUrl,
siteOneUrl,
} from '@support/test_config';
import {
ChannelListScreen,
+ Invite,
HomeScreen,
LoginScreen,
ServerScreen,
} from '@support/ui/screen';
-import {isIos, timeouts, wait} from '@support/utils';
+import {isIos, timeouts} from '@support/utils';
import {expect} from 'detox';
function systemDialog(label: string) {
- if (device.getPlatform() === 'ios') {
+ if (isIos()) {
return element(by.label(label)).atIndex(0);
}
return element(by.text(label));
}
-describe('Teams - Invite people', () => {
+describe('Teams - Invite', () => {
const serverOneDisplayName = 'Server 1';
let testTeam: any;
let testUser: any;
+ let testUser1: any;
beforeAll(async () => {
const {team, user} = await Setup.apiInit(siteOneUrl);
@@ -40,38 +42,208 @@ describe('Teams - Invite people', () => {
testTeam = team;
testUser = user;
+ const {user: user1} = await User.apiCreateUser(siteOneUrl, {prefix: 'i'});
+
+ testUser1 = user1;
+
// # Log in to server
await ServerScreen.connectToServer(serverOneUrl, serverOneDisplayName);
await LoginScreen.login(testUser);
});
beforeEach(async () => {
+ await device.reloadReactNative();
+
// * Verify on channel list screen
await ChannelListScreen.toBeVisible();
+
+ // # Open invite screen
+ await Invite.open();
});
afterAll(async () => {
+ // # Close invite screen
+ await Invite.close();
+
// # Log out
await HomeScreen.logout();
});
+ it('MM-T5360 - should open the invite screen', async () => {
+ // * Verify invite screen Header buttons
+ await expect(Invite.closeButton).toBeVisible();
+ await expect(Invite.sendButton).toBeVisible();
+
+ // * Verify Team data
+ await expect(Invite.teamDisplayName).toHaveText(testTeam.display_name);
+ await expect(Invite.teamIcon).toBeVisible();
+
+ // * Verify default Selection
+ await expect(Invite.screenSelection).toBeVisible();
+
+ // * Verify Server data
+ await expect(Invite.serverDisplayName).toHaveText(serverOneDisplayName);
+
+ // * Verify Share Link
+ await expect(Invite.shareLinkButton).toBeVisible();
+
+ // * Verify Search bar
+ await expect(Invite.searchBarTitle).toBeVisible();
+ await expect(Invite.searchBarInput).toBeVisible();
+ });
+
it('MM-T5221 - should be able to share a URL invite to the team', async () => {
- // # Open plus menu
- await ChannelListScreen.headerPlusButton.tap();
-
- // * Verify invite people to team item is available
- await wait(timeouts.ONE_SEC);
- await expect(ChannelListScreen.invitePeopleToTeamItem).toExist();
-
- // # Tap on invite people to team item
- await ChannelListScreen.invitePeopleToTeamItem.tap();
+ // # Tap on Share link
+ await Invite.shareLinkButton.tap();
if (isIos()) {
+ const dialog = systemDialog(`Join the ${testTeam.display_name} team`);
+
// * Verify share dialog is open
- await expect(systemDialog(`Join the ${testTeam.display_name} team`)).toExist();
+ await expect(dialog).toExist();
// # Close share dialog
- await device.reloadReactNative();
+ await dialog.swipe('down');
}
});
+
+ it('MM-T5361 - should show no results item in search list', async () => {
+ const noUser = 'qwertyuiop';
+
+ // # Search for a non existent user
+ await Invite.searchBarInput.replaceText(noUser);
+
+ // * Validate no results item in search list
+ await expect(Invite.getSearchListNoResults(noUser)).toBeVisible();
+ await expect(Invite.getSearchListNoResultsText(noUser)).toHaveText(noUser);
+ });
+
+ it('MM-T5362 - should be able to send email invite', async () => {
+ const noUserEmailFormat = 'qwerty@ui.op';
+
+ // # Search for a non existent user with email format
+ await Invite.searchBarInput.replaceText(noUserEmailFormat);
+
+ // * Validate email invite item in search list
+ await expect(Invite.getSearchListTextItem(noUserEmailFormat)).toBeVisible();
+ await expect(Invite.getSearchListTextItemText(noUserEmailFormat)).toHaveText(noUserEmailFormat);
+
+ // # Select email invite item
+ await Invite.getSearchListTextItem(noUserEmailFormat).tap();
+ await expect(Invite.getSearchListTextItem(noUserEmailFormat)).not.toBeVisible();
+
+ // * Validate email invite is added to selected items
+ await expect(Invite.getSelectedItem(noUserEmailFormat)).toBeVisible();
+
+ // # Send invitation
+ await Invite.sendButton.tap();
+
+ // * Validate summary report sent
+ await expect(Invite.screenSummary).toBeVisible();
+ await expect(Invite.getSummaryReportSent()).toBeVisible();
+ await expect(Invite.getSummaryReportNotSent()).not.toExist();
+ await expect(Invite.getSummaryReportTextItem(noUserEmailFormat)).toBeVisible();
+ await expect(Invite.getSummaryReportTextItemText(noUserEmailFormat)).toHaveText(noUserEmailFormat);
+ });
+
+ it('MM-T5363 - should be able to send user invite', async () => {
+ const username = ` @${testUser1.username}`;
+
+ // # Search for a existent user
+ await Invite.searchBarInput.replaceText(testUser1.username);
+
+ // * Validate user item in search list
+ await expect(Invite.getSearchListUserItem(testUser1.id)).toBeVisible();
+ await expect(Invite.getSearchListUserItemText(testUser1.id)).toHaveText(username);
+
+ // # Select user item
+ await Invite.getSearchListUserItem(testUser1.id).tap();
+ await expect(Invite.getSearchListUserItem(testUser1.id)).not.toBeVisible();
+
+ // * Validate user is added to selected items
+ await expect(Invite.getSelectedItem(testUser1.id)).toBeVisible();
+
+ // # Send invitation
+ await Invite.sendButton.tap();
+
+ // * Validate summary report sent
+ await expect(Invite.screenSummary).toBeVisible();
+ await expect(Invite.getSummaryReportSent()).toBeVisible();
+ await expect(Invite.getSummaryReportNotSent()).not.toExist();
+ await expect(Invite.getSummaryReportUserItem(testUser1.id)).toBeVisible();
+ await expect(Invite.getSummaryReportUserItemText(testUser1.id)).toHaveText(username);
+ });
+
+ it('MM-T5364 - should not be able to send user invite to user already in team', async () => {
+ const username = ` @${testUser1.username}`;
+
+ // # Search for a existent user already in team
+ await Invite.searchBarInput.replaceText(testUser1.username);
+
+ // * Validate user item in search list
+ await expect(Invite.getSearchListUserItem(testUser1.id)).toBeVisible();
+
+ // # Select user item
+ await Invite.getSearchListUserItem(testUser1.id).tap();
+
+ // * Validate user is added to selected items
+ await expect(Invite.getSelectedItem(testUser1.id)).toBeVisible();
+
+ // # Send invitation
+ await Invite.sendButton.tap();
+
+ // * Validate summary report not sent
+ await expect(Invite.screenSummary).toBeVisible();
+ await expect(Invite.getSummaryReportSent()).not.toExist();
+ await expect(Invite.getSummaryReportNotSent()).toBeVisible();
+ await expect(Invite.getSummaryReportUserItem(testUser1.id)).toBeVisible();
+ await expect(Invite.getSummaryReportUserItemText(testUser1.id)).toHaveText(username);
+ });
+
+ it('MM-T5365 - should handle both sent and not sent invites', async () => {
+ const {user: testUser2} = await User.apiCreateUser(siteOneUrl, {prefix: 'i'});
+
+ const username1 = ` @${testUser1.username}`;
+ const username2 = ` @${testUser2.username}`;
+
+ // # Search for a existent user
+ await Invite.searchBarInput.replaceText(testUser2.username);
+
+ // * Validate user item in search list
+ await expect(Invite.getSearchListUserItem(testUser2.id)).toBeVisible();
+
+ // # Select user item
+ await Invite.getSearchListUserItem(testUser2.id).tap();
+
+ // * Validate user is added to selected items
+ await expect(Invite.getSelectedItem(testUser2.id)).toBeVisible();
+
+ // # Search for a existent user already in team
+ await Invite.searchBarInput.replaceText(testUser1.username);
+
+ // # Wait for user item in search list
+ await waitFor(Invite.getSearchListUserItem(testUser1.id)).toExist().withTimeout(timeouts.TWO_SEC);
+
+ // # Select user item
+ await Invite.getSearchListUserItem(testUser1.id).tap();
+
+ // * Validate user is added to selected items
+ await expect(Invite.getSelectedItem(testUser1.id)).toBeVisible();
+
+ // # Send invitation
+ await Invite.sendButton.tap();
+
+ // * Validate summary
+ await expect(Invite.screenSummary).toBeVisible();
+
+ // * Validate summary report not sent
+ await expect(Invite.getSummaryReportNotSent()).toBeVisible();
+ await expect(Invite.getSummaryReportUserItem(testUser1.id)).toBeVisible();
+ await expect(Invite.getSummaryReportUserItemText(testUser1.id)).toHaveText(username1);
+
+ // * Validate summary report sent
+ await expect(Invite.getSummaryReportSent()).toBeVisible();
+ await expect(Invite.getSummaryReportUserItem(testUser2.id)).toBeVisible();
+ await expect(Invite.getSummaryReportUserItemText(testUser2.id)).toHaveText(username2);
+ });
});
diff --git a/detox/package-lock.json b/detox/package-lock.json
index e61e8d934d..76fb4b4799 100644
--- a/detox/package-lock.json
+++ b/detox/package-lock.json
@@ -11,17 +11,17 @@
"@babel/plugin-transform-runtime": "7.19.6",
"@babel/preset-env": "7.20.2",
"@jest/test-sequencer": "29.3.1",
- "@types/jest": "29.2.5",
+ "@types/jest": "29.2.6",
"@types/tough-cookie": "4.0.2",
"@types/uuid": "9.0.0",
- "aws-sdk": "2.1286.0",
- "axios": "1.2.2",
+ "aws-sdk": "2.1297.0",
+ "axios": "1.2.3",
"axios-cookiejar-support": "4.0.6",
"babel-jest": "29.3.1",
- "babel-plugin-module-resolver": "4.1.0",
+ "babel-plugin-module-resolver": "5.0.0",
"client-oauth2": "4.3.3",
"deepmerge": "4.2.2",
- "detox": "20.1.1",
+ "detox": "20.1.2",
"form-data": "4.0.0",
"jest": "29.3.1",
"jest-circus": "29.3.1",
@@ -35,7 +35,7 @@
"sanitize-filename": "1.6.3",
"shelljs": "0.8.5",
"tough-cookie": "4.1.2",
- "ts-jest": "29.0.3",
+ "ts-jest": "29.0.5",
"tslib": "2.4.1",
"typescript": "4.9.4",
"uuid": "9.0.0",
@@ -2612,9 +2612,9 @@
}
},
"node_modules/@types/jest": {
- "version": "29.2.5",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.5.tgz",
- "integrity": "sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw==",
+ "version": "29.2.6",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.6.tgz",
+ "integrity": "sha512-XEUC/Tgw3uMh6Ho8GkUtQ2lPhY5Fmgyp3TdlkTJs1W9VgNxs+Ow/x3Elh8lHQKqCbZL0AubQuqWjHVT033Hhrw==",
"dev": true,
"dependencies": {
"expect": "^29.0.0",
@@ -2792,9 +2792,9 @@
}
},
"node_modules/aws-sdk": {
- "version": "2.1286.0",
- "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1286.0.tgz",
- "integrity": "sha512-CvkCD1+NSk2MPOutD2hEPhXDET/79w/gd9a359QWb9Ja0Fd4vVFXPkhlm1DTGzuwqFKGinpCMxDP4md7QPsVvw==",
+ "version": "2.1297.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1297.0.tgz",
+ "integrity": "sha512-hZbG8tfluU2ijCCBQnQzCiPbArFtaWqAUFAWAGZ0+Df7OzTm7ya9fLYV3j3L6p2PacAyAuxXaeMbgMHlHi/D3w==",
"dev": true,
"dependencies": {
"buffer": "4.9.2",
@@ -2841,9 +2841,9 @@
}
},
"node_modules/axios": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.2.tgz",
- "integrity": "sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.3.tgz",
+ "integrity": "sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.0",
@@ -2993,19 +2993,59 @@
}
},
"node_modules/babel-plugin-module-resolver": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz",
- "integrity": "sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.0.tgz",
+ "integrity": "sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==",
"dev": true,
"dependencies": {
- "find-babel-config": "^1.2.0",
- "glob": "^7.1.6",
+ "find-babel-config": "^2.0.0",
+ "glob": "^8.0.3",
"pkg-up": "^3.1.0",
- "reselect": "^4.0.0",
- "resolve": "^1.13.1"
+ "reselect": "^4.1.7",
+ "resolve": "^1.22.1"
},
"engines": {
- "node": ">= 8.0.0"
+ "node": ">= 16"
+ }
+ },
+ "node_modules/babel-plugin-module-resolver/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/babel-plugin-module-resolver/node_modules/glob": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
+ "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/babel-plugin-module-resolver/node_modules/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
}
},
"node_modules/babel-plugin-polyfill-corejs2": {
@@ -3651,9 +3691,9 @@
}
},
"node_modules/detox": {
- "version": "20.1.1",
- "resolved": "https://registry.npmjs.org/detox/-/detox-20.1.1.tgz",
- "integrity": "sha512-0ieeWAyo2f3YKeFwm7KCz4lBkCJIydyqzCQVN1sw/ZU9x9Qc8kz+itKAEiH4DHUlLkb4YLzfEbAXfO09wvrQ3w==",
+ "version": "20.1.2",
+ "resolved": "https://registry.npmjs.org/detox/-/detox-20.1.2.tgz",
+ "integrity": "sha512-SGxLyuzE8TjIc4Lg49YKD0buj3JLaX+KtprSeFvn7ZTdWd4fH6o5Szd4KM21uBSpnYEEgXTgiCypPQst6dt5mQ==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -3669,7 +3709,7 @@
"glob": "^8.0.3",
"ini": "^1.3.4",
"json-cycle": "^1.3.0",
- "lodash": "^4.17.5",
+ "lodash": "^4.17.11",
"multi-sort-stream": "^1.0.3",
"multipipe": "^4.0.0",
"node-ipc": "^9.2.1",
@@ -4163,25 +4203,25 @@
}
},
"node_modules/find-babel-config": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz",
- "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.0.0.tgz",
+ "integrity": "sha512-dOKT7jvF3hGzlW60Gc3ONox/0rRZ/tz7WCil0bqA1In/3I8f1BctpXahRnEKDySZqci7u+dqq93sZST9fOJpFw==",
"dev": true,
"dependencies": {
- "json5": "^0.5.1",
- "path-exists": "^3.0.0"
+ "json5": "^2.1.1",
+ "path-exists": "^4.0.0"
},
"engines": {
- "node": ">=4.0.0"
+ "node": ">=16.0.0"
}
},
- "node_modules/find-babel-config/node_modules/json5": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
- "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==",
+ "node_modules/find-babel-config/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
- "bin": {
- "json5": "lib/cli.js"
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/find-up": {
@@ -7445,9 +7485,9 @@
"dev": true
},
"node_modules/json5": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
- "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true,
"bin": {
"json5": "lib/cli.js"
@@ -8525,9 +8565,9 @@
"dev": true
},
"node_modules/reselect": {
- "version": "4.1.6",
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz",
- "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==",
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
+ "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==",
"dev": true
},
"node_modules/resolve": {
@@ -9211,15 +9251,15 @@
"dev": true
},
"node_modules/ts-jest": {
- "version": "29.0.3",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
- "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
+ "version": "29.0.5",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz",
+ "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==",
"dev": true,
"dependencies": {
"bs-logger": "0.x",
"fast-json-stable-stringify": "2.x",
"jest-util": "^29.0.0",
- "json5": "^2.2.1",
+ "json5": "^2.2.3",
"lodash.memoize": "4.x",
"make-error": "1.x",
"semver": "7.x",
@@ -11674,9 +11714,9 @@
}
},
"@types/jest": {
- "version": "29.2.5",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.5.tgz",
- "integrity": "sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw==",
+ "version": "29.2.6",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.6.tgz",
+ "integrity": "sha512-XEUC/Tgw3uMh6Ho8GkUtQ2lPhY5Fmgyp3TdlkTJs1W9VgNxs+Ow/x3Elh8lHQKqCbZL0AubQuqWjHVT033Hhrw==",
"dev": true,
"requires": {
"expect": "^29.0.0",
@@ -11823,9 +11863,9 @@
"dev": true
},
"aws-sdk": {
- "version": "2.1286.0",
- "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1286.0.tgz",
- "integrity": "sha512-CvkCD1+NSk2MPOutD2hEPhXDET/79w/gd9a359QWb9Ja0Fd4vVFXPkhlm1DTGzuwqFKGinpCMxDP4md7QPsVvw==",
+ "version": "2.1297.0",
+ "resolved": "https://registry.npmjs.org/aws-sdk/-/aws-sdk-2.1297.0.tgz",
+ "integrity": "sha512-hZbG8tfluU2ijCCBQnQzCiPbArFtaWqAUFAWAGZ0+Df7OzTm7ya9fLYV3j3L6p2PacAyAuxXaeMbgMHlHi/D3w==",
"dev": true,
"requires": {
"buffer": "4.9.2",
@@ -11865,9 +11905,9 @@
}
},
"axios": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.2.tgz",
- "integrity": "sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.3.tgz",
+ "integrity": "sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==",
"dev": true,
"requires": {
"follow-redirects": "^1.15.0",
@@ -11976,16 +12016,49 @@
}
},
"babel-plugin-module-resolver": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz",
- "integrity": "sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.0.tgz",
+ "integrity": "sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==",
"dev": true,
"requires": {
- "find-babel-config": "^1.2.0",
- "glob": "^7.1.6",
+ "find-babel-config": "^2.0.0",
+ "glob": "^8.0.3",
"pkg-up": "^3.1.0",
- "reselect": "^4.0.0",
- "resolve": "^1.13.1"
+ "reselect": "^4.1.7",
+ "resolve": "^1.22.1"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
+ "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ }
+ },
+ "minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^2.0.1"
+ }
+ }
}
},
"babel-plugin-polyfill-corejs2": {
@@ -12459,9 +12532,9 @@
"dev": true
},
"detox": {
- "version": "20.1.1",
- "resolved": "https://registry.npmjs.org/detox/-/detox-20.1.1.tgz",
- "integrity": "sha512-0ieeWAyo2f3YKeFwm7KCz4lBkCJIydyqzCQVN1sw/ZU9x9Qc8kz+itKAEiH4DHUlLkb4YLzfEbAXfO09wvrQ3w==",
+ "version": "20.1.2",
+ "resolved": "https://registry.npmjs.org/detox/-/detox-20.1.2.tgz",
+ "integrity": "sha512-SGxLyuzE8TjIc4Lg49YKD0buj3JLaX+KtprSeFvn7ZTdWd4fH6o5Szd4KM21uBSpnYEEgXTgiCypPQst6dt5mQ==",
"dev": true,
"requires": {
"ajv": "^8.6.3",
@@ -12476,7 +12549,7 @@
"glob": "^8.0.3",
"ini": "^1.3.4",
"json-cycle": "^1.3.0",
- "lodash": "^4.17.5",
+ "lodash": "^4.17.11",
"multi-sort-stream": "^1.0.3",
"multipipe": "^4.0.0",
"node-ipc": "^9.2.1",
@@ -12859,19 +12932,19 @@
}
},
"find-babel-config": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz",
- "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.0.0.tgz",
+ "integrity": "sha512-dOKT7jvF3hGzlW60Gc3ONox/0rRZ/tz7WCil0bqA1In/3I8f1BctpXahRnEKDySZqci7u+dqq93sZST9fOJpFw==",
"dev": true,
"requires": {
- "json5": "^0.5.1",
- "path-exists": "^3.0.0"
+ "json5": "^2.1.1",
+ "path-exists": "^4.0.0"
},
"dependencies": {
- "json5": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
- "integrity": "sha512-4xrs1aW+6N5DalkqSVA8fxh458CXvR99WU8WLKmq4v8eWAL86Xo3BVqyd3SkA9wEVjCMqyvvRRkshAdOnBp5rw==",
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
}
}
@@ -15285,9 +15358,9 @@
"dev": true
},
"json5": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz",
- "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
+ "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"dev": true
},
"jsonfile": {
@@ -16111,9 +16184,9 @@
"dev": true
},
"reselect": {
- "version": "4.1.6",
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.6.tgz",
- "integrity": "sha512-ZovIuXqto7elwnxyXbBtCPo9YFEr3uJqj2rRbcOOog1bmu2Ag85M4hixSwFWyaBMKXNgvPaJ9OSu9SkBPIeJHQ==",
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
+ "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==",
"dev": true
},
"resolve": {
@@ -16622,15 +16695,15 @@
"dev": true
},
"ts-jest": {
- "version": "29.0.3",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
- "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
+ "version": "29.0.5",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz",
+ "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==",
"dev": true,
"requires": {
"bs-logger": "0.x",
"fast-json-stable-stringify": "2.x",
"jest-util": "^29.0.0",
- "json5": "^2.2.1",
+ "json5": "^2.2.3",
"lodash.memoize": "4.x",
"make-error": "1.x",
"semver": "7.x",
diff --git a/detox/package.json b/detox/package.json
index e91b122073..ae83b4aafc 100644
--- a/detox/package.json
+++ b/detox/package.json
@@ -9,17 +9,17 @@
"@babel/plugin-transform-runtime": "7.19.6",
"@babel/preset-env": "7.20.2",
"@jest/test-sequencer": "29.3.1",
- "@types/jest": "29.2.5",
+ "@types/jest": "29.2.6",
"@types/tough-cookie": "4.0.2",
"@types/uuid": "9.0.0",
- "aws-sdk": "2.1286.0",
- "axios": "1.2.2",
+ "aws-sdk": "2.1297.0",
+ "axios": "1.2.3",
"axios-cookiejar-support": "4.0.6",
"babel-jest": "29.3.1",
- "babel-plugin-module-resolver": "4.1.0",
+ "babel-plugin-module-resolver": "5.0.0",
"client-oauth2": "4.3.3",
"deepmerge": "4.2.2",
- "detox": "20.1.1",
+ "detox": "20.1.2",
"form-data": "4.0.0",
"jest": "29.3.1",
"jest-circus": "29.3.1",
@@ -33,7 +33,7 @@
"sanitize-filename": "1.6.3",
"shelljs": "0.8.5",
"tough-cookie": "4.1.2",
- "ts-jest": "29.0.3",
+ "ts-jest": "29.0.5",
"tslib": "2.4.1",
"typescript": "4.9.4",
"uuid": "9.0.0",
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
index 63a4161ab0..fad38e7460 100644
--- a/fastlane/Fastfile
+++ b/fastlane/Fastfile
@@ -667,6 +667,7 @@ platform :android do
package_id = ENV['MAIN_APP_IDENTIFIER'] || 'com.mattermost.rnbeta'
android_change_package_identifier(newIdentifier: package_id, manifest: './android/app/src/main/AndroidManifest.xml')
android_update_application_id(app_folder_name: 'android/app', application_id: package_id)
+ android_update_namespace(app_folder_name: 'android/app', namespace: package_id)
app_scheme = ENV['APP_SCHEME'] || 'mattermost'
find_replace_string(
@@ -693,12 +694,6 @@ platform :android do
sh "mv .#{beta_dir}* .#{release_dir}"
- find_replace_string(
- path_to_file: './android/app/BUCK',
- old_string: 'package com.mattermost.rnbeta;',
- new_string: "package #{package_id};"
- )
-
Dir.glob(".#{release_dir}*.java") do |item|
find_replace_string(
path_to_file: item[1..-1],
diff --git a/fastlane/Gemfile.lock b/fastlane/Gemfile.lock
index 8f0e2da226..5ca22a121f 100644
--- a/fastlane/Gemfile.lock
+++ b/fastlane/Gemfile.lock
@@ -8,16 +8,16 @@ GEM
artifactory (3.0.15)
atomos (0.1.3)
aws-eventstream (1.2.0)
- aws-partitions (1.683.0)
- aws-sdk-core (3.168.4)
+ aws-partitions (1.695.0)
+ aws-sdk-core (3.169.0)
aws-eventstream (~> 1, >= 1.0.2)
aws-partitions (~> 1, >= 1.651.0)
aws-sigv4 (~> 1.5)
jmespath (~> 1, >= 1.6.1)
- aws-sdk-kms (1.61.0)
+ aws-sdk-kms (1.62.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sigv4 (~> 1.1)
- aws-sdk-s3 (1.117.2)
+ aws-sdk-s3 (1.118.0)
aws-sdk-core (~> 3, >= 3.165.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.4)
@@ -36,8 +36,8 @@ GEM
unf (>= 0.0.5, < 1.0.0)
dotenv (2.8.1)
emoji_regex (3.2.3)
- excon (0.95.0)
- faraday (1.10.2)
+ excon (0.97.1)
+ faraday (1.10.3)
faraday-em_http (~> 1.0)
faraday-em_synchrony (~> 1.0)
faraday-excon (~> 1.1)
@@ -113,7 +113,7 @@ GEM
gh_inspector (1.1.3)
google-apis-androidpublisher_v3 (0.32.0)
google-apis-core (>= 0.9.1, < 2.a)
- google-apis-core (0.9.2)
+ google-apis-core (0.9.5)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.16.2, < 2.a)
httpclient (>= 2.8.1, < 3.a)
@@ -159,19 +159,19 @@ GEM
memoist (0.16.2)
mini_magick (4.12.0)
mini_mime (1.1.2)
- mini_portile2 (2.8.0)
+ mini_portile2 (2.8.1)
multi_json (1.15.0)
multipart-post (2.0.0)
nanaimo (0.3.0)
naturally (2.2.1)
- nokogiri (1.13.10)
+ nokogiri (1.14.0)
mini_portile2 (~> 2.8.0)
racc (~> 1.4)
optparse (0.1.1)
os (1.1.4)
plist (3.6.0)
public_suffix (5.0.1)
- racc (1.6.1)
+ racc (1.6.2)
rake (13.0.6)
representable (3.2.0)
declarative (< 0.1.0)
diff --git a/fastlane/actions/android_update_namespace.rb b/fastlane/actions/android_update_namespace.rb
new file mode 100644
index 0000000000..e0b0eecb49
--- /dev/null
+++ b/fastlane/actions/android_update_namespace.rb
@@ -0,0 +1,110 @@
+# rubocop:disable Style/CaseEquality
+# rubocop:disable Style/MultilineTernaryOperator
+# rubocop:disable Style/NestedTernaryOperator
+
+require 'tempfile'
+require 'fileutils'
+
+module Fastlane
+ module Actions
+ class AndroidUpdateNamespaceAction < Action
+ def self.run(params)
+ app_folder_name ||= params[:app_folder_name]
+ UI.message("The update_namespace plugin is looking inside your project folder (#{app_folder_name})!")
+
+ new_namespace ||= params[:namespace]
+ UI.message("new namespace = #{new_namespace}")
+
+ temp_file = Tempfile.new('fastlaneUpdateNamespace')
+ foundNamespace = "false"
+ Dir.glob("#{app_folder_name}/build.gradle") do |path|
+ UI.message(" -> Found a build.gradle file at path: (#{path})!")
+ begin
+ temp_file = Tempfile.new('fastlaneUpdateNamespace')
+ File.open(path, 'r') do |file|
+ file.each_line do |line|
+ if line.include? "namespace " and foundNamespace=="false"
+
+ applicationComponents = line.strip.split(' ')
+ namespace = applicationComponents[1].tr("\"","")
+ line.replace line.sub(namespace, new_namespace.to_s)
+ foundNamespace = "true"
+ temp_file.puts line
+ else
+ temp_file.puts line
+ end
+ end
+
+ if foundNamespace=="true"
+ break
+ end
+ file.close
+ end
+ temp_file.rewind
+ temp_file.close
+ FileUtils.mv(temp_file.path, path)
+ temp_file.unlink
+ ensure
+ if foundNamespace=="true"
+
+ break
+ end
+
+ end
+ end
+
+
+ if new_namespace.empty?
+ UI.user_error!("Impossible to update the namespace in the current project folder #{app_folder_name} 😭")
+ else
+ # Store the version name in the shared hash
+ Actions.lane_context["ANDROID_NAMESPACE"]=new_namespace
+ UI.success("☝️ namespace has been changed to #{new_namespace}")
+ end
+
+ return new_namespace
+ end
+
+ def self.description
+ "Update the namespace of your android project."
+ end
+
+ def self.authors
+ ["Elias Nahum"]
+ end
+
+ def self.available_options
+ [
+ FastlaneCore::ConfigItem.new(key: :app_folder_name,
+ env_name: "APPLICATIONID_APP_FOLDER_NAME",
+ description: "The name of the application source folder in the Android project (default: app)",
+ optional: true,
+ type: String,
+ default_value:"app"),
+ FastlaneCore::ConfigItem.new(key: :namespace,
+ env_name: "NAMESPACE_VALUE",
+ description: "Change to a specific namespace",
+ optional: false,
+ type: String,
+ default_value: '')
+ ]
+ end
+
+ def self.output
+ [
+ ['ANDROID_NAMESPACE', 'The new namespace of the project']
+ ]
+ end
+
+ def self.is_supported?(platform)
+ [:android].include?(platform)
+ end
+ end
+ end
+end
+
+
+
+# rubocop:enable Style/CaseEquality
+# rubocop:enable Style/MultilineTernaryOperator
+# rubocop:enable Style/NestedTernaryOperator
diff --git a/index.ts b/index.ts
index 1b0b597d17..69fbefa2df 100644
--- a/index.ts
+++ b/index.ts
@@ -3,10 +3,10 @@
import TurboLogger from '@mattermost/react-native-turbo-log';
import {LogBox, Platform} from 'react-native';
+import ViewReactNativeStyleAttributes from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes';
import {RUNNING_E2E} from 'react-native-dotenv';
import 'react-native-gesture-handler';
import {Navigation} from 'react-native-navigation';
-import ViewReactNativeStyleAttributes from 'react-native/Libraries/Components/View/ReactNativeStyleAttributes';
import {initialize, start} from './app/init/app';
import setFontFamily from './app/utils/font_family';
@@ -26,9 +26,6 @@ TurboLogger.configure({
if (__DEV__) {
LogBox.ignoreLogs([
- '`-[RCTRootView cancelTouches]`',
- 'scaleY',
- "[react-native-gesture-handler] Seems like you're using an old API with gesture components, check out new Gestures system!",
'new NativeEventEmitter',
]);
diff --git a/ios/Mattermost.xcodeproj/project.pbxproj b/ios/Mattermost.xcodeproj/project.pbxproj
index 958371b43e..638d652ec1 100644
--- a/ios/Mattermost.xcodeproj/project.pbxproj
+++ b/ios/Mattermost.xcodeproj/project.pbxproj
@@ -921,7 +921,7 @@
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-DoubleConversion/double-conversion.framework/double-conversion",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/Flipper-Glog/glog.framework/glog",
"${PODS_XCFRAMEWORKS_BUILD_DIR}/OpenSSL-Universal/OpenSSL.framework/OpenSSL",
- "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/hermes.framework/hermes",
+ "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes",
);
name = "[CP] Embed Pods Frameworks";
outputPaths = (
@@ -1116,7 +1116,7 @@
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- CURRENT_PROJECT_VERSION = 452;
+ CURRENT_PROJECT_VERSION = 453;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = (
@@ -1160,7 +1160,7 @@
CODE_SIGN_ENTITLEMENTS = Mattermost/Mattermost.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
- CURRENT_PROJECT_VERSION = 452;
+ CURRENT_PROJECT_VERSION = 453;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
ENABLE_BITCODE = NO;
HEADER_SEARCH_PATHS = (
@@ -1303,7 +1303,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
- CURRENT_PROJECT_VERSION = 452;
+ CURRENT_PROJECT_VERSION = 453;
DEBUG_INFORMATION_FORMAT = dwarf;
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
GCC_C_LANGUAGE_STANDARD = gnu11;
@@ -1354,7 +1354,7 @@
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CODE_SIGN_STYLE = Automatic;
COPY_PHASE_STRIP = NO;
- CURRENT_PROJECT_VERSION = 452;
+ CURRENT_PROJECT_VERSION = 453;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
GCC_C_LANGUAGE_STANDARD = gnu11;
diff --git a/ios/Mattermost.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/ios/Mattermost.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
index f9b0d7c5ea..ff23ebc817 100644
--- a/ios/Mattermost.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
+++ b/ios/Mattermost.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings
@@ -2,6 +2,8 @@
+ IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
+
PreviewsEnabled
diff --git a/ios/Mattermost/AppDelegate.h b/ios/Mattermost/AppDelegate.h
index 52ab11b46d..37ec94b47f 100644
--- a/ios/Mattermost/AppDelegate.h
+++ b/ios/Mattermost/AppDelegate.h
@@ -1,10 +1,9 @@
-#import
+#import
#import
#import "RNNotifications.h"
-@interface AppDelegate : UIResponder
+@interface AppDelegate : RCTAppDelegate
-@property (nonatomic, strong) UIWindow *window;
@property(nonatomic,assign)BOOL allowRotation;
@end
diff --git a/ios/Mattermost/AppDelegate.mm b/ios/Mattermost/AppDelegate.mm
index cda7f23962..c35997300f 100644
--- a/ios/Mattermost/AppDelegate.mm
+++ b/ios/Mattermost/AppDelegate.mm
@@ -3,9 +3,7 @@
#import
#import
-#import
#import
-#import
#import
#import
@@ -15,26 +13,6 @@
#import "Mattermost-Swift.h"
#import
-#if RCT_NEW_ARCH_ENABLED
-#import
-#import
-#import
-#import
-#import
-#import
-#import
-
-static NSString *const kRNConcurrentRoot = @"concurrentRoot";
-
-@interface AppDelegate () {
- RCTTurboModuleManager *_turboModuleManager;
- RCTSurfacePresenterBridgeAdapter *_bridgeAdapter;
- std::shared_ptr _reactNativeConfig;
- facebook::react::ContextContainer::Shared _contextContainer;
-}
-@end
-#endif
-
@implementation AppDelegate
NSString* const NOTIFICATION_MESSAGE_ACTION = @"message";
@@ -50,8 +28,6 @@ NSString* const NOTIFICATION_TEST_ACTION = @"test";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
- RCTAppSetupPrepareApp(application);
-
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
_allowRotation = YES;
@@ -75,25 +51,11 @@ NSString* const NOTIFICATION_TEST_ACTION = @"test";
[RNNotifications startMonitorNotifications];
- self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
- if (@available(iOS 13.0, *)) {
- self.window.backgroundColor = [UIColor systemBackgroundColor];
- } else {
- self.window.backgroundColor = [UIColor whiteColor];
- }
- [self.window makeKeyWindow];
-
- RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions];
-
- #if RCT_NEW_ARCH_ENABLED
- _contextContainer = std::make_shared();
- _reactNativeConfig = std::make_shared();
- _contextContainer->insert("ReactNativeConfig", _reactNativeConfig);
- _bridgeAdapter = [[RCTSurfacePresenterBridgeAdapter alloc] initWithBridge:bridge contextContainer:_contextContainer];
- bridge.surfacePresenter = _bridgeAdapter.surfacePresenter;
- #endif
-
- [ReactNativeNavigation bootstrapWithBridge:bridge];
+ self.moduleName = @"Mattermost";
+ // You can add your custom initial props in the dictionary below.
+ // They will be passed down to the ViewController used by React Native.
+ self.initialProps = @{};
+ [ReactNativeNavigation bootstrapWithDelegate:self launchOptions:launchOptions];
os_log(OS_LOG_DEFAULT, "Mattermost started!!");
@@ -250,6 +212,7 @@ RNHWKeyboardEvent *hwKeyEvent = nil;
// Switch this bool to turn on and off the concurrent root
return false;
}
+
- (NSDictionary *)prepareInitialProps
{
NSMutableDictionary *initProps = [NSMutableDictionary new];
@@ -268,35 +231,4 @@ RNHWKeyboardEvent *hwKeyEvent = nil;
#endif
}
-#if RCT_NEW_ARCH_ENABLED
-#pragma mark - RCTCxxBridgeDelegate
-- (std::unique_ptr)jsExecutorFactoryForBridge:(RCTBridge *)bridge
-{
- _turboModuleManager = [[RCTTurboModuleManager alloc] initWithBridge:bridge
- delegate:self
- jsInvoker:bridge.jsCallInvoker];
- return RCTAppSetupDefaultJsExecutorFactory(bridge, _turboModuleManager);
-}
-#pragma mark RCTTurboModuleManagerDelegate
-- (Class)getModuleClassFromName:(const char *)name
-{
- return RCTCoreModulesClassProvider(name);
-}
-- (std::shared_ptr)getTurboModule:(const std::string &)name
- jsInvoker:(std::shared_ptr)jsInvoker
-{
- return nullptr;
-}
-- (std::shared_ptr)getTurboModule:(const std::string &)name
- initParams:
- (const facebook::react::ObjCTurboModule::InitParams &)params
-{
- return nullptr;
-}
-- (id)getModuleInstanceFromClass:(Class)moduleClass
-{
- return RCTAppSetupDefaultModuleFromClass(moduleClass);
-}
-#endif
-
@end
diff --git a/ios/Mattermost/Info.plist b/ios/Mattermost/Info.plist
index b92fded1b0..e8483614ce 100644
--- a/ios/Mattermost/Info.plist
+++ b/ios/Mattermost/Info.plist
@@ -37,7 +37,7 @@
CFBundleVersion
- 452
+ 453
ITSAppUsesNonExemptEncryption
LSRequiresIPhoneOS
@@ -83,6 +83,10 @@
Upload photos and videos from your device to $(PRODUCT_NAME)
NSSpeechRecognitionUsageDescription
Send voice messages to $(PRODUCT_NAME)
+ NSUserActivityTypes
+
+ INSendMessageIntent
+
UIAppFonts
OpenSans-Bold.ttf
@@ -113,23 +117,21 @@
armv7
UIRequiresFullScreen
-
+
UISupportedInterfaceOrientations
- UIInterfaceOrientationPortrait
UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortrait
UISupportedInterfaceOrientations~ipad
- UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
UIInterfaceOrientationLandscapeRight
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
UIViewControllerBasedStatusBarAppearance
- NSUserActivityTypes
-
- INSendMessageIntent
-
diff --git a/ios/MattermostShare/Info.plist b/ios/MattermostShare/Info.plist
index 597ef229c3..80d2594e0e 100644
--- a/ios/MattermostShare/Info.plist
+++ b/ios/MattermostShare/Info.plist
@@ -21,7 +21,7 @@
CFBundleShortVersionString
2.0.0
CFBundleVersion
- 452
+ 453
UIAppFonts
OpenSans-Bold.ttf
diff --git a/ios/NotificationService/Info.plist b/ios/NotificationService/Info.plist
index 9085909595..6eaa7947d9 100644
--- a/ios/NotificationService/Info.plist
+++ b/ios/NotificationService/Info.plist
@@ -21,7 +21,7 @@
CFBundleShortVersionString
2.0.0
CFBundleVersion
- 452
+ 453
NSExtension
NSExtensionPointIdentifier
diff --git a/ios/Podfile b/ios/Podfile
index a740aa8fab..0c70352b4f 100644
--- a/ios/Podfile
+++ b/ios/Podfile
@@ -1,8 +1,24 @@
require_relative '../node_modules/react-native/scripts/react_native_pods'
require_relative '../node_modules/@react-native-community/cli-platform-ios/native_modules'
-platform :ios, '12.4'
-install! 'cocoapods', :deterministic_uuids => false
+platform :ios, min_ios_version_supported
+prepare_react_native_project!
+
+# If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set.
+# because `react-native-flipper` depends on (FlipperKit,...) that will be excluded
+#
+# To fix this you can also exclude `react-native-flipper` using a `react-native.config.js`
+# ```js
+# module.exports = {
+# dependencies: {
+# ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}),
+# ```
+flipper_config = ENV['NO_FLIPPER'] == "1" ? FlipperConfiguration.disabled : FlipperConfiguration.enabled
+linkage = ENV['USE_FRAMEWORKS']
+if linkage != nil
+ Pod::UI.puts "Configuring Pod with #{linkage}ally linked Frameworks".green
+ use_frameworks! :linkage => linkage.to_sym
+end
target 'Mattermost' do
# Pods for Mattermost
@@ -23,7 +39,7 @@ target 'Mattermost' do
#
# Note that if you have use_frameworks! enabled, Flipper will not work and
# you should disable the next line.
- :flipper_configuration => FlipperConfiguration.enabled,
+ :flipper_configuration => flipper_config,
# An absolute path to your application root.
:app_path => "#{Pod::Config.instance.installation_root}/.."
)
@@ -34,6 +50,7 @@ target 'Mattermost' do
pod 'Permission-Notifications', :path => "#{permissions_path}/Notifications"
pod 'Permission-PhotoLibrary', :path => "#{permissions_path}/PhotoLibrary"
pod 'React-jsi', :path => '../node_modules/react-native/ReactCommon/jsi', :modular_headers => true
+ pod 'React-jsc', :path => '../node_modules/react-native/ReactCommon/jsc', :modular_headers => true
pod 'simdjson', path: '../node_modules/@nozbe/simdjson'
# TODO: Remove this once upstream PR https://github.com/daltoniam/Starscream/pull/871 is merged
@@ -53,16 +70,4 @@ post_install do |installer|
puts 'Patching Alamofire to include X-Uncompressed-Content-Length to measure download progress'
%x(patch Pods/Alamofire/Source/SessionDelegate.swift < patches/SessionDelegate.patch)
- installer.pods_project.targets.each do |target|
- if target.name != "RCT-Folly"
- target.build_configurations.each do |config|
- config.build_settings.delete 'IPHONEOS_DEPLOYMENT_TARGET'
- end
- end
- if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle"
- target.build_configurations.each do |config|
- config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO'
- end
- end
- end
end
diff --git a/ios/Podfile.lock b/ios/Podfile.lock
index ddd55e7aad..28a3a4b73f 100644
--- a/ios/Podfile.lock
+++ b/ios/Podfile.lock
@@ -8,14 +8,14 @@ PODS:
- CocoaLumberjack/Core (= 3.8.0)
- CocoaLumberjack/Core (3.8.0)
- DoubleConversion (1.1.6)
- - FBLazyVector (0.70.6)
- - FBReactNativeSpec (0.70.6):
+ - FBLazyVector (0.71.1)
+ - FBReactNativeSpec (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- - RCTRequired (= 0.70.6)
- - RCTTypeSafety (= 0.70.6)
- - React-Core (= 0.70.6)
- - React-jsi (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
+ - RCTRequired (= 0.71.1)
+ - RCTTypeSafety (= 0.71.1)
+ - React-Core (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
- Flipper (0.125.0):
- Flipper-Folly (~> 2.6)
- Flipper-RSocket (~> 1.4)
@@ -79,7 +79,9 @@ PODS:
- FlipperKit/FlipperKitNetworkPlugin
- fmt (6.2.1)
- glog (0.3.5)
- - hermes-engine (0.70.6)
+ - hermes-engine (0.71.1):
+ - hermes-engine/Pre-built (= 0.71.1)
+ - hermes-engine/Pre-built (0.71.1)
- HMSegmentedControl (1.5.6)
- jail-monkey (2.8.0):
- React-Core
@@ -93,8 +95,9 @@ PODS:
- libwebp/mux (1.2.4):
- libwebp/demux
- libwebp/webp (1.2.4)
- - mattermost-react-native-turbo-log (0.2.1):
+ - mattermost-react-native-turbo-log (0.2.2):
- CocoaLumberjack
+ - RCT-Folly (= 2021.07.22.00)
- React-Core
- OpenSSL-Universal (1.1.1100)
- Permission-Camera (3.6.1):
@@ -122,218 +125,216 @@ PODS:
- fmt (~> 6.2.1)
- glog
- libevent
- - RCTRequired (0.70.6)
- - RCTTypeSafety (0.70.6):
- - FBLazyVector (= 0.70.6)
- - RCTRequired (= 0.70.6)
- - React-Core (= 0.70.6)
- - React (0.70.6):
- - React-Core (= 0.70.6)
- - React-Core/DevSupport (= 0.70.6)
- - React-Core/RCTWebSocket (= 0.70.6)
- - React-RCTActionSheet (= 0.70.6)
- - React-RCTAnimation (= 0.70.6)
- - React-RCTBlob (= 0.70.6)
- - React-RCTImage (= 0.70.6)
- - React-RCTLinking (= 0.70.6)
- - React-RCTNetwork (= 0.70.6)
- - React-RCTSettings (= 0.70.6)
- - React-RCTText (= 0.70.6)
- - React-RCTVibration (= 0.70.6)
- - React-bridging (0.70.6):
- - RCT-Folly (= 2021.07.22.00)
- - React-jsi (= 0.70.6)
- - React-callinvoker (0.70.6)
- - React-Codegen (0.70.6):
- - FBReactNativeSpec (= 0.70.6)
- - RCT-Folly (= 2021.07.22.00)
- - RCTRequired (= 0.70.6)
- - RCTTypeSafety (= 0.70.6)
- - React-Core (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-Core (0.70.6):
+ - RCTRequired (0.71.1)
+ - RCTTypeSafety (0.71.1):
+ - FBLazyVector (= 0.71.1)
+ - RCTRequired (= 0.71.1)
+ - React-Core (= 0.71.1)
+ - React (0.71.1):
+ - React-Core (= 0.71.1)
+ - React-Core/DevSupport (= 0.71.1)
+ - React-Core/RCTWebSocket (= 0.71.1)
+ - React-RCTActionSheet (= 0.71.1)
+ - React-RCTAnimation (= 0.71.1)
+ - React-RCTBlob (= 0.71.1)
+ - React-RCTImage (= 0.71.1)
+ - React-RCTLinking (= 0.71.1)
+ - React-RCTNetwork (= 0.71.1)
+ - React-RCTSettings (= 0.71.1)
+ - React-RCTText (= 0.71.1)
+ - React-RCTVibration (= 0.71.1)
+ - React-callinvoker (0.71.1)
+ - React-Codegen (0.71.1):
+ - FBReactNativeSpec
+ - hermes-engine
+ - RCT-Folly
+ - RCTRequired
+ - RCTTypeSafety
+ - React-Core
+ - React-jsi
+ - React-jsiexecutor
+ - ReactCommon/turbomodule/bridging
+ - ReactCommon/turbomodule/core
+ - React-Core (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- - React-Core/Default (= 0.70.6)
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-Core/Default (= 0.71.1)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/CoreModulesHeaders (0.70.6):
+ - React-Core/CoreModulesHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/Default (0.70.6):
+ - React-Core/Default (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/DevSupport (0.70.6):
+ - React-Core/DevSupport (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- - React-Core/Default (= 0.70.6)
- - React-Core/RCTWebSocket (= 0.70.6)
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-jsinspector (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-Core/Default (= 0.71.1)
+ - React-Core/RCTWebSocket (= 0.71.1)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-jsinspector (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTActionSheetHeaders (0.70.6):
+ - React-Core/RCTActionSheetHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTAnimationHeaders (0.70.6):
+ - React-Core/RCTAnimationHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTBlobHeaders (0.70.6):
+ - React-Core/RCTBlobHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTImageHeaders (0.70.6):
+ - React-Core/RCTImageHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTLinkingHeaders (0.70.6):
+ - React-Core/RCTLinkingHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTNetworkHeaders (0.70.6):
+ - React-Core/RCTNetworkHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTSettingsHeaders (0.70.6):
+ - React-Core/RCTSettingsHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTTextHeaders (0.70.6):
+ - React-Core/RCTTextHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTVibrationHeaders (0.70.6):
+ - React-Core/RCTVibrationHeaders (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- React-Core/Default
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-Core/RCTWebSocket (0.70.6):
+ - React-Core/RCTWebSocket (0.71.1):
- glog
- RCT-Folly (= 2021.07.22.00)
- - React-Core/Default (= 0.70.6)
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-Core/Default (= 0.71.1)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- Yoga
- - React-CoreModules (0.70.6):
+ - React-CoreModules (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- - RCTTypeSafety (= 0.70.6)
- - React-Codegen (= 0.70.6)
- - React-Core/CoreModulesHeaders (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-RCTImage (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-cxxreact (0.70.6):
+ - RCTTypeSafety (= 0.71.1)
+ - React-Codegen (= 0.71.1)
+ - React-Core/CoreModulesHeaders (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-RCTImage (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
+ - React-cxxreact (0.71.1):
- boost (= 1.76.0)
- DoubleConversion
- glog
- RCT-Folly (= 2021.07.22.00)
- - React-callinvoker (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsinspector (= 0.70.6)
- - React-logger (= 0.70.6)
- - React-perflogger (= 0.70.6)
- - React-runtimeexecutor (= 0.70.6)
- - React-hermes (0.70.6):
+ - React-callinvoker (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsinspector (= 0.71.1)
+ - React-logger (= 0.71.1)
+ - React-perflogger (= 0.71.1)
+ - React-runtimeexecutor (= 0.71.1)
+ - React-hermes (0.71.1):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2021.07.22.00)
- RCT-Folly/Futures (= 2021.07.22.00)
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-jsiexecutor (= 0.70.6)
- - React-jsinspector (= 0.70.6)
- - React-perflogger (= 0.70.6)
- - React-jsi (0.70.6):
+ - React-cxxreact (= 0.71.1)
+ - React-jsiexecutor (= 0.71.1)
+ - React-jsinspector (= 0.71.1)
+ - React-perflogger (= 0.71.1)
+ - React-jsc (0.71.1):
+ - React-jsc/Fabric (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-jsc/Fabric (0.71.1):
+ - React-jsi (= 0.71.1)
+ - React-jsi (0.71.1):
- boost (= 1.76.0)
- DoubleConversion
- glog
+ - hermes-engine
- RCT-Folly (= 2021.07.22.00)
- - React-jsi/Default (= 0.70.6)
- - React-jsi/Default (0.70.6):
- - boost (= 1.76.0)
+ - React-jsiexecutor (0.71.1):
- DoubleConversion
- glog
- RCT-Folly (= 2021.07.22.00)
- - React-jsiexecutor (0.70.6):
- - DoubleConversion
- - glog
- - RCT-Folly (= 2021.07.22.00)
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-perflogger (= 0.70.6)
- - React-jsinspector (0.70.6)
- - React-logger (0.70.6):
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-perflogger (= 0.71.1)
+ - React-jsinspector (0.71.1)
+ - React-logger (0.71.1):
- glog
- react-native-background-timer (2.4.1):
- React-Core
- - react-native-cameraroll (5.2.1):
+ - react-native-cameraroll (5.2.2):
- React-Core
- react-native-cookies (6.2.1):
- React-Core
@@ -341,33 +342,34 @@ PODS:
- React-Core
- react-native-document-picker (8.1.3):
- React-Core
- - react-native-emm (1.3.3):
+ - react-native-emm (1.3.4):
- React-Core
- react-native-hw-keyboard-event (0.0.4):
- React
- - react-native-image-picker (4.10.3):
+ - react-native-image-picker (5.0.1):
- React-Core
- react-native-in-app-review (4.2.1):
- React-Core
- react-native-netinfo (9.3.7):
- React-Core
- - react-native-network-client (1.0.2):
+ - react-native-network-client (1.1.0):
- Alamofire (~> 5.6.4)
- React-Core
- Starscream (~> 4.0.4)
- SwiftyJSON (~> 5.0)
- react-native-notifications (4.3.3):
- React-Core
- - react-native-paste-input (0.5.2):
+ - react-native-paste-input (0.6.0):
- React-Core
- Swime (= 3.0.6)
- - react-native-safe-area-context (4.4.1):
+ - react-native-safe-area-context (4.5.0):
- RCT-Folly
- RCTRequired
- RCTTypeSafety
- React-Core
- ReactCommon/turbomodule/core
- - react-native-turbo-mailer (0.2.0):
+ - react-native-turbo-mailer (0.2.3):
+ - RCT-Folly (= 2021.07.22.00)
- React-Core
- react-native-video (5.2.1):
- React-Core
@@ -378,92 +380,107 @@ PODS:
- React
- react-native-webview (11.26.0):
- React-Core
- - React-perflogger (0.70.6)
- - React-RCTActionSheet (0.70.6):
- - React-Core/RCTActionSheetHeaders (= 0.70.6)
- - React-RCTAnimation (0.70.6):
+ - React-perflogger (0.71.1)
+ - React-RCTActionSheet (0.71.1):
+ - React-Core/RCTActionSheetHeaders (= 0.71.1)
+ - React-RCTAnimation (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- - RCTTypeSafety (= 0.70.6)
- - React-Codegen (= 0.70.6)
- - React-Core/RCTAnimationHeaders (= 0.70.6)
- - React-jsi (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-RCTBlob (0.70.6):
+ - RCTTypeSafety (= 0.71.1)
+ - React-Codegen (= 0.71.1)
+ - React-Core/RCTAnimationHeaders (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
+ - React-RCTAppDelegate (0.71.1):
+ - RCT-Folly
+ - RCTRequired
+ - RCTTypeSafety
+ - React-Core
+ - ReactCommon/turbomodule/core
+ - React-RCTBlob (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- - React-Codegen (= 0.70.6)
- - React-Core/RCTBlobHeaders (= 0.70.6)
- - React-Core/RCTWebSocket (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-RCTNetwork (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-RCTImage (0.70.6):
+ - React-Codegen (= 0.71.1)
+ - React-Core/RCTBlobHeaders (= 0.71.1)
+ - React-Core/RCTWebSocket (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-RCTNetwork (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
+ - React-RCTImage (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- - RCTTypeSafety (= 0.70.6)
- - React-Codegen (= 0.70.6)
- - React-Core/RCTImageHeaders (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-RCTNetwork (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-RCTLinking (0.70.6):
- - React-Codegen (= 0.70.6)
- - React-Core/RCTLinkingHeaders (= 0.70.6)
- - React-jsi (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-RCTNetwork (0.70.6):
+ - RCTTypeSafety (= 0.71.1)
+ - React-Codegen (= 0.71.1)
+ - React-Core/RCTImageHeaders (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-RCTNetwork (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
+ - React-RCTLinking (0.71.1):
+ - React-Codegen (= 0.71.1)
+ - React-Core/RCTLinkingHeaders (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
+ - React-RCTNetwork (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- - RCTTypeSafety (= 0.70.6)
- - React-Codegen (= 0.70.6)
- - React-Core/RCTNetworkHeaders (= 0.70.6)
- - React-jsi (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-RCTSettings (0.70.6):
+ - RCTTypeSafety (= 0.71.1)
+ - React-Codegen (= 0.71.1)
+ - React-Core/RCTNetworkHeaders (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
+ - React-RCTSettings (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- - RCTTypeSafety (= 0.70.6)
- - React-Codegen (= 0.70.6)
- - React-Core/RCTSettingsHeaders (= 0.70.6)
- - React-jsi (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-RCTText (0.70.6):
- - React-Core/RCTTextHeaders (= 0.70.6)
- - React-RCTVibration (0.70.6):
+ - RCTTypeSafety (= 0.71.1)
+ - React-Codegen (= 0.71.1)
+ - React-Core/RCTSettingsHeaders (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
+ - React-RCTText (0.71.1):
+ - React-Core/RCTTextHeaders (= 0.71.1)
+ - React-RCTVibration (0.71.1):
- RCT-Folly (= 2021.07.22.00)
- - React-Codegen (= 0.70.6)
- - React-Core/RCTVibrationHeaders (= 0.70.6)
- - React-jsi (= 0.70.6)
- - ReactCommon/turbomodule/core (= 0.70.6)
- - React-runtimeexecutor (0.70.6):
- - React-jsi (= 0.70.6)
- - ReactCommon/turbomodule/core (0.70.6):
+ - React-Codegen (= 0.71.1)
+ - React-Core/RCTVibrationHeaders (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - ReactCommon/turbomodule/core (= 0.71.1)
+ - React-runtimeexecutor (0.71.1):
+ - React-jsi (= 0.71.1)
+ - ReactCommon/turbomodule/bridging (0.71.1):
- DoubleConversion
- glog
- RCT-Folly (= 2021.07.22.00)
- - React-bridging (= 0.70.6)
- - React-callinvoker (= 0.70.6)
- - React-Core (= 0.70.6)
- - React-cxxreact (= 0.70.6)
- - React-jsi (= 0.70.6)
- - React-logger (= 0.70.6)
- - React-perflogger (= 0.70.6)
+ - React-callinvoker (= 0.71.1)
+ - React-Core (= 0.71.1)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-logger (= 0.71.1)
+ - React-perflogger (= 0.71.1)
+ - ReactCommon/turbomodule/core (0.71.1):
+ - DoubleConversion
+ - glog
+ - RCT-Folly (= 2021.07.22.00)
+ - React-callinvoker (= 0.71.1)
+ - React-Core (= 0.71.1)
+ - React-cxxreact (= 0.71.1)
+ - React-jsi (= 0.71.1)
+ - React-logger (= 0.71.1)
+ - React-perflogger (= 0.71.1)
- ReactNativeExceptionHandler (2.10.10):
- React-Core
- ReactNativeIncallManager (4.0.0):
- React-Core
- ReactNativeKeyboardTrackingView (5.7.0):
- React
- - ReactNativeNavigation (7.30.6):
+ - ReactNativeNavigation (7.31.1):
- HMSegmentedControl
- React-Core
- React-RCTImage
- React-RCTText
- - ReactNativeNavigation/Core (= 7.30.6)
- - ReactNativeNavigation/Core (7.30.6):
+ - ReactNativeNavigation/Core (= 7.31.1)
+ - ReactNativeNavigation/Core (7.31.1):
- HMSegmentedControl
- React-Core
- React-RCTImage
- React-RCTText
- RNCClipboard (1.11.1):
- React-Core
- - RNDateTimePicker (6.7.1):
+ - RNDateTimePicker (6.7.3):
- React-Core
- RNDeviceInfo (10.3.0):
- React-Core
@@ -475,7 +492,7 @@ PODS:
- React-Core
- RNFS (2.20.0):
- React-Core
- - RNGestureHandler (2.8.0):
+ - RNGestureHandler (2.9.0):
- React-Core
- RNKeychain (8.1.1):
- React-Core
@@ -485,7 +502,7 @@ PODS:
- React-Core
- RNReactNativeHapticFeedback (1.14.0):
- React-Core
- - RNReanimated (2.13.0):
+ - RNReanimated (2.14.4):
- DoubleConversion
- FBLazyVector
- FBReactNativeSpec
@@ -512,18 +529,18 @@ PODS:
- React-RCTText
- ReactCommon/turbomodule/core
- Yoga
- - RNRudderSdk (1.0.0):
+ - RNRudderSdk (1.5.2):
- React
- Rudder (~> 1.6.0)
- - RNScreens (3.18.2):
+ - RNScreens (3.19.0):
- React-Core
- React-RCTImage
- - RNSentry (4.12.0):
+ - RNSentry (4.13.0):
- React-Core
- - Sentry/HybridSDK (= 7.31.3)
+ - Sentry/HybridSDK (= 7.31.5)
- RNShare (8.1.0):
- React-Core
- - RNSVG (13.6.0):
+ - RNSVG (13.7.0):
- React-Core
- RNVectorIcons (9.2.0):
- React-Core
@@ -534,13 +551,13 @@ PODS:
- SDWebImageWebPCoder (0.8.5):
- libwebp (~> 1.0)
- SDWebImage/Core (~> 5.10)
- - Sentry/HybridSDK (7.31.3)
+ - Sentry/HybridSDK (7.31.5)
- simdjson (1.0.0)
- SocketRocket (0.6.0)
- Starscream (4.0.4)
- SwiftyJSON (5.0.1)
- Swime (3.0.6)
- - WatermelonDB (0.24.0):
+ - WatermelonDB (0.25.1):
- React
- React-jsi
- Yoga (1.14.0)
@@ -575,7 +592,7 @@ DEPENDENCIES:
- FlipperKit/FlipperKitUserDefaultsPlugin (= 0.125.0)
- FlipperKit/SKIOSNetworkPlugin (= 0.125.0)
- glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`)
- - hermes-engine (from `../node_modules/react-native/sdks/hermes/hermes-engine.podspec`)
+ - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`)
- jail-monkey (from `../node_modules/jail-monkey`)
- libevent (~> 2.1.12)
- "mattermost-react-native-turbo-log (from `../node_modules/@mattermost/react-native-turbo-log`)"
@@ -588,7 +605,6 @@ DEPENDENCIES:
- RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`)
- RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`)
- React (from `../node_modules/react-native/`)
- - React-bridging (from `../node_modules/react-native/ReactCommon`)
- React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`)
- React-Codegen (from `build/generated/ios`)
- React-Core (from `../node_modules/react-native/`)
@@ -597,6 +613,7 @@ DEPENDENCIES:
- React-CoreModules (from `../node_modules/react-native/React/CoreModules`)
- React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`)
- React-hermes (from `../node_modules/react-native/ReactCommon/hermes`)
+ - React-jsc (from `../node_modules/react-native/ReactCommon/jsc`)
- React-jsi (from `../node_modules/react-native/ReactCommon/jsi`)
- React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`)
- React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`)
@@ -622,6 +639,7 @@ DEPENDENCIES:
- React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`)
- React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`)
- React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`)
+ - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`)
- React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`)
- React-RCTImage (from `../node_modules/react-native/Libraries/Image`)
- React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`)
@@ -700,7 +718,7 @@ EXTERNAL SOURCES:
glog:
:podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec"
hermes-engine:
- :podspec: "../node_modules/react-native/sdks/hermes/hermes-engine.podspec"
+ :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec"
jail-monkey:
:path: "../node_modules/jail-monkey"
mattermost-react-native-turbo-log:
@@ -721,8 +739,6 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/TypeSafety"
React:
:path: "../node_modules/react-native/"
- React-bridging:
- :path: "../node_modules/react-native/ReactCommon"
React-callinvoker:
:path: "../node_modules/react-native/ReactCommon/callinvoker"
React-Codegen:
@@ -735,6 +751,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/ReactCommon/cxxreact"
React-hermes:
:path: "../node_modules/react-native/ReactCommon/hermes"
+ React-jsc:
+ :path: "../node_modules/react-native/ReactCommon/jsc"
React-jsi:
:path: "../node_modules/react-native/ReactCommon/jsi"
React-jsiexecutor:
@@ -785,6 +803,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native/Libraries/ActionSheetIOS"
React-RCTAnimation:
:path: "../node_modules/react-native/Libraries/NativeAnimation"
+ React-RCTAppDelegate:
+ :path: "../node_modules/react-native/Libraries/AppDelegate"
React-RCTBlob:
:path: "../node_modules/react-native/Libraries/Blob"
React-RCTImage:
@@ -864,13 +884,13 @@ CHECKOUT OPTIONS:
SPEC CHECKSUMS:
Alamofire: 4e95d97098eacb88856099c4fc79b526a299e48c
- boost: a7c83b31436843459a1961bfd74b96033dc77234
+ boost: 57d2868c099736d80fcd648bf211b4431e51a558
BVLinearGradient: 34a999fda29036898a09c6a6b728b0b4189e1a44
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
CocoaLumberjack: 78abfb691154e2a9df8ded4350d504ee19d90732
DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54
- FBLazyVector: 48289402952f4f7a4e235de70a9a590aa0b79ef4
- FBReactNativeSpec: dd1186fd05255e3457baa2f4ca65e94c2cd1e3ac
+ FBLazyVector: ad72713385db5289b19f1ead07e8e4aa26dcb01d
+ FBReactNativeSpec: df2602c11e33d310433496e28a48b4b2be652a61
Flipper: 26fc4b7382499f1281eb8cb921e5c3ad6de91fe0
Flipper-Boost-iOSX: fd1e2b8cbef7e662a122412d7ac5f5bea715403c
Flipper-DoubleConversion: 2dc99b02f658daf147069aad9dbd29d8feb06d30
@@ -882,97 +902,98 @@ SPEC CHECKSUMS:
FlipperKit: cbdee19bdd4e7f05472a66ce290f1b729ba3cb86
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
- hermes-engine: 2af7b7a59128f250adfd86f15aa1d5a2ecd39995
+ hermes-engine: 922ccd744f50d9bfde09e9677bf0f3b562ea5fb9
HMSegmentedControl: 34c1f54d822d8308e7b24f5d901ec674dfa31352
jail-monkey: a71b35d482a70ecba844a90f002994012cf12a5d
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
libwebp: f62cb61d0a484ba548448a4bd52aabf150ff6eef
- mattermost-react-native-turbo-log: bc61d03ab49480cd03a68dd85e816910d941c82f
+ mattermost-react-native-turbo-log: 3c56c4e6e1d706b70d652e5509d1254eef914153
OpenSSL-Universal: ebc357f1e6bc71fa463ccb2fe676756aff50e88c
Permission-Camera: bf6791b17c7f614b6826019fcfdcc286d3a107f6
Permission-Microphone: 48212dd4d28025d9930d583e3c7a56da7268665c
Permission-Notifications: 150484ae586eb9be4e32217582a78350a9bb31c3
Permission-PhotoLibrary: 5b34ca67279f7201ae109cef36f9806a6596002d
- RCT-Folly: 0080d0a6ebf2577475bda044aa59e2ca1f909cda
- RCTRequired: e1866f61af7049eb3d8e08e8b133abd38bc1ca7a
- RCTTypeSafety: 27c2ac1b00609a432ced1ae701247593f07f901e
- React: bb3e06418d2cc48a84f9666a576c7b38e89cd7db
- React-bridging: 572502ec59c9de30309afdc4932e278214288913
- React-callinvoker: 6b708b79c69f3359d42f1abb4663f620dbd4dadf
- React-Codegen: 74e1cd7cee692a8b983c18df3274b5e749de07c8
- React-Core: b587d0a624f9611b0e032505f3d6f25e8daa2bee
- React-CoreModules: c6ff48b985e7aa622e82ca51c2c353c7803eb04e
- React-cxxreact: ade3d9e63c599afdead3c35f8a8bd12b3da6730b
- React-hermes: ed09ae33512bbb8d31b2411778f3af1a2eb681a1
- React-jsi: 5a3952e0c6d57460ad9ee2c905025b4c28f71087
- React-jsiexecutor: b4a65947391c658450151275aa406f2b8263178f
- React-jsinspector: 60769e5a0a6d4b32294a2456077f59d0266f9a8b
- React-logger: 1623c216abaa88974afce404dc8f479406bbc3a0
+ RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1
+ RCTRequired: fd4d923b964658aa0c4091a32c8b2004c6d9e3a6
+ RCTTypeSafety: c276d85975bde3d8448907235c70bf0da257adfd
+ React: e481a67971af1ce9639c9f746b753dd0e84ca108
+ React-callinvoker: 1051c04a94fa9d243786b86380606bad701a3b31
+ React-Codegen: 14b1e716d361d5ad95e0ce1a338f3fa0733a98b5
+ React-Core: 698fc3baecb80d511d987475a16d036cec6d287f
+ React-CoreModules: 59245305f41ff0adfeac334acc0594dea4585a7c
+ React-cxxreact: 49accd2954b0f532805dbcd1918fa6962f32f247
+ React-hermes: d068733294581a085e95b6024e8d951b005e26d3
+ React-jsc: b4246f1eed2b9addf2edc93b0462c1b4e55fc1d6
+ React-jsi: 122b9bce14f4c6c7cb58f28f87912cfe091885fa
+ React-jsiexecutor: 60cf272aababc5212410e4249d17cea14fc36caa
+ React-jsinspector: ff56004b0c974b688a6548c156d5830ad751ae07
+ React-logger: 60a0b5f8bed667ecf9e24fecca1f30d125de6d75
react-native-background-timer: 17ea5e06803401a379ebf1f20505b793ac44d0fe
- react-native-cameraroll: f94bf9f46c998963ecd2bb6e9a3f9cca59b6d9f1
+ react-native-cameraroll: 71d68167beb6fc7216aa564abb6d86f1d666a2c6
react-native-cookies: f54fcded06bb0cda05c11d86788020b43528a26c
react-native-create-thumbnail: e022bcdcba8a0b4529a50d3fa1a832ec921be39d
react-native-document-picker: 958e2bc82e128be69055be261aeac8d872c8d34c
- react-native-emm: c5b7dcffde34ce345fd0c16d66b587e611a3d31f
+ react-native-emm: 8439515a27ad8723dfd37f554ea6c944882a49bc
react-native-hw-keyboard-event: b517cefb8d5c659a38049c582de85ff43337dc53
- react-native-image-picker: 60f4246eb5bb7187fc15638a8c1f13abd3820695
+ react-native-image-picker: 8cb4280e2c1efc3daeb2d9d597f9429a60472e40
react-native-in-app-review: a073f67c5f3392af6ea7fb383217cdb1aa2aa726
react-native-netinfo: 2517ad504b3d303e90d7a431b0fcaef76d207983
- react-native-network-client: ce464b9d413872f1b0c36852a44d66b1a45a9dce
+ react-native-network-client: 88b7ef8ef937352db3cfdbea939dc55397c64b9f
react-native-notifications: 83b4fd4a127a6c918fc846cae90da60f84819e44
- react-native-paste-input: 88709b4fd586ea8cc56ba5e2fc4cdfe90597730c
- react-native-safe-area-context: 99b24a0c5acd0d5dcac2b1a7f18c49ea317be99a
- react-native-turbo-mailer: 226fc3533d16500fb4ad08cf8ab2cfc7bb1ef593
+ react-native-paste-input: 5182843692fd2ec72be50f241a38a49796e225d7
+ react-native-safe-area-context: 39c2d8be3328df5d437ac1700f4f3a4f75716acc
+ react-native-turbo-mailer: fa3f18b5a274fa32ebe43af125caf041f7cc4cbf
react-native-video: c26780b224543c62d5e1b2a7244a5cd1b50e8253
react-native-webrtc: 86d841823e66d68cc1f86712db1c2956056bf0c2
react-native-webview: 994b9f8fbb504d6314dc40d83f94f27c6831b3bf
- React-perflogger: 8c79399b0500a30ee8152d0f9f11beae7fc36595
- React-RCTActionSheet: 7316773acabb374642b926c19aef1c115df5c466
- React-RCTAnimation: 5341e288375451297057391227f691d9b2326c3d
- React-RCTBlob: b0615fc2daf2b5684ade8fadcab659f16f6f0efa
- React-RCTImage: 6487b9600f268ecedcaa86114d97954d31ad4750
- React-RCTLinking: c8018ae9ebfefcec3839d690d4725f8d15e4e4b3
- React-RCTNetwork: 8aa63578741e0fe1205c28d7d4b40dbfdabce8a8
- React-RCTSettings: d00c15ad369cd62242a4dfcc6f277912b4a84ed3
- React-RCTText: f532e5ca52681ecaecea452b3ad7a5b630f50d75
- React-RCTVibration: c75ceef7aa60a33b2d5731ebe5800ddde40cefc4
- React-runtimeexecutor: 15437b576139df27635400de0599d9844f1ab817
- ReactCommon: 349be31adeecffc7986a0de875d7fb0dcf4e251c
+ React-perflogger: ec8eef2a8f03ecfa6361c2c5fb9197ef4a29cc85
+ React-RCTActionSheet: a0c023b86cf4c862fa9c4eb0f6f91fbe878fb2de
+ React-RCTAnimation: 168d53718c74153947c0109f55900faa64d79439
+ React-RCTAppDelegate: a8efbab128b34aa07a9491c85a41401210b1bec5
+ React-RCTBlob: 9bcbfc893bfda9f6b2eb016329d38c0f6366d31a
+ React-RCTImage: 3fcd4570b4b0f1ac2f4b4b6308dba33ce66c5b50
+ React-RCTLinking: 1edb8e1bb3fc39bf9e13c63d6aaaa3f0c3d18683
+ React-RCTNetwork: 500a79e0e0f67678077df727fabba87a55c043e1
+ React-RCTSettings: cc4414eb84ad756d619076c3999fecbf12896d6f
+ React-RCTText: 2a34261f3da6e34f47a62154def657546ebfa5e1
+ React-RCTVibration: 49d531ec8498e0afa2c9b22c2205784372e3d4f3
+ React-runtimeexecutor: 311feb67600774723fe10eb8801d3138cae9ad67
+ ReactCommon: 03be76588338a27a88d103b35c3c44a3fd43d136
ReactNativeExceptionHandler: b11ff67c78802b2f62eed0e10e75cb1ef7947c60
ReactNativeIncallManager: b169b57d3064d8f62478f8fc3c485da6c75045d1
ReactNativeKeyboardTrackingView: 02137fac3b2ebd330d74fa54ead48b14750a2306
- ReactNativeNavigation: 44df9a6347dc583deac3a09b171e2e1b4905a9d6
+ ReactNativeNavigation: c3e1e813b46d4c7219949cfbb67feb90b8315058
RNCClipboard: 2834e1c4af68697089cdd455ee4a4cdd198fa7dd
- RNDateTimePicker: 0530a73a6f3a1a85814cbde0802736993b9e675e
+ RNDateTimePicker: 00247f26c34683c80be94207f488f6f13448586e
RNDeviceInfo: 4701f0bf2a06b34654745053db0ce4cb0c53ada7
RNFastImage: 0ee8f7e39df8190d3ca3a5b0c4ea0109c0ff132e
RNFileViewer: ce7ca3ac370e18554d35d6355cffd7c30437c592
RNFS: 4ac0f0ea233904cb798630b3c077808c06931688
- RNGestureHandler: 62232ba8f562f7dea5ba1b3383494eb5bf97a4d3
+ RNGestureHandler: 071d7a9ad81e8b83fe7663b303d132406a7d8f39
RNKeychain: ff836453cba46938e0e9e4c22e43d43fa2c90333
RNLocalize: 0df7970cfc60389f00eb62fd7c097dc75af3fb4f
RNPermissions: dcdb7b99796bbeda6975a6e79ad519c41b251b1c
RNReactNativeHapticFeedback: 1e3efeca9628ff9876ee7cdd9edec1b336913f8c
- RNReanimated: ce445c233a6ff5600223484a88ad5704945d972a
- RNRudderSdk: 14c176adb1557f3832cb385fcd14250f76a7e268
- RNScreens: 34cc502acf1b916c582c60003dc3089fa01dc66d
- RNSentry: 4c09f4dd9740cb9b33e94303de5b6d0dbeb0737d
+ RNReanimated: cc5e3aa479cb9170bcccf8204291a6950a3be128
+ RNRudderSdk: 07f732edfe473ef67b8cc6ad1800ddb81b78286f
+ RNScreens: ea4cd3a853063cda19a4e3c28d2e52180c80f4eb
+ RNSentry: acebe4104a6f5915ae871eb59dc73f13dcc92ef7
RNShare: 48b3113cd089a2be8ff0515c3ae7a46a4db8a76b
- RNSVG: 3a79c0c4992213e4f06c08e62730c5e7b9e4dc17
+ RNSVG: d787d64ca06b9158e763ad2638a8c4edce00782a
RNVectorIcons: fcc2f6cb32f5735b586e66d14103a74ce6ad61f8
Rudder: 7c080303528ea612f58c9f9e8fcfab92b5dbcca8
SDWebImage: a47aea9e3d8816015db4e523daff50cfd294499d
SDWebImageWebPCoder: 908b83b6adda48effe7667cd2b7f78c897e5111d
- Sentry: 08884c523575ec0f6690d94ed3ccb0246a1600bf
+ Sentry: 4c9babff9034785067c896fd580b1f7de44da020
simdjson: c96317b3a50dff3468a42f586ab7ed22c6ab2fd9
SocketRocket: fccef3f9c5cedea1353a9ef6ada904fde10d6608
Starscream: 5178aed56b316f13fa3bc55694e583d35dd414d9
SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e
Swime: d7b2c277503b6cea317774aedc2dce05613f8b0b
- WatermelonDB: baec390a1039dcebeee959218900c978af3407c9
- Yoga: 99caf8d5ab45e9d637ee6e0174ec16fbbb01bcfc
+ WatermelonDB: cce0b748ccbd7a71c161e8545b5f6357a0945be1
+ Yoga: 921eb014669cf9c718ada68b08d362517d564e0c
YogaKit: f782866e155069a2cca2517aafea43200b01fd5a
-PODFILE CHECKSUM: 96049f4170c9cafd0ff121db4444b3f46f51bc97
+PODFILE CHECKSUM: 9f76739ed16bbdc0f4b1049ecb366fb5d23a0f3a
COCOAPODS: 1.11.3
diff --git a/package-lock.json b/package-lock.json
index 91620ba23c..96813a4582 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -18,24 +18,24 @@
"@formatjs/intl-relativetimeformat": "11.1.8",
"@gorhom/bottom-sheet": "4.4.5",
"@mattermost/compass-icons": "0.1.35",
- "@mattermost/react-native-emm": "1.3.3",
- "@mattermost/react-native-network-client": "1.0.2",
- "@mattermost/react-native-paste-input": "0.5.2",
- "@mattermost/react-native-turbo-log": "0.2.1",
- "@mattermost/react-native-turbo-mailer": "0.2.0",
+ "@mattermost/react-native-emm": "1.3.4",
+ "@mattermost/react-native-network-client": "1.1.0",
+ "@mattermost/react-native-paste-input": "0.6.0",
+ "@mattermost/react-native-turbo-log": "0.2.2",
+ "@mattermost/react-native-turbo-mailer": "0.2.3",
"@msgpack/msgpack": "2.8.0",
- "@nozbe/watermelondb": "0.24.0",
+ "@nozbe/watermelondb": "0.25.1",
"@nozbe/with-observables": "1.4.1",
- "@react-native-camera-roll/camera-roll": "5.2.1",
+ "@react-native-camera-roll/camera-roll": "5.2.2",
"@react-native-clipboard/clipboard": "1.11.1",
- "@react-native-community/datetimepicker": "6.7.1",
+ "@react-native-community/datetimepicker": "6.7.3",
"@react-native-community/netinfo": "9.3.7",
"@react-native-cookies/cookies": "6.2.1",
- "@react-navigation/bottom-tabs": "6.5.2",
- "@react-navigation/native": "6.1.1",
- "@react-navigation/stack": "6.3.10",
- "@rudderstack/rudder-sdk-react-native": "1.5.1",
- "@sentry/react-native": "4.12.0",
+ "@react-navigation/bottom-tabs": "6.5.3",
+ "@react-navigation/native": "6.1.2",
+ "@react-navigation/stack": "6.3.11",
+ "@rudderstack/rudder-sdk-react-native": "1.5.2",
+ "@sentry/react-native": "4.13.0",
"@stream-io/flat-list-mvcp": "0.10.2",
"base-64": "1.0.0",
"commonmark": "npm:@mattermost/commonmark@0.30.1-0",
@@ -52,7 +52,7 @@
"react": "18.2.0",
"react-freeze": "1.0.3",
"react-intl": "6.2.5",
- "react-native": "0.70.6",
+ "react-native": "0.71.1",
"react-native-android-open-settings": "1.3.0",
"react-native-animated-numbers": "0.4.1",
"react-native-background-timer": "2.4.1",
@@ -67,10 +67,10 @@
"react-native-fast-image": "8.6.3",
"react-native-file-viewer": "2.1.5",
"react-native-fs": "2.20.0",
- "react-native-gesture-handler": "2.8.0",
+ "react-native-gesture-handler": "2.9.0",
"react-native-haptic-feedback": "1.14.0",
"react-native-hw-keyboard-event": "0.0.4",
- "react-native-image-picker": "4.10.3",
+ "react-native-image-picker": "5.0.1",
"react-native-in-app-review": "4.2.1",
"react-native-incall-manager": "github:cpoile/react-native-incall-manager",
"react-native-keyboard-aware-scroll-view": "0.9.5",
@@ -79,19 +79,19 @@
"react-native-linear-gradient": "2.6.2",
"react-native-localize": "2.2.4",
"react-native-math-view": "3.9.5",
- "react-native-navigation": "7.30.6",
+ "react-native-navigation": "7.31.1",
"react-native-notifications": "4.3.3",
"react-native-permissions": "3.6.1",
- "react-native-reanimated": "2.13.0",
- "react-native-safe-area-context": "4.4.1",
- "react-native-screens": "3.18.2",
+ "react-native-reanimated": "2.14.4",
+ "react-native-safe-area-context": "4.5.0",
+ "react-native-screens": "3.19.0",
"react-native-section-list-get-item-layout": "2.2.3",
"react-native-shadow-2": "7.0.6",
"react-native-share": "8.1.0",
- "react-native-svg": "13.6.0",
+ "react-native-svg": "13.7.0",
"react-native-vector-icons": "9.2.0",
"react-native-video": "5.2.1",
- "react-native-walkthrough-tooltip": "1.4.0",
+ "react-native-walkthrough-tooltip": "1.5.0",
"react-native-webrtc": "github:mattermost/react-native-webrtc",
"react-native-webview": "11.26.0",
"react-syntax-highlighter": "15.5.0",
@@ -107,13 +107,13 @@
"@babel/core": "7.20.12",
"@babel/eslint-parser": "7.19.1",
"@babel/plugin-proposal-class-properties": "7.18.6",
- "@babel/plugin-proposal-decorators": "7.20.7",
+ "@babel/plugin-proposal-decorators": "7.20.13",
"@babel/plugin-transform-flow-strip-types": "7.19.0",
"@babel/plugin-transform-runtime": "7.19.6",
"@babel/preset-env": "7.20.2",
"@babel/preset-typescript": "7.18.6",
"@babel/register": "7.18.9",
- "@babel/runtime": "7.20.7",
+ "@babel/runtime": "7.20.13",
"@react-native-community/eslint-config": "3.2.0",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/react-native": "11.5.0",
@@ -121,12 +121,11 @@
"@types/commonmark": "0.27.5",
"@types/commonmark-react-renderer": "4.3.1",
"@types/deep-equal": "1.0.1",
- "@types/jest": "29.2.5",
+ "@types/jest": "29.2.6",
"@types/lodash": "4.14.191",
"@types/mime-db": "1.43.1",
"@types/querystringify": "2.0.0",
- "@types/react": "18.0.26",
- "@types/react-native": "0.70.8",
+ "@types/react": "18.0.27",
"@types/react-native-background-timer": "2.0.0",
"@types/react-native-button": "3.0.1",
"@types/react-native-dotenv": "0.2.0",
@@ -141,36 +140,36 @@
"@types/tough-cookie": "4.0.2",
"@types/url-parse": "1.4.8",
"@types/uuid": "9.0.0",
- "@typescript-eslint/eslint-plugin": "5.48.0",
- "@typescript-eslint/parser": "5.48.0",
- "axios": "1.2.2",
+ "@typescript-eslint/eslint-plugin": "5.49.0",
+ "@typescript-eslint/parser": "5.49.0",
+ "axios": "1.2.3",
"axios-cookiejar-support": "4.0.6",
"babel-jest": "29.3.1",
"babel-loader": "9.1.2",
- "babel-plugin-module-resolver": "4.1.0",
+ "babel-plugin-module-resolver": "5.0.0",
"deep-freeze": "0.0.1",
- "detox": "20.1.1",
- "eslint": "8.31.0",
+ "detox": "20.1.2",
+ "eslint": "8.32.0",
"eslint-plugin-header": "3.1.1",
- "eslint-plugin-import": "2.26.0",
+ "eslint-plugin-import": "2.27.5",
"eslint-plugin-jest": "27.2.1",
- "eslint-plugin-react": "7.31.11",
+ "eslint-plugin-react": "7.32.1",
"eslint-plugin-react-hooks": "4.6.0",
"husky": "8.0.3",
"isomorphic-fetch": "3.0.0",
"jest": "29.3.1",
"jest-cli": "29.3.1",
"jetifier": "2.0.0",
- "metro-react-native-babel-preset": "0.73.7",
+ "metro-react-native-babel-preset": "0.74.1",
"mmjstool": "github:mattermost/mattermost-utilities#010f456ea8be5beebafdb8776177cba515c1969e",
"mock-async-storage": "2.2.0",
- "nock": "13.2.9",
+ "nock": "13.3.0",
"patch-package": "6.5.1",
"react-devtools-core": "4.27.1",
"react-native-svg-transformer": "1.0.0",
"react-test-renderer": "18.2.0",
"tough-cookie": "4.1.2",
- "ts-jest": "29.0.3",
+ "ts-jest": "29.0.5",
"typescript": "4.9.4",
"underscore": "1.13.6",
"util": "0.12.5",
@@ -376,9 +375,9 @@
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="
},
"node_modules/@babel/helper-create-class-features-plugin": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.7.tgz",
- "integrity": "sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w==",
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
+ "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.18.6",
"@babel/helper-environment-visitor": "^7.18.9",
@@ -386,6 +385,7 @@
"@babel/helper-member-expression-to-functions": "^7.20.7",
"@babel/helper-optimise-call-expression": "^7.18.6",
"@babel/helper-replace-supers": "^7.20.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
"@babel/helper-split-export-declaration": "^7.18.6"
},
"engines": {
@@ -580,11 +580,11 @@
}
},
"node_modules/@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz",
- "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==",
+ "version": "7.20.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
+ "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
"dependencies": {
- "@babel/types": "^7.18.9"
+ "@babel/types": "^7.20.0"
},
"engines": {
"node": ">=6.9.0"
@@ -755,12 +755,12 @@
}
},
"node_modules/@babel/plugin-proposal-decorators": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.7.tgz",
- "integrity": "sha512-JB45hbUweYpwAGjkiM7uCyXMENH2lG+9r3G2E+ttc2PRXAoEkpfd/KW5jDg4j8RS6tLtTG1jZi9LbHZVSfs1/A==",
+ "version": "7.20.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz",
+ "integrity": "sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw==",
"dev": true,
"dependencies": {
- "@babel/helper-create-class-features-plugin": "^7.20.7",
+ "@babel/helper-create-class-features-plugin": "^7.20.12",
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/helper-replace-supers": "^7.20.7",
"@babel/helper-split-export-declaration": "^7.18.6",
@@ -2044,9 +2044,9 @@
}
},
"node_modules/@babel/runtime": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz",
- "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==",
+ "version": "7.20.13",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
+ "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
"dependencies": {
"regenerator-runtime": "^0.13.11"
},
@@ -2686,108 +2686,20 @@
}
},
"node_modules/@jest/create-cache-key-function": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz",
- "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==",
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.3.1.tgz",
+ "integrity": "sha512-4i+E+E40gK13K78ffD/8cy4lSSqeWwyXeTZoq16tndiCP12hC8uQsPJdIu5C6Kf22fD8UbBk71so7s/6VwpUOQ==",
"dependencies": {
- "@jest/types": "^27.5.1"
+ "@jest/types": "^29.3.1"
},
"engines": {
- "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
- }
- },
- "node_modules/@jest/create-cache-key-function/node_modules/@jest/types": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
- "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
- "dependencies": {
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^16.0.0",
- "chalk": "^4.0.0"
- },
- "engines": {
- "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0"
- }
- },
- "node_modules/@jest/create-cache-key-function/node_modules/@types/yargs": {
- "version": "16.0.4",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
- "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
- "dependencies": {
- "@types/yargs-parser": "*"
- }
- },
- "node_modules/@jest/create-cache-key-function/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/@jest/create-cache-key-function/node_modules/chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dependencies": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/chalk?sponsor=1"
- }
- },
- "node_modules/@jest/create-cache-key-function/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/@jest/create-cache-key-function/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "node_modules/@jest/create-cache-key-function/node_modules/has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/@jest/create-cache-key-function/node_modules/supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dependencies": {
- "has-flag": "^4.0.0"
- },
- "engines": {
- "node": ">=8"
+ "node": "^14.15.0 || ^16.10.0 || >=18.0.0"
}
},
"node_modules/@jest/environment": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz",
"integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==",
- "dev": true,
"dependencies": {
"@jest/fake-timers": "^29.3.1",
"@jest/types": "^29.3.1",
@@ -2827,7 +2739,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz",
"integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==",
- "dev": true,
"dependencies": {
"@jest/types": "^29.3.1",
"@sinonjs/fake-timers": "^9.1.2",
@@ -2981,7 +2892,6 @@
"version": "29.0.0",
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
"integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
- "dev": true,
"dependencies": {
"@sinclair/typebox": "^0.24.1"
},
@@ -3157,7 +3067,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
"integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
- "dev": true,
"dependencies": {
"@jest/schemas": "^29.0.0",
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -3174,7 +3083,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
@@ -3189,7 +3097,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -3205,7 +3112,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
@@ -3216,14 +3122,12 @@
"node_modules/@jest/types/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@jest/types/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -3232,7 +3136,6 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -3273,8 +3176,6 @@
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
- "dev": true,
- "peer": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
@@ -3331,21 +3232,21 @@
"integrity": "sha512-qCZjvU6Vsl7cg/0urrq8ItK5CXnt3DqjFq/w9mBpWuem/YhMWLMVBoSuASAx9S2HV7Vr/iMdsMGWH/4qXkXCBg=="
},
"node_modules/@mattermost/react-native-emm": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-emm/-/react-native-emm-1.3.3.tgz",
- "integrity": "sha512-mOPlp3C0ba1XOANTYi3i2dL9gBdQLoJZ4zvOzhqYeg5FQXBXXoJomPKAzxJH27aX3k92bu+U0BmEbnKIitKKEA==",
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-emm/-/react-native-emm-1.3.4.tgz",
+ "integrity": "sha512-xdFPfAH3d9pa1og6rr+kHCWlLYMnHe7kY1IxIjhvfZ28ElNExjOhOF7JOL/s4RUvk8bZS7H72+ldRYZ6ERHlWw==",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/@mattermost/react-native-network-client": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.0.2.tgz",
- "integrity": "sha512-ywVxTKPT1A8eEccPpCrHXYqO9BvvEx+xdecn/VILUDeEIfpOVETLh5952SQjoc3PP0RRME0bv92+fzoxiOZ4YQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.1.0.tgz",
+ "integrity": "sha512-iZemjWqUaGkfSY+7Ve+m6MUJc8blUOzHoY9J5miKjez7QPiknYGMIdVFMYAiuO9jUtgQ4XSG7/nENqYR5jSwCg==",
"dependencies": {
"validator": "13.7.0",
- "zod": "3.19.1"
+ "zod": "3.20.2"
},
"peerDependencies": {
"react": "*",
@@ -3353,11 +3254,11 @@
}
},
"node_modules/@mattermost/react-native-paste-input": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-paste-input/-/react-native-paste-input-0.5.2.tgz",
- "integrity": "sha512-aQdLUidSAbWPLXWmwM1x8AhnZIO4EN5uWx813/G3+mL8kWD7mpXrQEvMpcdtKWatD705kCyKZkvnNY4yjq0TkA==",
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-paste-input/-/react-native-paste-input-0.6.0.tgz",
+ "integrity": "sha512-Hy4w8RaiiXl2AKcLXT0FjJJsh4FXtLiWCxfh6zaBtCkx7jsr4d9xwJ/zqrnjv0jkG7XbRUCp40dgNBpWYZ1pyQ==",
"dependencies": {
- "deprecated-react-native-prop-types": "^2.3.0"
+ "semver": "7.3.8"
},
"peerDependencies": {
"react": "*",
@@ -3365,18 +3266,18 @@
}
},
"node_modules/@mattermost/react-native-turbo-log": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-log/-/react-native-turbo-log-0.2.1.tgz",
- "integrity": "sha512-c5Wx82gYLEUY70lIoA3jWg2sWo+l/Ah8vAfvu2cYkGnX4NArB/NKWnC4GWaclDSuNO4Tm5DrXgFeSqqArs7IJQ==",
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-log/-/react-native-turbo-log-0.2.2.tgz",
+ "integrity": "sha512-UjatbzMyB3jp/tAI1B8lmqZtF8om103hzUAlRVnUIPvzDQl5u2OtiwkwdYlnyN1P72WiIKhNcx7W+NZO0/wjyg==",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/@mattermost/react-native-turbo-mailer": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-mailer/-/react-native-turbo-mailer-0.2.0.tgz",
- "integrity": "sha512-KMrEkMa30zjFv8ofvQsE1c1ln+8ntGDKJWDjScK02jvN3rtD8jMz1derz1py8tbDU9uU2nQPqWu4lP4b3g27Tw==",
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-mailer/-/react-native-turbo-mailer-0.2.3.tgz",
+ "integrity": "sha512-m49wYLOx6TCiv5IDZKNAzhY8hnib+CgZ31jenR5rMiEmykmnI4VIyan1nNcPTyZPRGGmBb4UYzrcPd3hdIaOSg==",
"engines": {
"node": ">= 16.0.0"
},
@@ -3455,33 +3356,20 @@
"integrity": "sha512-wKTFGvgf5V+bYlhXdukOWKH0XgdG0NmUQwLWG7w5Yk4EUeQS29D5uWPCeWT1Ac/NzDKuHsYP6KVOJDbJSauAAg=="
},
"node_modules/@nozbe/watermelondb": {
- "version": "0.24.0",
- "resolved": "https://registry.npmjs.org/@nozbe/watermelondb/-/watermelondb-0.24.0.tgz",
- "integrity": "sha512-CPCsRLQY2Lyq1MwUeK6zDsjfMKpW2KWYQJlF+ijGeKWv84xND0QC6a6EBWWiflvcdAwLSuGclojoah1HZYfs0g==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@nozbe/watermelondb/-/watermelondb-0.25.1.tgz",
+ "integrity": "sha512-Yd4gXttVlfl2e8rDsduTmPWgZWidaVAMpDcJr1fmsmHJQnNWdYRR+1V07Io4muNMSSq7rdn0Yl8GHNpNzN+rfQ==",
"dependencies": {
"@babel/runtime": "^7.11.2",
"@nozbe/simdjson": "1.0.0",
"@nozbe/sqlite": "3.36.0",
- "@nozbe/with-observables": "1.4.0",
+ "@nozbe/with-observables": "1.4.1",
"hoist-non-react-statics": "^3.3.2",
- "lokijs": "npm:@nozbe/lokijs@1.5.12-wmelon4",
- "rxjs": "^7.3.0",
+ "lokijs": "npm:@nozbe/lokijs@1.5.12-wmelon6",
+ "rxjs": "^7.4.0",
"sql-escape-string": "^1.1.0"
}
},
- "node_modules/@nozbe/watermelondb/node_modules/@nozbe/with-observables": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@nozbe/with-observables/-/with-observables-1.4.0.tgz",
- "integrity": "sha512-vzc0QiYcXK/GmflBGBXTs02ayL25e1l4Cr9aYgSuYCZVqpyMfep9xp89RygNbiibAfVLbgEUa7thxlm3jw8hFw==",
- "dependencies": {
- "hoist-non-react-statics": "^3.3.2"
- },
- "peerDependencies": {
- "@types/hoist-non-react-statics": "^3.3.1",
- "@types/react": "^16.9.23||^17",
- "react": "^16.4.2||^17"
- }
- },
"node_modules/@nozbe/with-observables": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/@nozbe/with-observables/-/with-observables-1.4.1.tgz",
@@ -3496,9 +3384,9 @@
}
},
"node_modules/@react-native-camera-roll/camera-roll": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-camera-roll/camera-roll/-/camera-roll-5.2.1.tgz",
- "integrity": "sha512-axWwlLj/3E5PIjXcN2y2XZzK/hYTx73kDlQJpHpcurejmQR9sU22w3cs+YltaNkZGl3y7Eu/LbiPEkGIwNVQow==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@react-native-camera-roll/camera-roll/-/camera-roll-5.2.2.tgz",
+ "integrity": "sha512-LVzUX1KdKvOXJGiV/9tlkDyDSOEjvAzuiV8OkSUD13TXN/Tk5u2KVHTYRYJz5pmXanLN2dmEamctJcqKCeXYxg==",
"peerDependencies": {
"react-native": ">=0.59"
}
@@ -3513,21 +3401,21 @@
}
},
"node_modules/@react-native-community/cli": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-9.3.2.tgz",
- "integrity": "sha512-IAW4X0vmX/xozNpp/JVZaX7MrC85KV0OP2DF4o7lNGOfpUhzJAEWqTfkxFYS+VsRjZHDve4wSTiGIuXwE7FG1w==",
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.1.3.tgz",
+ "integrity": "sha512-kzh6bYLGN1q1q0IiczKSP1LTrovFeVzppYRTKohPI9VdyZwp7b5JOgaQMB/Ijtwm3MxBDrZgV9AveH/eUmUcKQ==",
"dependencies": {
- "@react-native-community/cli-clean": "^9.2.1",
- "@react-native-community/cli-config": "^9.2.1",
- "@react-native-community/cli-debugger-ui": "^9.0.0",
- "@react-native-community/cli-doctor": "^9.3.0",
- "@react-native-community/cli-hermes": "^9.3.1",
- "@react-native-community/cli-plugin-metro": "^9.2.1",
- "@react-native-community/cli-server-api": "^9.2.1",
- "@react-native-community/cli-tools": "^9.2.1",
- "@react-native-community/cli-types": "^9.1.0",
+ "@react-native-community/cli-clean": "^10.1.1",
+ "@react-native-community/cli-config": "^10.1.1",
+ "@react-native-community/cli-debugger-ui": "^10.0.0",
+ "@react-native-community/cli-doctor": "^10.1.1",
+ "@react-native-community/cli-hermes": "^10.1.3",
+ "@react-native-community/cli-plugin-metro": "^10.1.1",
+ "@react-native-community/cli-server-api": "^10.1.1",
+ "@react-native-community/cli-tools": "^10.1.1",
+ "@react-native-community/cli-types": "^10.0.0",
"chalk": "^4.1.2",
- "commander": "^9.4.0",
+ "commander": "^9.4.1",
"execa": "^1.0.0",
"find-up": "^4.1.0",
"fs-extra": "^8.1.0",
@@ -3543,11 +3431,11 @@
}
},
"node_modules/@react-native-community/cli-clean": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-9.2.1.tgz",
- "integrity": "sha512-dyNWFrqRe31UEvNO+OFWmQ4hmqA07bR9Ief/6NnGwx67IO9q83D5PEAf/o96ML6jhSbDwCmpPKhPwwBbsyM3mQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-10.1.1.tgz",
+ "integrity": "sha512-iNsrjzjIRv9yb5y309SWJ8NDHdwYtnCpmxZouQDyOljUdC9MwdZ4ChbtA4rwQyAwgOVfS9F/j56ML3Cslmvrxg==",
"dependencies": {
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"execa": "^1.0.0",
"prompts": "^2.4.0"
@@ -3696,17 +3584,63 @@
}
},
"node_modules/@react-native-community/cli-config": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-9.2.1.tgz",
- "integrity": "sha512-gHJlBBXUgDN9vrr3aWkRqnYrPXZLztBDQoY97Mm5Yo6MidsEpYo2JIP6FH4N/N2p1TdjxJL4EFtdd/mBpiR2MQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-10.1.1.tgz",
+ "integrity": "sha512-p4mHrjC+s/ayiNVG6T35GdEGdP6TuyBUg5plVGRJfTl8WT6LBfLYLk+fz/iETrEZ/YkhQIsQcEUQC47MqLNHog==",
"dependencies": {
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-tools": "^10.1.1",
+ "chalk": "^4.1.2",
"cosmiconfig": "^5.1.0",
"deepmerge": "^3.2.0",
"glob": "^7.1.3",
"joi": "^17.2.1"
}
},
+ "node_modules/@react-native-community/cli-config/node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@react-native-community/cli-config/node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@react-native-community/cli-config/node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/@react-native-community/cli-config/node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
"node_modules/@react-native-community/cli-config/node_modules/deepmerge": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz",
@@ -3715,22 +3649,41 @@
"node": ">=0.10.0"
}
},
+ "node_modules/@react-native-community/cli-config/node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@react-native-community/cli-config/node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
"node_modules/@react-native-community/cli-debugger-ui": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-9.0.0.tgz",
- "integrity": "sha512-7hH05ZwU9Tp0yS6xJW0bqcZPVt0YCK7gwj7gnRu1jDNN2kughf6Lg0Ys29rAvtZ7VO1PK5c1O+zs7yFnylQDUA==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-10.0.0.tgz",
+ "integrity": "sha512-8UKLcvpSNxnUTRy8CkCl27GGLqZunQ9ncGYhSrWyKrU9SWBJJGeZwi2k2KaoJi5FvF2+cD0t8z8cU6lsq2ZZmA==",
"dependencies": {
"serve-static": "^1.13.1"
}
},
"node_modules/@react-native-community/cli-doctor": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-9.3.0.tgz",
- "integrity": "sha512-/fiuG2eDGC2/OrXMOWI5ifq4X1gdYTQhvW2m0TT5Lk1LuFiZsbTCp1lR+XILKekuTvmYNjEGdVpeDpdIWlXdEA==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-10.1.1.tgz",
+ "integrity": "sha512-9uvUhr6aJu4C7pCTsD9iRS/38tx1mzIrWuEQoh2JffTXg9MOq4jesvobkyKFRD90nOvqunEvfpnWnRdWcZO0Wg==",
"dependencies": {
- "@react-native-community/cli-config": "^9.2.1",
- "@react-native-community/cli-platform-ios": "^9.3.0",
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-config": "^10.1.1",
+ "@react-native-community/cli-platform-ios": "^10.1.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"command-exists": "^1.2.8",
"envinfo": "^7.7.2",
@@ -3916,12 +3869,12 @@
}
},
"node_modules/@react-native-community/cli-hermes": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-9.3.1.tgz",
- "integrity": "sha512-Mq4PK8m5YqIdaVq5IdRfp4qK09aVO+aiCtd6vjzjNUgk1+1X5cgUqV6L65h4N+TFJYJHcp2AnB+ik1FAYXvYPQ==",
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-10.1.3.tgz",
+ "integrity": "sha512-uYl8MLBtuu6bj0tDUzVGf30nK5i9haBv7F0u+NCOq31+zVjcwiUplrCuLorb2dMLMF+Fno9wDxi66W9MxoW4nA==",
"dependencies": {
- "@react-native-community/cli-platform-android": "^9.3.1",
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-platform-android": "^10.1.3",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"hermes-profile-transformer": "^0.0.6",
"ip": "^1.1.5"
@@ -3992,17 +3945,15 @@
}
},
"node_modules/@react-native-community/cli-platform-android": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-9.3.1.tgz",
- "integrity": "sha512-m0bQ6Twewl7OEZoVf79I2GZmsDqh+Gh0bxfxWgwxobsKDxLx8/RNItAo1lVtTCgzuCR75cX4EEO8idIF9jYhew==",
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-10.1.3.tgz",
+ "integrity": "sha512-8YZEpBL6yd9l4CIoFcLOgrV8x2GDujdqrdWrNsNERDAbsiFwqAQvfjyyb57GAZVuEPEJCoqUlGlMCwOh3XQb9A==",
"dependencies": {
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"execa": "^1.0.0",
- "fs-extra": "^8.1.0",
"glob": "^7.1.3",
- "logkitty": "^0.7.1",
- "slash": "^3.0.0"
+ "logkitty": "^0.7.1"
}
},
"node_modules/@react-native-community/cli-platform-android/node_modules/ansi-styles": {
@@ -4082,19 +4033,6 @@
"node": ">=6"
}
},
- "node_modules/@react-native-community/cli-platform-android/node_modules/fs-extra": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
- "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- },
- "engines": {
- "node": ">=6 <7 || >=8"
- }
- },
"node_modules/@react-native-community/cli-platform-android/node_modules/get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -4149,14 +4087,6 @@
"semver": "bin/semver"
}
},
- "node_modules/@react-native-community/cli-platform-android/node_modules/slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/@react-native-community/cli-platform-android/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -4169,11 +4099,11 @@
}
},
"node_modules/@react-native-community/cli-platform-ios": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-9.3.0.tgz",
- "integrity": "sha512-nihTX53BhF2Q8p4B67oG3RGe1XwggoGBrMb6vXdcu2aN0WeXJOXdBLgR900DAA1O8g7oy1Sudu6we+JsVTKnjw==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.1.1.tgz",
+ "integrity": "sha512-EB9/L8j1LqrqyfJtLRixU+d8FIP6Pr83rEgUgXgya/u8wk3h/bvX70w+Ff2skwjdPLr5dLUQ/n5KFX4r3bsNmA==",
"dependencies": {
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"execa": "^1.0.0",
"glob": "^7.1.3",
@@ -4323,19 +4253,20 @@
}
},
"node_modules/@react-native-community/cli-plugin-metro": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-9.2.1.tgz",
- "integrity": "sha512-byBGBH6jDfUvcHGFA45W/sDwMlliv7flJ8Ns9foCh3VsIeYYPoDjjK7SawE9cPqRdMAD4SY7EVwqJnOtRbwLiQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.1.1.tgz",
+ "integrity": "sha512-wEp47le4mzlelDF5sfkaaujUDYcuLep5HZqlcMx7PkL7BA3/fSHdDo1SblqaLgZ1ca6vFU+kfbHueLDct+xwFg==",
"dependencies": {
- "@react-native-community/cli-server-api": "^9.2.1",
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-server-api": "^10.1.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
- "metro": "0.72.3",
- "metro-config": "0.72.3",
- "metro-core": "0.72.3",
- "metro-react-native-babel-transformer": "0.72.3",
- "metro-resolver": "0.72.3",
- "metro-runtime": "0.72.3",
+ "execa": "^1.0.0",
+ "metro": "0.73.7",
+ "metro-config": "0.73.7",
+ "metro-core": "0.73.7",
+ "metro-react-native-babel-transformer": "0.73.7",
+ "metro-resolver": "0.73.7",
+ "metro-runtime": "0.73.7",
"readline": "^1.3.0"
}
},
@@ -4384,6 +4315,49 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "node_modules/@react-native-community/cli-plugin-metro/node_modules/cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dependencies": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ },
+ "engines": {
+ "node": ">=4.8"
+ }
+ },
+ "node_modules/@react-native-community/cli-plugin-metro/node_modules/execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dependencies": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/@react-native-community/cli-plugin-metro/node_modules/get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dependencies": {
+ "pump": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
"node_modules/@react-native-community/cli-plugin-metro/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -4392,6 +4366,41 @@
"node": ">=8"
}
},
+ "node_modules/@react-native-community/cli-plugin-metro/node_modules/is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/@react-native-community/cli-plugin-metro/node_modules/npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "dependencies": {
+ "path-key": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@react-native-community/cli-plugin-metro/node_modules/path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/@react-native-community/cli-plugin-metro/node_modules/semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "bin": {
+ "semver": "bin/semver"
+ }
+ },
"node_modules/@react-native-community/cli-plugin-metro/node_modules/supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -4404,12 +4413,12 @@
}
},
"node_modules/@react-native-community/cli-server-api": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-9.2.1.tgz",
- "integrity": "sha512-EI+9MUxEbWBQhWw2PkhejXfkcRqPl+58+whlXJvKHiiUd7oVbewFs0uLW0yZffUutt4FGx6Uh88JWEgwOzAdkw==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-10.1.1.tgz",
+ "integrity": "sha512-NZDo/wh4zlm8as31UEBno2bui8+ufzsZV+KN7QjEJWEM0levzBtxaD+4je0OpfhRIIkhaRm2gl/vVf7OYAzg4g==",
"dependencies": {
- "@react-native-community/cli-debugger-ui": "^9.0.0",
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-debugger-ui": "^10.0.0",
+ "@react-native-community/cli-tools": "^10.1.1",
"compression": "^1.7.1",
"connect": "^3.6.5",
"errorhandler": "^1.5.0",
@@ -4435,9 +4444,9 @@
}
},
"node_modules/@react-native-community/cli-server-api/node_modules/@types/yargs": {
- "version": "15.0.14",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
- "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
+ "version": "15.0.15",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz",
+ "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==",
"dependencies": {
"@types/yargs-parser": "*"
}
@@ -4526,9 +4535,9 @@
}
},
"node_modules/@react-native-community/cli-tools": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-9.2.1.tgz",
- "integrity": "sha512-bHmL/wrKmBphz25eMtoJQgwwmeCylbPxqFJnFSbkqJPXQz3ManQ6q/gVVMqFyz7D3v+riaus/VXz3sEDa97uiQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-10.1.1.tgz",
+ "integrity": "sha512-+FlwOnZBV+ailEzXjcD8afY2ogFEBeHOw/8+XXzMgPaquU2Zly9B+8W089tnnohO3yfiQiZqkQlElP423MY74g==",
"dependencies": {
"appdirsjs": "^1.2.4",
"chalk": "^4.1.2",
@@ -4698,9 +4707,9 @@
}
},
"node_modules/@react-native-community/cli-types": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-9.1.0.tgz",
- "integrity": "sha512-KDybF9XHvafLEILsbiKwz5Iobd+gxRaPyn4zSaAerBxedug4er5VUWa8Szy+2GeYKZzMh/gsb1o9lCToUwdT/g==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-10.0.0.tgz",
+ "integrity": "sha512-31oUM6/rFBZQfSmDQsT1DX/5fjqfxg7sf2u8kTPJK7rXVya5SRpAMaCXsPAG0omsmJxXt+J9HxUi3Ic+5Ux5Iw==",
"dependencies": {
"joi": "^17.2.1"
}
@@ -4751,9 +4760,9 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-native-community/cli/node_modules/commander": {
- "version": "9.4.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz",
- "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==",
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
+ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ==",
"engines": {
"node": "^12.20.0 || >=14"
}
@@ -4877,9 +4886,9 @@
}
},
"node_modules/@react-native-community/datetimepicker": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-6.7.1.tgz",
- "integrity": "sha512-NPW1YITG7N+3TsqXc4LZV3c5IEpTD5iX18r0bvFsHdIblo5qi0ykpeK3TffmMM5gbTjgKJ4DNVHOjLiWKxFUxw==",
+ "version": "6.7.3",
+ "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-6.7.3.tgz",
+ "integrity": "sha512-fXWbEdHMLW/e8cts3snEsbOTbnFXfUHeO2pkiDFX3fWpFoDtUrRWvn50xbY13IJUUKHDhoJ+mj24nMRVIXfX1A==",
"dependencies": {
"invariant": "^2.2.4"
}
@@ -4964,9 +4973,9 @@
"integrity": "sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ=="
},
"node_modules/@react-native/normalize-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-2.0.0.tgz",
- "integrity": "sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw=="
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-2.1.0.tgz",
+ "integrity": "sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA=="
},
"node_modules/@react-native/polyfills": {
"version": "2.0.0",
@@ -4974,11 +4983,11 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ=="
},
"node_modules/@react-navigation/bottom-tabs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.2.tgz",
- "integrity": "sha512-iN3B1cgXdo64lqXdsTsCjN7n+5ILYKRexAu0VtW6EO8E6Z/0obK5JcCEropSiimRqVRs0kyuYj3F94Oth+hMrw==",
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.3.tgz",
+ "integrity": "sha512-ZA2Ko9fNwNaaSNn7738KpEk8Doi+yjRfTg8Wb/WvduIaK/28qNLAYWBCUEVjBC55y/9zJOzwc4R8Av2J2MG/4g==",
"dependencies": {
- "@react-navigation/elements": "^1.3.12",
+ "@react-navigation/elements": "^1.3.13",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -5019,9 +5028,9 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@react-navigation/core": {
- "version": "6.4.5",
- "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.5.tgz",
- "integrity": "sha512-wcde35HeOM5r2P25EwLQZyJ1yhXDGKuWpnKfsSI1xrgYIvWdYi3j/yGnwgNGDelCmtUt1Fyk2pmOv8sEku9KkA==",
+ "version": "6.4.6",
+ "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz",
+ "integrity": "sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==",
"dependencies": {
"@react-navigation/routers": "^6.1.6",
"escape-string-regexp": "^4.0.0",
@@ -5035,9 +5044,9 @@
}
},
"node_modules/@react-navigation/elements": {
- "version": "1.3.12",
- "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.12.tgz",
- "integrity": "sha512-iVcLIYg/XJk1p6X1rSFhNhCjAJ3ORqNT2/bJqw7I/liujeJAoz1oZ5JDoEcZaA0wMDts1txxLuqAYJmhCgU2aA==",
+ "version": "1.3.13",
+ "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.13.tgz",
+ "integrity": "sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA==",
"peerDependencies": {
"@react-navigation/native": "^6.0.0",
"react": "*",
@@ -5046,11 +5055,11 @@
}
},
"node_modules/@react-navigation/native": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.1.tgz",
- "integrity": "sha512-iIozx9c66EjSFyzKrZPixnk6vBuivYXp0jmbKCJXNIa7MY+8OLx9CXj/+1py/l/OGlXDhI6jiUWWetOfOtMaBQ==",
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.2.tgz",
+ "integrity": "sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==",
"dependencies": {
- "@react-navigation/core": "^6.4.5",
+ "@react-navigation/core": "^6.4.6",
"escape-string-regexp": "^4.0.0",
"fast-deep-equal": "^3.1.3",
"nanoid": "^3.1.23"
@@ -5069,11 +5078,11 @@
}
},
"node_modules/@react-navigation/stack": {
- "version": "6.3.10",
- "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.10.tgz",
- "integrity": "sha512-mghQpCbGBI9jpwYmhXDI5drGOxz6F9hLxQgLeu1IsTSA9767Edov7TDt5n/PTJqhpOru7/xoNMs4yhp9ykVhng==",
+ "version": "6.3.11",
+ "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.11.tgz",
+ "integrity": "sha512-GWOAyJfPEsjVwDWec1ERwWL5LvManJucCRUZetJqCBs4/mV7HXEt2x6l3SMitHxH1+K+9XuYXI+wBTbK1WDYOA==",
"dependencies": {
- "@react-navigation/elements": "^1.3.12",
+ "@react-navigation/elements": "^1.3.13",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -5115,35 +5124,24 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/@rudderstack/rudder-sdk-react-native": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@rudderstack/rudder-sdk-react-native/-/rudder-sdk-react-native-1.5.1.tgz",
- "integrity": "sha512-nyacl2EpJ3l2NBMm7YhijyjD1jIk0GeBpBgFMZavMdAChA+Ak7sl+quKOfewYHLuFf/g2xh07p4ULLQpLqBpZw==",
- "dependencies": {
- "@babel/runtime": "^7.7.7",
- "@types/async-lock": "^1.1.3",
- "@types/react-native": "^0.62.2",
- "async-lock": "^1.3.0"
- },
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@rudderstack/rudder-sdk-react-native/-/rudder-sdk-react-native-1.5.2.tgz",
+ "integrity": "sha512-M6dqOHqmbDzFE3R+TfjA0AppQfS8TSuv+qLtiq57V47zlLlkusszfZvHLQ8O63iTi5XsVciO1oTyj2ZCLtJUHA==",
"peerDependencies": {
- "react-native": ">=0.41.2 <=0.69.3"
- }
- },
- "node_modules/@rudderstack/rudder-sdk-react-native/node_modules/@types/react-native": {
- "version": "0.62.18",
- "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.62.18.tgz",
- "integrity": "sha512-7QfU8EzIYxYqeXpPf8QNv2xi8hrePlgTbRATRo+plRSdVfJu7N6sAXqrFxKJp6bGLvp82GV1gczl93gqiAfXPA==",
- "dependencies": {
- "@types/react": "*"
+ "async-lock": "1.4.0",
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
+ "react-native": "^0.41.2"
}
},
"node_modules/@sentry/browser": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.26.0.tgz",
- "integrity": "sha512-S6uW+Ni2VLGHUV9eAUtTy5QEvqKeOhcnWnv+2yTGDtQCJ0SuHfXRCM7ASAQYBiKffZqIFc9Z2XNU/2cuWcXJmw==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.29.0.tgz",
+ "integrity": "sha512-Af+dIcntaw405Wt7myDOMGDxiszfy4aBdshrEKYbGgcfHjgXBIdF3iKlNatvl6nrOm+IOVuKgSpCLOr2hiCwzw==",
"dependencies": {
- "@sentry/core": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/core": "7.29.0",
+ "@sentry/replay": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"tslib": "^1.9.3"
},
"engines": {
@@ -5191,12 +5189,12 @@
}
},
"node_modules/@sentry/core": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.26.0.tgz",
- "integrity": "sha512-ydi236ZoP/xpvLdf7B8seKjCcGc5Z+q9c14tHCFusplPZgLSXcYpiiLIDWmF7OAXO89sSbb1NaFt9YB0LkYdLQ==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.29.0.tgz",
+ "integrity": "sha512-+e9aIp2ljtT4EJq3901z6TfEVEeqZd5cWzbKEuQzPn2UO6If9+Utd7kY2Y31eQYb4QnJgZfiIEz1HonuYY6zqQ==",
"dependencies": {
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"tslib": "^1.9.3"
},
"engines": {
@@ -5209,13 +5207,13 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/hub": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.26.0.tgz",
- "integrity": "sha512-djAMuA4/Jy28dOSy9z5ccXBDyYk1N9m0ljle+dKqjfJwv440tCGyoxm2arqJFHbXvqwJTt2Giv8ASR4uGD1UNg==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.29.0.tgz",
+ "integrity": "sha512-nIV2NtTn16VukTtWFhROHJ35NyUIXgEGtesG8a1i7D4iRSvkfLkLrQ9i6D0BAE2huqKqQemO3zGEPR00szqsiA==",
"dependencies": {
- "@sentry/core": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/core": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"tslib": "^1.9.3"
},
"engines": {
@@ -5228,12 +5226,12 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/integrations": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.26.0.tgz",
- "integrity": "sha512-5tyBA5BnZEuosSIvBP7mJz66xJaZTb/k1EzHEc0hR2Mw8QpLgMneDZBfi4vdbhxtGpJKC/gURoUGZf9hpwW+DA==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.29.0.tgz",
+ "integrity": "sha512-BkZe3ALij320VtC5bNkeSz3OUhT9oxZsj2lf5rCuRFqcqw4tvVNADF/Y98mf0L4VCy582M9MlNXmwfewJjxGOA==",
"dependencies": {
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"localforage": "^1.8.1",
"tslib": "^1.9.3"
},
@@ -5247,13 +5245,13 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/react": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.26.0.tgz",
- "integrity": "sha512-v5XKpG1PF4qnWvG8E0N1kcUk74lTp+TDfKx5x996NIja2oOTp/JL9V0Q+lAMlB1EKgJuxLe92IeqD5/DTtzE7A==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.29.0.tgz",
+ "integrity": "sha512-pJ138QTChfAiYzFrCgycBgXrAVARV6TdVvLB8z/HsqbHzPq17RhyF9M1xPE4ffeLDQAEuSudwED9CLOpJqKnAw==",
"dependencies": {
- "@sentry/browser": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/browser": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"hoist-non-react-statics": "^3.3.2",
"tslib": "^1.9.3"
},
@@ -5265,19 +5263,19 @@
}
},
"node_modules/@sentry/react-native": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-4.12.0.tgz",
- "integrity": "sha512-KBRXXqqGg67oqhtGzZQ8Ls4rxxUozDyL8tMLmRLk//bkSWBC6XslyjkZkQrB1VZsv2ikEYCUgyAP7fzcj6Bbig==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-4.13.0.tgz",
+ "integrity": "sha512-CxQd5jWPKEPgR1SH5ppf555h7DMhSBZMU3eSZ/VNT+BocgzxxBnf/tcJj92+gpwrzt2m7MiZ3uDfyfQOgyMc8Q==",
"dependencies": {
- "@sentry/browser": "7.26.0",
+ "@sentry/browser": "7.29.0",
"@sentry/cli": "1.74.4",
- "@sentry/core": "7.26.0",
- "@sentry/hub": "7.26.0",
- "@sentry/integrations": "7.26.0",
- "@sentry/react": "7.26.0",
- "@sentry/tracing": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/core": "7.29.0",
+ "@sentry/hub": "7.29.0",
+ "@sentry/integrations": "7.29.0",
+ "@sentry/react": "7.29.0",
+ "@sentry/tracing": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"@sentry/wizard": "1.4.0"
},
"peerDependencies": {
@@ -5290,14 +5288,30 @@
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
- "node_modules/@sentry/tracing": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.26.0.tgz",
- "integrity": "sha512-UK8EiXxJrDTWD82Oasj2WP/QuQ+wzPlg74vYmxl1ie/LRs6C6wHkilBZwDV9HnDdqAqSjl0al8oBa075lK+U3Q==",
+ "node_modules/@sentry/replay": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.29.0.tgz",
+ "integrity": "sha512-Gw7HgviJQu6pX5RFQGVY38Av4qFn9otrZdwSSl/QK5hIyg6yhlh5h7U0ydZkrYYGiW6Z6SYYRpEWCJc/Wbh+ZQ==",
"dependencies": {
- "@sentry/core": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/core": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "peerDependencies": {
+ "@sentry/browser": ">=7.24.0"
+ }
+ },
+ "node_modules/@sentry/tracing": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.29.0.tgz",
+ "integrity": "sha512-MAN/G6XROtRhzo/KDjddb6VJn/Q1TaPLwdyj9vvfkUkBNtlt5k16oXp+u7eHWX0uujER9wnZtj2ivXaPeqq0VA==",
+ "dependencies": {
+ "@sentry/core": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"tslib": "^1.9.3"
},
"engines": {
@@ -5310,19 +5324,19 @@
"integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg=="
},
"node_modules/@sentry/types": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.26.0.tgz",
- "integrity": "sha512-U2s0q3ALwWFdHJBgn8nrG9bCTJZ3hAqL/I2Si4Mf0ZWnJ/KTJKbtyrputHr8wMbHvX0NZTJGTxFVUO46J+GBRA==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-DmoEpoqHPty3VxqubS/5gxarwebHRlcBd/yuno+PS3xy++/i9YPjOWLZhU2jYs1cW68M9R6CcCOiC9f2ckJjdw==",
"engines": {
"node": ">=8"
}
},
"node_modules/@sentry/utils": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.26.0.tgz",
- "integrity": "sha512-nIC1PRyoMBi4QB7XNCWaPDqaQbPayMwAvUm6W3MC5bHPfVZmmFt+3sLZQKUD/E0NeQnJ3vTyPewPF/LfxLOE5A==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.29.0.tgz",
+ "integrity": "sha512-ICcBwTiBGK8NQA8H2BJo0JcMN6yCeKLqNKNMVampRgS6wSfSk1edvcTdhRkW3bSktIGrIPZrKskBHyMwDGF2XQ==",
"dependencies": {
- "@sentry/types": "7.26.0",
+ "@sentry/types": "7.29.0",
"tslib": "^1.9.3"
},
"engines": {
@@ -5369,9 +5383,9 @@
}
},
"node_modules/@sideway/formula": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
- "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg=="
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
},
"node_modules/@sideway/pinpoint": {
"version": "2.0.0",
@@ -5381,14 +5395,12 @@
"node_modules/@sinclair/typebox": {
"version": "0.24.44",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz",
- "integrity": "sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==",
- "dev": true
+ "integrity": "sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg=="
},
"node_modules/@sinonjs/commons": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
"integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
- "dev": true,
"dependencies": {
"type-detect": "4.0.8"
}
@@ -5397,7 +5409,6 @@
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
"integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
- "dev": true,
"dependencies": {
"@sinonjs/commons": "^1.7.0"
}
@@ -5758,11 +5769,6 @@
"node": ">=10.13.0"
}
},
- "node_modules/@types/async-lock": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz",
- "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ=="
- },
"node_modules/@types/babel__core": {
"version": "7.1.19",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz",
@@ -5892,11 +5898,6 @@
"hoist-non-react-statics": "^3.3.0"
}
},
- "node_modules/@types/invariant": {
- "version": "2.2.35",
- "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz",
- "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg=="
- },
"node_modules/@types/istanbul-lib-coverage": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -5919,9 +5920,9 @@
}
},
"node_modules/@types/jest": {
- "version": "29.2.5",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.5.tgz",
- "integrity": "sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw==",
+ "version": "29.2.6",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.6.tgz",
+ "integrity": "sha512-XEUC/Tgw3uMh6Ho8GkUtQ2lPhY5Fmgyp3TdlkTJs1W9VgNxs+Ow/x3Elh8lHQKqCbZL0AubQuqWjHVT033Hhrw==",
"dev": true,
"dependencies": {
"expect": "^29.0.0",
@@ -5981,9 +5982,9 @@
"dev": true
},
"node_modules/@types/react": {
- "version": "18.0.26",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz",
- "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==",
+ "version": "18.0.27",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
+ "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
"dependencies": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@@ -6097,8 +6098,7 @@
"node_modules/@types/stack-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
- "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
- "dev": true
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw=="
},
"node_modules/@types/tinycolor2": {
"version": "1.4.3",
@@ -6133,7 +6133,6 @@
"version": "17.0.13",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz",
"integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==",
- "dev": true,
"dependencies": {
"@types/yargs-parser": "*"
}
@@ -6144,14 +6143,14 @@
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.0.tgz",
- "integrity": "sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.49.0.tgz",
+ "integrity": "sha512-IhxabIpcf++TBaBa1h7jtOWyon80SXPRLDq0dVz5SLFC/eW6tofkw/O7Ar3lkx5z5U6wzbKDrl2larprp5kk5Q==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.48.0",
- "@typescript-eslint/type-utils": "5.48.0",
- "@typescript-eslint/utils": "5.48.0",
+ "@typescript-eslint/scope-manager": "5.49.0",
+ "@typescript-eslint/type-utils": "5.49.0",
+ "@typescript-eslint/utils": "5.49.0",
"debug": "^4.3.4",
"ignore": "^5.2.0",
"natural-compare-lite": "^1.4.0",
@@ -6177,14 +6176,14 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.0.tgz",
- "integrity": "sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.49.0.tgz",
+ "integrity": "sha512-veDlZN9mUhGqU31Qiv2qEp+XrJj5fgZpJ8PW30sHU+j/8/e5ruAhLaVDAeznS7A7i4ucb/s8IozpDtt9NqCkZg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.48.0",
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/typescript-estree": "5.48.0",
+ "@typescript-eslint/scope-manager": "5.49.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/typescript-estree": "5.49.0",
"debug": "^4.3.4"
},
"engines": {
@@ -6204,9 +6203,9 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/types": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
- "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz",
+ "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -6217,13 +6216,13 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
- "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz",
+ "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/visitor-keys": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/visitor-keys": "5.49.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -6244,12 +6243,12 @@
}
},
"node_modules/@typescript-eslint/parser/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
- "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz",
+ "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -6270,13 +6269,13 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz",
- "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.49.0.tgz",
+ "integrity": "sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/visitor-keys": "5.48.0"
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/visitor-keys": "5.49.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -6287,9 +6286,9 @@
}
},
"node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/types": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
- "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz",
+ "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -6300,12 +6299,12 @@
}
},
"node_modules/@typescript-eslint/scope-manager/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
- "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz",
+ "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -6326,13 +6325,13 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.0.tgz",
- "integrity": "sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.49.0.tgz",
+ "integrity": "sha512-eUgLTYq0tR0FGU5g1YHm4rt5H/+V2IPVkP0cBmbhRyEmyGe4XvJ2YJ6sYTmONfjmdMqyMLad7SB8GvblbeESZA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "5.48.0",
- "@typescript-eslint/utils": "5.48.0",
+ "@typescript-eslint/typescript-estree": "5.49.0",
+ "@typescript-eslint/utils": "5.49.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
@@ -6353,9 +6352,9 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
- "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz",
+ "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -6366,13 +6365,13 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
- "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz",
+ "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/visitor-keys": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/visitor-keys": "5.49.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -6393,12 +6392,12 @@
}
},
"node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
- "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz",
+ "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -6459,16 +6458,16 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.0.tgz",
- "integrity": "sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.49.0.tgz",
+ "integrity": "sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==",
"dev": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.48.0",
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/typescript-estree": "5.48.0",
+ "@typescript-eslint/scope-manager": "5.49.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/typescript-estree": "5.49.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0",
"semver": "^7.3.7"
@@ -6485,9 +6484,9 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/types": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
- "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz",
+ "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -6498,13 +6497,13 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
- "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz",
+ "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/visitor-keys": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/visitor-keys": "5.49.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -6525,12 +6524,12 @@
}
},
"node_modules/@typescript-eslint/utils/node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
- "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz",
+ "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
@@ -6825,7 +6824,6 @@
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
"integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
- "dev": true,
"bin": {
"acorn": "bin/acorn"
},
@@ -7108,14 +7106,15 @@
}
},
"node_modules/array.prototype.flat": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz",
- "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz",
+ "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0"
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
},
"engines": {
"node": ">= 0.4"
@@ -7198,9 +7197,10 @@
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"node_modules/async-lock": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.0.tgz",
- "integrity": "sha512-8A7SkiisnEgME2zEedtDYPxUPzdv3x//E7n5IFktPAtMYSEAV7eNJF0rMwrVyUFj6d/8rgajLantbjcNRQYXIg=="
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.0.tgz",
+ "integrity": "sha512-coglx5yIWuetakm3/1dsX9hxCNox22h7+V80RQOu2XUUMidtArxKoZoOtHUPuR84SycKTXzgGzAUR5hJxujyJQ==",
+ "peer": true
},
"node_modules/asynckit": {
"version": "0.4.0",
@@ -7240,9 +7240,9 @@
}
},
"node_modules/axios": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.2.tgz",
- "integrity": "sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.3.tgz",
+ "integrity": "sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==",
"dev": true,
"dependencies": {
"follow-redirects": "^1.15.0",
@@ -7479,19 +7479,76 @@
}
},
"node_modules/babel-plugin-module-resolver": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz",
- "integrity": "sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.0.tgz",
+ "integrity": "sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==",
"dev": true,
"dependencies": {
- "find-babel-config": "^1.2.0",
- "glob": "^7.1.6",
+ "find-babel-config": "^2.0.0",
+ "glob": "^8.0.3",
"pkg-up": "^3.1.0",
- "reselect": "^4.0.0",
- "resolve": "^1.13.1"
+ "reselect": "^4.1.7",
+ "resolve": "^1.22.1"
},
"engines": {
- "node": ">= 8.0.0"
+ "node": ">= 16"
+ }
+ },
+ "node_modules/babel-plugin-module-resolver/node_modules/brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/babel-plugin-module-resolver/node_modules/glob": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
+ "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
+ "dev": true,
+ "dependencies": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/babel-plugin-module-resolver/node_modules/minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==",
+ "dev": true,
+ "dependencies": {
+ "brace-expansion": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/babel-plugin-module-resolver/node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/babel-plugin-polyfill-corejs2": {
@@ -8956,9 +9013,9 @@
}
},
"node_modules/detox": {
- "version": "20.1.1",
- "resolved": "https://registry.npmjs.org/detox/-/detox-20.1.1.tgz",
- "integrity": "sha512-0ieeWAyo2f3YKeFwm7KCz4lBkCJIydyqzCQVN1sw/ZU9x9Qc8kz+itKAEiH4DHUlLkb4YLzfEbAXfO09wvrQ3w==",
+ "version": "20.1.2",
+ "resolved": "https://registry.npmjs.org/detox/-/detox-20.1.2.tgz",
+ "integrity": "sha512-SGxLyuzE8TjIc4Lg49YKD0buj3JLaX+KtprSeFvn7ZTdWd4fH6o5Szd4KM21uBSpnYEEgXTgiCypPQst6dt5mQ==",
"dev": true,
"hasInstallScript": true,
"dependencies": {
@@ -8974,7 +9031,7 @@
"glob": "^8.0.3",
"ini": "^1.3.4",
"json-cycle": "^1.3.0",
- "lodash": "^4.17.5",
+ "lodash": "^4.17.11",
"multi-sort-stream": "^1.0.3",
"multipipe": "^4.0.0",
"node-ipc": "^9.2.1",
@@ -9496,9 +9553,9 @@
}
},
"node_modules/eslint": {
- "version": "8.31.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz",
- "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==",
+ "version": "8.32.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz",
+ "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.4.1",
@@ -9564,13 +9621,14 @@
}
},
"node_modules/eslint-import-resolver-node": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
- "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz",
+ "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==",
"dev": true,
"dependencies": {
"debug": "^3.2.7",
- "resolve": "^1.20.0"
+ "is-core-module": "^2.11.0",
+ "resolve": "^1.22.1"
}
},
"node_modules/eslint-import-resolver-node/node_modules/debug": {
@@ -9582,17 +9640,38 @@
"ms": "^2.1.1"
}
},
- "node_modules/eslint-module-utils": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
- "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==",
+ "node_modules/eslint-import-resolver-node/node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
"dev": true,
"dependencies": {
- "debug": "^3.2.7",
- "find-up": "^2.1.0"
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-module-utils": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz",
+ "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^3.2.7"
},
"engines": {
"node": ">=4"
+ },
+ "peerDependenciesMeta": {
+ "eslint": {
+ "optional": true
+ }
}
},
"node_modules/eslint-module-utils/node_modules/debug": {
@@ -9604,64 +9683,6 @@
"ms": "^2.1.1"
}
},
- "node_modules/eslint-module-utils/node_modules/find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
- "dev": true,
- "dependencies": {
- "locate-path": "^2.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/eslint-module-utils/node_modules/locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
- "dev": true,
- "dependencies": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/eslint-module-utils/node_modules/p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
- "dev": true,
- "dependencies": {
- "p-try": "^1.0.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/eslint-module-utils/node_modules/p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
- "dev": true,
- "dependencies": {
- "p-limit": "^1.1.0"
- },
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/eslint-module-utils/node_modules/p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
- "dev": true,
- "engines": {
- "node": ">=4"
- }
- },
"node_modules/eslint-plugin-eslint-comments": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.2.0.tgz",
@@ -9717,23 +9738,25 @@
}
},
"node_modules/eslint-plugin-import": {
- "version": "2.26.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz",
- "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==",
+ "version": "2.27.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz",
+ "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==",
"dev": true,
"dependencies": {
- "array-includes": "^3.1.4",
- "array.prototype.flat": "^1.2.5",
- "debug": "^2.6.9",
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "array.prototype.flatmap": "^1.3.1",
+ "debug": "^3.2.7",
"doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.6",
- "eslint-module-utils": "^2.7.3",
+ "eslint-import-resolver-node": "^0.3.7",
+ "eslint-module-utils": "^2.7.4",
"has": "^1.0.3",
- "is-core-module": "^2.8.1",
+ "is-core-module": "^2.11.0",
"is-glob": "^4.0.3",
"minimatch": "^3.1.2",
- "object.values": "^1.1.5",
- "resolve": "^1.22.0",
+ "object.values": "^1.1.6",
+ "resolve": "^1.22.1",
+ "semver": "^6.3.0",
"tsconfig-paths": "^3.14.1"
},
"engines": {
@@ -9744,12 +9767,12 @@
}
},
"node_modules/eslint-plugin-import/node_modules/debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"dependencies": {
- "ms": "2.0.0"
+ "ms": "^2.1.1"
}
},
"node_modules/eslint-plugin-import/node_modules/doctrine": {
@@ -9764,11 +9787,31 @@
"node": ">=0.10.0"
}
},
- "node_modules/eslint-plugin-import/node_modules/ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
- "dev": true
+ "node_modules/eslint-plugin-import/node_modules/resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "dependencies": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/eslint-plugin-import/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
},
"node_modules/eslint-plugin-jest": {
"version": "27.2.1",
@@ -9816,9 +9859,9 @@
}
},
"node_modules/eslint-plugin-react": {
- "version": "7.31.11",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz",
- "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==",
+ "version": "7.32.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.1.tgz",
+ "integrity": "sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www==",
"dev": true,
"dependencies": {
"array-includes": "^3.1.6",
@@ -9833,7 +9876,7 @@
"object.hasown": "^1.1.2",
"object.values": "^1.1.6",
"prop-types": "^15.8.1",
- "resolve": "^2.0.0-next.3",
+ "resolve": "^2.0.0-next.4",
"semver": "^6.3.0",
"string.prototype.matchall": "^4.0.8"
},
@@ -9888,13 +9931,17 @@
}
},
"node_modules/eslint-plugin-react/node_modules/resolve": {
- "version": "2.0.0-next.3",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz",
- "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==",
+ "version": "2.0.0-next.4",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz",
+ "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==",
"dev": true,
"dependencies": {
- "is-core-module": "^2.2.0",
- "path-parse": "^1.0.6"
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ },
+ "bin": {
+ "resolve": "bin/resolve"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -10892,25 +10939,25 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
"node_modules/find-babel-config": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz",
- "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.0.0.tgz",
+ "integrity": "sha512-dOKT7jvF3hGzlW60Gc3ONox/0rRZ/tz7WCil0bqA1In/3I8f1BctpXahRnEKDySZqci7u+dqq93sZST9fOJpFw==",
"dev": true,
"dependencies": {
- "json5": "^0.5.1",
- "path-exists": "^3.0.0"
+ "json5": "^2.1.1",
+ "path-exists": "^4.0.0"
},
"engines": {
- "node": ">=4.0.0"
+ "node": ">=16.0.0"
}
},
- "node_modules/find-babel-config/node_modules/json5": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
- "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "node_modules/find-babel-config/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true,
- "bin": {
- "json5": "lib/cli.js"
+ "engines": {
+ "node": ">=8"
}
},
"node_modules/find-cache-dir": {
@@ -11029,9 +11076,9 @@
"dev": true
},
"node_modules/flow-parser": {
- "version": "0.121.0",
- "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz",
- "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==",
+ "version": "0.185.2",
+ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.185.2.tgz",
+ "integrity": "sha512-2hJ5ACYeJCzNtiVULov6pljKOLygy0zddoqSI1fFetM+XRPpRshFdGEijtqlamA1XwyZ+7rhryI6FQFzvtLWUQ==",
"engines": {
"node": ">=0.4.0"
}
@@ -12175,9 +12222,9 @@
"dev": true
},
"node_modules/is-core-module": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
- "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"dependencies": {
"has": "^1.0.3"
},
@@ -13377,7 +13424,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz",
"integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==",
- "dev": true,
"dependencies": {
"@jest/environment": "^29.3.1",
"@jest/fake-timers": "^29.3.1",
@@ -13526,7 +13572,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
"integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
- "dev": true,
"dependencies": {
"@babel/code-frame": "^7.12.13",
"@jest/types": "^29.3.1",
@@ -13546,7 +13591,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
@@ -13561,7 +13605,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -13577,7 +13620,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
@@ -13588,14 +13630,12 @@
"node_modules/jest-message-util/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/jest-message-util/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -13604,7 +13644,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -13613,7 +13652,6 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -13625,7 +13663,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz",
"integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==",
- "dev": true,
"dependencies": {
"@jest/types": "^29.3.1",
"@types/node": "*",
@@ -14133,7 +14170,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
"integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
- "dev": true,
"dependencies": {
"@jest/types": "^29.3.1",
"@types/node": "*",
@@ -14150,7 +14186,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"dependencies": {
"color-convert": "^2.0.1"
},
@@ -14165,7 +14200,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"dependencies": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -14181,7 +14215,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"dependencies": {
"color-name": "~1.1.4"
},
@@ -14192,14 +14225,12 @@
"node_modules/jest-util/node_modules/color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"node_modules/jest-util/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -14208,7 +14239,6 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@@ -14873,14 +14903,6 @@
"node": ">=0.10.0"
}
},
- "node_modules/klaw": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
- "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==",
- "optionalDependencies": {
- "graceful-fs": "^4.1.9"
- }
- },
"node_modules/klaw-sync": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
@@ -15223,9 +15245,9 @@
},
"node_modules/lokijs": {
"name": "@nozbe/lokijs",
- "version": "1.5.12-wmelon4",
- "resolved": "https://registry.npmjs.org/@nozbe/lokijs/-/lokijs-1.5.12-wmelon4.tgz",
- "integrity": "sha512-3sYrhLI2GkdXW/VOi1w6D2tENxxL+n1LJHRIAkaSCoehTVDiysAjxa/1GQq7gb7T4CFxJ+brMGvSx0sugEwqjQ=="
+ "version": "1.5.12-wmelon6",
+ "resolved": "https://registry.npmjs.org/@nozbe/lokijs/-/lokijs-1.5.12-wmelon6.tgz",
+ "integrity": "sha512-GXsaqY8qTJ6xdCrGyno2t+ON2aj6PrUDdvhbrkxK/0Fp12C4FGvDg1wS+voLU9BANYHEnr7KRWfItDZnQkjoAg=="
},
"node_modules/loose-envify": {
"version": "1.4.0",
@@ -15355,17 +15377,17 @@
}
},
"node_modules/metro": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro/-/metro-0.72.3.tgz",
- "integrity": "sha512-Hb3xTvPqex8kJ1hutQNZhQadUKUwmns/Du9GikmWKBFrkiG3k3xstGAyO5t5rN9JSUEzQT6y9SWzSSOGogUKIg==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro/-/metro-0.73.7.tgz",
+ "integrity": "sha512-pkRqFhuGUvkiu8HxKPUQelbCuyy6te6okMssTyLzQwsKilNLK4YMI2uD6PHnypg5SiMJ58lwfqkp/t5w72jEvw==",
"dependencies": {
"@babel/code-frame": "^7.0.0",
- "@babel/core": "^7.14.0",
- "@babel/generator": "^7.14.0",
- "@babel/parser": "^7.14.0",
+ "@babel/core": "^7.20.0",
+ "@babel/generator": "^7.20.0",
+ "@babel/parser": "^7.20.0",
"@babel/template": "^7.0.0",
- "@babel/traverse": "^7.14.0",
- "@babel/types": "^7.0.0",
+ "@babel/traverse": "^7.20.0",
+ "@babel/types": "^7.20.0",
"absolute-path": "^0.0.0",
"accepts": "^1.3.7",
"async": "^3.2.2",
@@ -15375,92 +15397,81 @@
"debug": "^2.2.0",
"denodeify": "^1.2.1",
"error-stack-parser": "^2.0.6",
- "fs-extra": "^1.0.0",
"graceful-fs": "^4.2.4",
"hermes-parser": "0.8.0",
"image-size": "^0.6.0",
"invariant": "^2.2.4",
"jest-worker": "^27.2.0",
"lodash.throttle": "^4.1.1",
- "metro-babel-transformer": "0.72.3",
- "metro-cache": "0.72.3",
- "metro-cache-key": "0.72.3",
- "metro-config": "0.72.3",
- "metro-core": "0.72.3",
- "metro-file-map": "0.72.3",
- "metro-hermes-compiler": "0.72.3",
- "metro-inspector-proxy": "0.72.3",
- "metro-minify-uglify": "0.72.3",
- "metro-react-native-babel-preset": "0.72.3",
- "metro-resolver": "0.72.3",
- "metro-runtime": "0.72.3",
- "metro-source-map": "0.72.3",
- "metro-symbolicate": "0.72.3",
- "metro-transform-plugins": "0.72.3",
- "metro-transform-worker": "0.72.3",
+ "metro-babel-transformer": "0.73.7",
+ "metro-cache": "0.73.7",
+ "metro-cache-key": "0.73.7",
+ "metro-config": "0.73.7",
+ "metro-core": "0.73.7",
+ "metro-file-map": "0.73.7",
+ "metro-hermes-compiler": "0.73.7",
+ "metro-inspector-proxy": "0.73.7",
+ "metro-minify-terser": "0.73.7",
+ "metro-minify-uglify": "0.73.7",
+ "metro-react-native-babel-preset": "0.73.7",
+ "metro-resolver": "0.73.7",
+ "metro-runtime": "0.73.7",
+ "metro-source-map": "0.73.7",
+ "metro-symbolicate": "0.73.7",
+ "metro-transform-plugins": "0.73.7",
+ "metro-transform-worker": "0.73.7",
"mime-types": "^2.1.27",
"node-fetch": "^2.2.0",
"nullthrows": "^1.1.1",
- "rimraf": "^2.5.4",
+ "rimraf": "^3.0.2",
"serialize-error": "^2.1.0",
"source-map": "^0.5.6",
"strip-ansi": "^6.0.0",
"temp": "0.8.3",
"throat": "^5.0.0",
"ws": "^7.5.1",
- "yargs": "^15.3.1"
+ "yargs": "^17.5.1"
},
"bin": {
"metro": "src/cli.js"
}
},
"node_modules/metro-babel-transformer": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.72.3.tgz",
- "integrity": "sha512-PTOR2zww0vJbWeeM3qN90WKENxCLzv9xrwWaNtwVlhcV8/diNdNe82sE1xIxLFI6OQuAVwNMv1Y7VsO2I7Ejrw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.73.7.tgz",
+ "integrity": "sha512-s7UVkwovGTEXYEQrv5hcmSBbFJ9s9lhCRNMScn4Itgj3UMdqRr9lU8DXKEFlJ7osgRxN6n5+eXqcvhE4B1H1VQ==",
"dependencies": {
- "@babel/core": "^7.14.0",
+ "@babel/core": "^7.20.0",
"hermes-parser": "0.8.0",
- "metro-source-map": "0.72.3",
+ "metro-source-map": "0.73.7",
"nullthrows": "^1.1.1"
}
},
"node_modules/metro-cache": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.72.3.tgz",
- "integrity": "sha512-++eyZzwkXvijWRV3CkDbueaXXGlVzH9GA52QWqTgAOgSHYp5jWaDwLQ8qpsMkQzpwSyIF4LLK9aI3eA7Xa132A==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.73.7.tgz",
+ "integrity": "sha512-CPPgI+i9yVzOEDCdmEEZ67JgOvZyNDs8kStmGUFgDuLSjj3//HhkqT5XyfWjGeH6KmyGiS8ip3cgLOVn3IsOSA==",
"dependencies": {
- "metro-core": "0.72.3",
- "rimraf": "^2.5.4"
+ "metro-core": "0.73.7",
+ "rimraf": "^3.0.2"
}
},
"node_modules/metro-cache-key": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.72.3.tgz",
- "integrity": "sha512-kQzmF5s3qMlzqkQcDwDxrOaVxJ2Bh6WRXWdzPnnhsq9LcD3B3cYqQbRBS+3tSuXmathb4gsOdhWslOuIsYS8Rg=="
- },
- "node_modules/metro-cache/node_modules/rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- }
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.73.7.tgz",
+ "integrity": "sha512-GngYzrHwZU9U0Xl81H4aq9Tn5cjQyU12v9/flB0hzpeiYO5A89TIeilb4Kg8jtfC6JcmmsdK9nxYIGEq7odHhQ=="
},
"node_modules/metro-config": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.72.3.tgz",
- "integrity": "sha512-VEsAIVDkrIhgCByq8HKTWMBjJG6RlYwWSu1Gnv3PpHa0IyTjKJtB7wC02rbTjSaemcr82scldf2R+h6ygMEvsw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.73.7.tgz",
+ "integrity": "sha512-pD/F+vK3u37cbj1skYmI6cUsEEscqNRtW2KlDKu1m+n8nooDB2oGTOZatlS5WQa7Ga6jYQRydftlq4CLDexAfA==",
"dependencies": {
"cosmiconfig": "^5.0.5",
"jest-validate": "^26.5.2",
- "metro": "0.72.3",
- "metro-cache": "0.72.3",
- "metro-core": "0.72.3",
- "metro-runtime": "0.72.3"
+ "metro": "0.73.7",
+ "metro-cache": "0.73.7",
+ "metro-core": "0.73.7",
+ "metro-runtime": "0.73.7"
}
},
"node_modules/metro-config/node_modules/@jest/types": {
@@ -15479,9 +15490,9 @@
}
},
"node_modules/metro-config/node_modules/@types/yargs": {
- "version": "15.0.14",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
- "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
+ "version": "15.0.15",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz",
+ "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==",
"dependencies": {
"@types/yargs-parser": "*"
}
@@ -15605,18 +15616,18 @@
}
},
"node_modules/metro-core": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.72.3.tgz",
- "integrity": "sha512-KuYWBMmLB4+LxSMcZ1dmWabVExNCjZe3KysgoECAIV+wyIc2r4xANq15GhS94xYvX1+RqZrxU1pa0jQ5OK+/6A==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.73.7.tgz",
+ "integrity": "sha512-H7j1Egj1VnNnsSYf9ZKv0SRwijgtRKIcaGNQq/T+er73vqqb4kR9H+2VIJYPXi6R8lT+QLIMfs6CWSUHAJUgtg==",
"dependencies": {
"lodash.throttle": "^4.1.1",
- "metro-resolver": "0.72.3"
+ "metro-resolver": "0.73.7"
}
},
"node_modules/metro-file-map": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.72.3.tgz",
- "integrity": "sha512-LhuRnuZ2i2uxkpFsz1XCDIQSixxBkBG7oICAFyLyEMDGbcfeY6/NexphfLdJLTghkaoJR5ARFMiIxUg9fIY/pA==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.73.7.tgz",
+ "integrity": "sha512-BYaCo2e/4FMN4nOajeN+Za5cPfecfikzUYuFWWMyLAmHU6dj7B+PFkaJ4OEJO3vmRoeq5vMOmhpKXgysYbNXJg==",
"dependencies": {
"abort-controller": "^3.0.0",
"anymatch": "^3.0.3",
@@ -15629,10 +15640,11 @@
"jest-util": "^27.2.0",
"jest-worker": "^27.2.0",
"micromatch": "^4.0.4",
+ "nullthrows": "^1.1.1",
"walker": "^1.0.7"
},
"optionalDependencies": {
- "fsevents": "^2.1.2"
+ "fsevents": "^2.3.2"
}
},
"node_modules/metro-file-map/node_modules/@jest/types": {
@@ -15651,9 +15663,9 @@
}
},
"node_modules/metro-file-map/node_modules/@types/yargs": {
- "version": "16.0.4",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
- "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "version": "16.0.5",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz",
+ "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==",
"dependencies": {
"@types/yargs-parser": "*"
}
@@ -15787,64 +15799,37 @@
}
},
"node_modules/metro-hermes-compiler": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.72.3.tgz",
- "integrity": "sha512-QWDQASMiXNW3j8uIQbzIzCdGYv5PpAX/ZiF4/lTWqKRWuhlkP4auhVY4eqdAKj5syPx45ggpjkVE0p8hAPDZYg=="
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.73.7.tgz",
+ "integrity": "sha512-F8PlJ8mWEEumGNH3eMRA3gjgP70ZvH4Ex5F1KY6ofD/gpn7w5HJHSPTeVw8gtUb1pYLN4nevptpyXGg04Jfcog=="
},
"node_modules/metro-inspector-proxy": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.72.3.tgz",
- "integrity": "sha512-UPFkaq2k93RaOi+eqqt7UUmqy2ywCkuxJLasQ55+xavTUS+TQSyeTnTczaYn+YKw+izLTLllGcvqnQcZiWYhGw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.73.7.tgz",
+ "integrity": "sha512-TsAtQeKr9X7NaQHlpshu+ZkGWlPi5fFKNqieLkfqvT1oXN4PQF/4q38INyiZtWLPvoUzTR6PRnm4pcUbJ7+Nzg==",
"dependencies": {
"connect": "^3.6.5",
"debug": "^2.2.0",
"ws": "^7.5.1",
- "yargs": "^15.3.1"
+ "yargs": "^17.5.1"
},
"bin": {
"metro-inspector-proxy": "src/cli.js"
}
},
- "node_modules/metro-inspector-proxy/node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
"node_modules/metro-inspector-proxy/node_modules/cliui": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
- "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dependencies": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
- }
- },
- "node_modules/metro-inspector-proxy/node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dependencies": {
- "color-name": "~1.1.4"
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
},
"engines": {
- "node": ">=7.0.0"
+ "node": ">=12"
}
},
- "node_modules/metro-inspector-proxy/node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
"node_modules/metro-inspector-proxy/node_modules/debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -15853,14 +15838,6 @@
"ms": "2.0.0"
}
},
- "node_modules/metro-inspector-proxy/node_modules/decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/metro-inspector-proxy/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -15892,70 +15869,117 @@
"node": ">=8"
}
},
- "node_modules/metro-inspector-proxy/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/metro-inspector-proxy/node_modules/y18n": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
- "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
- },
"node_modules/metro-inspector-proxy/node_modules/yargs": {
- "version": "15.4.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
- "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
"dependencies": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
},
"engines": {
- "node": ">=8"
+ "node": ">=12"
}
},
"node_modules/metro-inspector-proxy/node_modules/yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dependencies": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- },
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"engines": {
- "node": ">=6"
+ "node": ">=12"
+ }
+ },
+ "node_modules/metro-minify-terser": {
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.73.7.tgz",
+ "integrity": "sha512-gbv1fmMOZm6gJ6dQoD+QktlCi2wk6nlTR8j8lQCjeeXGbs6O9e5XLWNPOexHqo7S69bdbohEnfZnLJFcxgHeNw==",
+ "dependencies": {
+ "terser": "^5.15.0"
}
},
"node_modules/metro-minify-uglify": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.72.3.tgz",
- "integrity": "sha512-dPXqtMI8TQcj0g7ZrdhC8X3mx3m3rtjtMuHKGIiEXH9CMBvrET8IwrgujQw2rkPcXiSiX8vFDbGMIlfxefDsKA==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.73.7.tgz",
+ "integrity": "sha512-DmDCzfdbaPExQuQ7NQozCNOSOAgp5Ux9kWzmKAT8seQ38/3NtUepW+PTgxXIHmwNjJV4oHsHwlBlTwJmYihKXg==",
"dependencies": {
"uglify-es": "^3.1.9"
}
},
"node_modules/metro-react-native-babel-preset": {
+ "version": "0.74.1",
+ "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.74.1.tgz",
+ "integrity": "sha512-DjsG9nqm5C7cjB2SlgbcNJOn9y5MBUd3bRlCfnoj8CxAeGTGkS+yXd183lHR3C1bhmQNjuUE0abzzpE1CFh6JQ==",
+ "dev": true,
+ "dependencies": {
+ "@babel/core": "^7.20.0",
+ "@babel/plugin-proposal-async-generator-functions": "^7.0.0",
+ "@babel/plugin-proposal-class-properties": "^7.0.0",
+ "@babel/plugin-proposal-export-default-from": "^7.0.0",
+ "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
+ "@babel/plugin-proposal-numeric-separator": "^7.0.0",
+ "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
+ "@babel/plugin-proposal-optional-catch-binding": "^7.0.0",
+ "@babel/plugin-proposal-optional-chaining": "^7.0.0",
+ "@babel/plugin-syntax-dynamic-import": "^7.0.0",
+ "@babel/plugin-syntax-export-default-from": "^7.0.0",
+ "@babel/plugin-syntax-flow": "^7.18.0",
+ "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
+ "@babel/plugin-syntax-optional-chaining": "^7.0.0",
+ "@babel/plugin-transform-arrow-functions": "^7.0.0",
+ "@babel/plugin-transform-async-to-generator": "^7.0.0",
+ "@babel/plugin-transform-block-scoping": "^7.0.0",
+ "@babel/plugin-transform-classes": "^7.0.0",
+ "@babel/plugin-transform-computed-properties": "^7.0.0",
+ "@babel/plugin-transform-destructuring": "^7.0.0",
+ "@babel/plugin-transform-flow-strip-types": "^7.0.0",
+ "@babel/plugin-transform-function-name": "^7.0.0",
+ "@babel/plugin-transform-literals": "^7.0.0",
+ "@babel/plugin-transform-modules-commonjs": "^7.0.0",
+ "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0",
+ "@babel/plugin-transform-parameters": "^7.0.0",
+ "@babel/plugin-transform-react-display-name": "^7.0.0",
+ "@babel/plugin-transform-react-jsx": "^7.0.0",
+ "@babel/plugin-transform-react-jsx-self": "^7.0.0",
+ "@babel/plugin-transform-react-jsx-source": "^7.0.0",
+ "@babel/plugin-transform-runtime": "^7.0.0",
+ "@babel/plugin-transform-shorthand-properties": "^7.0.0",
+ "@babel/plugin-transform-spread": "^7.0.0",
+ "@babel/plugin-transform-sticky-regex": "^7.0.0",
+ "@babel/plugin-transform-typescript": "^7.5.0",
+ "@babel/plugin-transform-unicode-regex": "^7.0.0",
+ "@babel/template": "^7.0.0",
+ "react-refresh": "^0.4.0"
+ },
+ "peerDependencies": {
+ "@babel/core": "*"
+ }
+ },
+ "node_modules/metro-react-native-babel-transformer": {
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.7.tgz",
+ "integrity": "sha512-73HW8betjX+VPm3iqsMBe8F/F2Tt+hONO6YJwcF7FonTqQYW1oTz0dOp0dClZGfHUXxpJBz6Vuo7J6TpdzDD+w==",
+ "dependencies": {
+ "@babel/core": "^7.20.0",
+ "babel-preset-fbjs": "^3.4.0",
+ "hermes-parser": "0.8.0",
+ "metro-babel-transformer": "0.73.7",
+ "metro-react-native-babel-preset": "0.73.7",
+ "metro-source-map": "0.73.7",
+ "nullthrows": "^1.1.1"
+ },
+ "peerDependencies": {
+ "@babel/core": "*"
+ }
+ },
+ "node_modules/metro-react-native-babel-transformer/node_modules/metro-react-native-babel-preset": {
"version": "0.73.7",
"resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.7.tgz",
"integrity": "sha512-RKcmRZREjJCzHKP+JhC9QTCohkeb3xa/DtqHU14U5KWzJHdC0mMrkTZYNXhV0cryxsaVKVEw5873KhbZyZHMVw==",
- "dev": true,
"dependencies": {
"@babel/core": "^7.20.0",
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
@@ -16000,100 +16024,34 @@
"@babel/core": "*"
}
},
- "node_modules/metro-react-native-babel-transformer": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.72.3.tgz",
- "integrity": "sha512-Ogst/M6ujYrl/+9mpEWqE3zF7l2mTuftDTy3L8wZYwX1pWUQWQpfU1aJBeWiLxt1XlIq+uriRjKzKoRoIK57EA==",
- "dependencies": {
- "@babel/core": "^7.14.0",
- "babel-preset-fbjs": "^3.4.0",
- "hermes-parser": "0.8.0",
- "metro-babel-transformer": "0.72.3",
- "metro-react-native-babel-preset": "0.72.3",
- "metro-source-map": "0.72.3",
- "nullthrows": "^1.1.1"
- },
- "peerDependencies": {
- "@babel/core": "*"
- }
- },
- "node_modules/metro-react-native-babel-transformer/node_modules/metro-react-native-babel-preset": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.72.3.tgz",
- "integrity": "sha512-uJx9y/1NIqoYTp6ZW1osJ7U5ZrXGAJbOQ/Qzl05BdGYvN1S7Qmbzid6xOirgK0EIT0pJKEEh1s8qbassYZe4cw==",
- "dependencies": {
- "@babel/core": "^7.14.0",
- "@babel/plugin-proposal-async-generator-functions": "^7.0.0",
- "@babel/plugin-proposal-class-properties": "^7.0.0",
- "@babel/plugin-proposal-export-default-from": "^7.0.0",
- "@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
- "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
- "@babel/plugin-proposal-optional-catch-binding": "^7.0.0",
- "@babel/plugin-proposal-optional-chaining": "^7.0.0",
- "@babel/plugin-syntax-dynamic-import": "^7.0.0",
- "@babel/plugin-syntax-export-default-from": "^7.0.0",
- "@babel/plugin-syntax-flow": "^7.2.0",
- "@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
- "@babel/plugin-syntax-optional-chaining": "^7.0.0",
- "@babel/plugin-transform-arrow-functions": "^7.0.0",
- "@babel/plugin-transform-async-to-generator": "^7.0.0",
- "@babel/plugin-transform-block-scoping": "^7.0.0",
- "@babel/plugin-transform-classes": "^7.0.0",
- "@babel/plugin-transform-computed-properties": "^7.0.0",
- "@babel/plugin-transform-destructuring": "^7.0.0",
- "@babel/plugin-transform-exponentiation-operator": "^7.0.0",
- "@babel/plugin-transform-flow-strip-types": "^7.0.0",
- "@babel/plugin-transform-function-name": "^7.0.0",
- "@babel/plugin-transform-literals": "^7.0.0",
- "@babel/plugin-transform-modules-commonjs": "^7.0.0",
- "@babel/plugin-transform-named-capturing-groups-regex": "^7.0.0",
- "@babel/plugin-transform-parameters": "^7.0.0",
- "@babel/plugin-transform-react-display-name": "^7.0.0",
- "@babel/plugin-transform-react-jsx": "^7.0.0",
- "@babel/plugin-transform-react-jsx-self": "^7.0.0",
- "@babel/plugin-transform-react-jsx-source": "^7.0.0",
- "@babel/plugin-transform-runtime": "^7.0.0",
- "@babel/plugin-transform-shorthand-properties": "^7.0.0",
- "@babel/plugin-transform-spread": "^7.0.0",
- "@babel/plugin-transform-sticky-regex": "^7.0.0",
- "@babel/plugin-transform-template-literals": "^7.0.0",
- "@babel/plugin-transform-typescript": "^7.5.0",
- "@babel/plugin-transform-unicode-regex": "^7.0.0",
- "@babel/template": "^7.0.0",
- "react-refresh": "^0.4.0"
- },
- "peerDependencies": {
- "@babel/core": "*"
- }
- },
"node_modules/metro-resolver": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.72.3.tgz",
- "integrity": "sha512-wu9zSMGdxpKmfECE7FtCdpfC+vrWGTdVr57lDA0piKhZV6VN6acZIvqQ1yZKtS2WfKsngncv5VbB8Y5eHRQP3w==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.73.7.tgz",
+ "integrity": "sha512-mGW3XPeKBCwZnkHcKo1dhFa9olcx7SyNzG1vb5kjzJYe4Qs3yx04r/qFXIJLcIgLItB69TIGvosznUhpeOOXzg==",
"dependencies": {
"absolute-path": "^0.0.0"
}
},
"node_modules/metro-runtime": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.72.3.tgz",
- "integrity": "sha512-3MhvDKfxMg2u7dmTdpFOfdR71NgNNo4tzAyJumDVQKwnHYHN44f2QFZQqpPBEmqhWlojNeOxsqFsjYgeyMx6VA==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.73.7.tgz",
+ "integrity": "sha512-2fxRGrF8FyrwwHY0TCitdUljzutfW6CWEpdvPilfrs8p0PI5X8xOWg8ficeYtw+DldHtHIAL2phT59PqzHTyVA==",
"dependencies": {
"@babel/runtime": "^7.0.0",
"react-refresh": "^0.4.0"
}
},
"node_modules/metro-source-map": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.72.3.tgz",
- "integrity": "sha512-eNtpjbjxSheXu/jYCIDrbNEKzMGOvYW6/ePYpRM7gDdEagUOqKOCsi3St8NJIQJzZCsxD2JZ2pYOiomUSkT1yQ==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.73.7.tgz",
+ "integrity": "sha512-gbC/lfUN52TtQhEsTTA+987MaFUpQlufuCI05blLGLosDcFCsARikHsxa65Gtslm/rG2MqvFLiPA5hviONNv9g==",
"dependencies": {
- "@babel/traverse": "^7.14.0",
- "@babel/types": "^7.0.0",
+ "@babel/traverse": "^7.20.0",
+ "@babel/types": "^7.20.0",
"invariant": "^2.2.4",
- "metro-symbolicate": "0.72.3",
+ "metro-symbolicate": "0.73.7",
"nullthrows": "^1.1.1",
- "ob1": "0.72.3",
+ "ob1": "0.73.7",
"source-map": "^0.5.6",
"vlq": "^1.0.0"
}
@@ -16107,12 +16065,12 @@
}
},
"node_modules/metro-symbolicate": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.72.3.tgz",
- "integrity": "sha512-eXG0NX2PJzJ/jTG4q5yyYeN2dr1cUqUaY7worBB0SP5bRWRc3besfb+rXwfh49wTFiL5qR0oOawkU4ZiD4eHXw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.73.7.tgz",
+ "integrity": "sha512-571ThWmX5o8yGNzoXjlcdhmXqpByHU/bSZtWKhtgV2TyIAzYCYt4hawJAS5+/qDazUvjHdm8BbdqFUheM0EKNQ==",
"dependencies": {
"invariant": "^2.2.4",
- "metro-source-map": "0.72.3",
+ "metro-source-map": "0.73.7",
"nullthrows": "^1.1.1",
"source-map": "^0.5.6",
"through2": "^2.0.1",
@@ -16134,34 +16092,34 @@
}
},
"node_modules/metro-transform-plugins": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.72.3.tgz",
- "integrity": "sha512-D+TcUvCKZbRua1+qujE0wV1onZvslW6cVTs7dLCyC2pv20lNHjFr1GtW01jN2fyKR2PcRyMjDCppFd9VwDKnSg==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.73.7.tgz",
+ "integrity": "sha512-M5isiWEau0jMudb5ezaNBZnYqXxcATMqnAYc+Cu25IahT1NHi5aWwLok9EBmBpN5641IZUZXScf+KnS7fPxPCQ==",
"dependencies": {
- "@babel/core": "^7.14.0",
- "@babel/generator": "^7.14.0",
+ "@babel/core": "^7.20.0",
+ "@babel/generator": "^7.20.0",
"@babel/template": "^7.0.0",
- "@babel/traverse": "^7.14.0",
+ "@babel/traverse": "^7.20.0",
"nullthrows": "^1.1.1"
}
},
"node_modules/metro-transform-worker": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.72.3.tgz",
- "integrity": "sha512-WsuWj9H7i6cHuJuy+BgbWht9DK5FOgJxHLGAyULD5FJdTG9rSMFaHDO5WfC0OwQU5h4w6cPT40iDuEGksM7+YQ==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.73.7.tgz",
+ "integrity": "sha512-gZYIu9JAqEI9Rxi0xGMuMW6QsHGbMSptozlTOwOd7T7yXX3WwYS/I3yLPbLhbZTjOhwMHkTt8Nhm2qBo8nh14g==",
"dependencies": {
- "@babel/core": "^7.14.0",
- "@babel/generator": "^7.14.0",
- "@babel/parser": "^7.14.0",
- "@babel/types": "^7.0.0",
+ "@babel/core": "^7.20.0",
+ "@babel/generator": "^7.20.0",
+ "@babel/parser": "^7.20.0",
+ "@babel/types": "^7.20.0",
"babel-preset-fbjs": "^3.4.0",
- "metro": "0.72.3",
- "metro-babel-transformer": "0.72.3",
- "metro-cache": "0.72.3",
- "metro-cache-key": "0.72.3",
- "metro-hermes-compiler": "0.72.3",
- "metro-source-map": "0.72.3",
- "metro-transform-plugins": "0.72.3",
+ "metro": "0.73.7",
+ "metro-babel-transformer": "0.73.7",
+ "metro-cache": "0.73.7",
+ "metro-cache-key": "0.73.7",
+ "metro-hermes-compiler": "0.73.7",
+ "metro-source-map": "0.73.7",
+ "metro-transform-plugins": "0.73.7",
"nullthrows": "^1.1.1"
}
},
@@ -16200,13 +16158,16 @@
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
},
"node_modules/metro/node_modules/cliui": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
- "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"dependencies": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
}
},
"node_modules/metro/node_modules/color-convert": {
@@ -16233,29 +16194,11 @@
"ms": "2.0.0"
}
},
- "node_modules/metro/node_modules/decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==",
- "engines": {
- "node": ">=0.10.0"
- }
- },
"node_modules/metro/node_modules/emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
- "node_modules/metro/node_modules/fs-extra": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
- "integrity": "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==",
- "dependencies": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^2.1.0",
- "klaw": "^1.0.0"
- }
- },
"node_modules/metro/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -16299,20 +16242,12 @@
"url": "https://github.com/chalk/supports-color?sponsor=1"
}
},
- "node_modules/metro/node_modules/jsonfile": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
- "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==",
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
- }
- },
"node_modules/metro/node_modules/metro-react-native-babel-preset": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.72.3.tgz",
- "integrity": "sha512-uJx9y/1NIqoYTp6ZW1osJ7U5ZrXGAJbOQ/Qzl05BdGYvN1S7Qmbzid6xOirgK0EIT0pJKEEh1s8qbassYZe4cw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.7.tgz",
+ "integrity": "sha512-RKcmRZREjJCzHKP+JhC9QTCohkeb3xa/DtqHU14U5KWzJHdC0mMrkTZYNXhV0cryxsaVKVEw5873KhbZyZHMVw==",
"dependencies": {
- "@babel/core": "^7.14.0",
+ "@babel/core": "^7.20.0",
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
@@ -16322,7 +16257,7 @@
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-export-default-from": "^7.0.0",
- "@babel/plugin-syntax-flow": "^7.2.0",
+ "@babel/plugin-syntax-flow": "^7.18.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-syntax-optional-chaining": "^7.0.0",
"@babel/plugin-transform-arrow-functions": "^7.0.0",
@@ -16331,7 +16266,6 @@
"@babel/plugin-transform-classes": "^7.0.0",
"@babel/plugin-transform-computed-properties": "^7.0.0",
"@babel/plugin-transform-destructuring": "^7.0.0",
- "@babel/plugin-transform-exponentiation-operator": "^7.0.0",
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
"@babel/plugin-transform-function-name": "^7.0.0",
"@babel/plugin-transform-literals": "^7.0.0",
@@ -16361,17 +16295,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "node_modules/metro/node_modules/rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "dependencies": {
- "glob": "^7.1.3"
- },
- "bin": {
- "rimraf": "bin.js"
- }
- },
"node_modules/metro/node_modules/serialize-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
@@ -16412,55 +16335,29 @@
"node": ">=8"
}
},
- "node_modules/metro/node_modules/wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/metro/node_modules/y18n": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
- "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
- },
"node_modules/metro/node_modules/yargs": {
- "version": "15.4.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
- "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
"dependencies": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
},
"engines": {
- "node": ">=8"
+ "node": ">=12"
}
},
"node_modules/metro/node_modules/yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "dependencies": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- },
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
"engines": {
- "node": ">=6"
+ "node": ">=12"
}
},
"node_modules/mhchemparser": {
@@ -16832,9 +16729,9 @@
}
},
"node_modules/nock": {
- "version": "13.2.9",
- "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.9.tgz",
- "integrity": "sha512-1+XfJNYF1cjGB+TKMWi29eZ0b82QOvQs2YoLNzbpWGqFMtRQHTa57osqdGj4FrFPgkO4D4AZinzUJR9VvW3QUA==",
+ "version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.0.tgz",
+ "integrity": "sha512-HHqYQ6mBeiMc+N038w8LkMpDCRquCHWeNmN3v6645P3NhN2+qXOBqvPqo7Rt1VyCMzKhJ733wZqw5B7cQVFNPg==",
"dev": true,
"dependencies": {
"debug": "^4.1.0",
@@ -16996,9 +16893,9 @@
}
},
"node_modules/ob1": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.72.3.tgz",
- "integrity": "sha512-OnVto25Sj7Ghp0vVm2THsngdze3tVq0LOg9LUHsAVXMecpqOP0Y8zaATW8M9gEgs2lNEAcCqV0P/hlmOPhVRvg=="
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.73.7.tgz",
+ "integrity": "sha512-DfelfvR843KADhSUATGGhuepVMRcf5VQX+6MQLy5AW0BKDLlO7Usj6YZeAAZP7P86QwsoTxB0RXCFiA7t6S1IQ=="
},
"node_modules/object-assign": {
"version": "4.1.1",
@@ -17912,7 +17809,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
- "dev": true,
"dependencies": {
"@jest/schemas": "^29.0.0",
"ansi-styles": "^5.0.0",
@@ -17926,7 +17822,6 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true,
"engines": {
"node": ">=10"
},
@@ -17937,8 +17832,7 @@
"node_modules/pretty-format/node_modules/react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
- "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
- "dev": true
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
},
"node_modules/prismjs": {
"version": "1.27.0",
@@ -18149,7 +18043,6 @@
"version": "4.27.1",
"resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.27.1.tgz",
"integrity": "sha512-qXhcxxDWiFmFAOq48jts9YQYe1+wVoUXzJTlY4jbaATzyio6dd6CUGu3dXBhREeVgpZ+y4kg6vFJzIOZh6vY2w==",
- "dev": true,
"dependencies": {
"shell-quote": "^1.6.1",
"ws": "^7"
@@ -18224,42 +18117,44 @@
"integrity": "sha512-txfpPCQYiazVdcbMRhatqWKcAxJweUu2wDXvts5/7Wyp6+Y9cHojqXHsLPEckzutfHlxZhG8Oiundbmp8Fd6eQ=="
},
"node_modules/react-native": {
- "version": "0.70.6",
- "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.70.6.tgz",
- "integrity": "sha512-xtQdImPHnwgraEx3HIZFOF+D1hJ9bC5mfpIdUGoMHRws6OmvHAjmFpO6qfdnaQ29vwbmZRq7yf14sbury74R/w==",
+ "version": "0.71.1",
+ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.71.1.tgz",
+ "integrity": "sha512-bLP5+IBj2IX6tgF9WnC/UL2ZPYkVUPsU4xqZV1jntTC2TH4xyLrvfKACjGlz5nQ3Mx4BmOFqsnMxithm53+6Aw==",
"dependencies": {
- "@jest/create-cache-key-function": "^27.0.1",
- "@react-native-community/cli": "9.3.2",
- "@react-native-community/cli-platform-android": "9.3.1",
- "@react-native-community/cli-platform-ios": "9.3.0",
+ "@jest/create-cache-key-function": "^29.2.1",
+ "@react-native-community/cli": "10.1.3",
+ "@react-native-community/cli-platform-android": "10.1.3",
+ "@react-native-community/cli-platform-ios": "10.1.1",
"@react-native/assets": "1.0.0",
- "@react-native/normalize-color": "2.0.0",
+ "@react-native/normalize-color": "2.1.0",
"@react-native/polyfills": "2.0.0",
"abort-controller": "^3.0.0",
"anser": "^1.4.9",
"base64-js": "^1.1.2",
+ "deprecated-react-native-prop-types": "^3.0.1",
"event-target-shim": "^5.0.1",
"invariant": "^2.2.4",
+ "jest-environment-node": "^29.2.1",
"jsc-android": "^250230.2.1",
"memoize-one": "^5.0.0",
- "metro-react-native-babel-transformer": "0.72.3",
- "metro-runtime": "0.72.3",
- "metro-source-map": "0.72.3",
+ "metro-react-native-babel-transformer": "0.73.7",
+ "metro-runtime": "0.73.7",
+ "metro-source-map": "0.73.7",
"mkdirp": "^0.5.1",
"nullthrows": "^1.1.1",
"pretty-format": "^26.5.2",
"promise": "^8.3.0",
- "react-devtools-core": "4.24.0",
- "react-native-codegen": "^0.70.6",
- "react-native-gradle-plugin": "^0.70.3",
+ "react-devtools-core": "^4.26.1",
+ "react-native-codegen": "^0.71.3",
+ "react-native-gradle-plugin": "^0.71.13",
"react-refresh": "^0.4.0",
"react-shallow-renderer": "^16.15.0",
"regenerator-runtime": "^0.13.2",
- "scheduler": "^0.22.0",
+ "scheduler": "^0.23.0",
"stacktrace-parser": "^0.1.3",
"use-sync-external-store": "^1.0.0",
"whatwg-fetch": "^3.0.0",
- "ws": "^6.1.4"
+ "ws": "^6.2.2"
},
"bin": {
"react-native": "cli.js"
@@ -18268,7 +18163,7 @@
"node": ">=14"
},
"peerDependencies": {
- "react": "18.1.0"
+ "react": "18.2.0"
}
},
"node_modules/react-native-android-open-settings": {
@@ -18327,12 +18222,12 @@
}
},
"node_modules/react-native-codegen": {
- "version": "0.70.6",
- "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.70.6.tgz",
- "integrity": "sha512-kdwIhH2hi+cFnG5Nb8Ji2JwmcCxnaOOo9440ov7XDzSvGfmUStnCzl+MCW8jLjqHcE4icT7N9y+xx4f50vfBTw==",
+ "version": "0.71.3",
+ "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.71.3.tgz",
+ "integrity": "sha512-5AvdHVU1sAaXg05i0dG664ZTaCaIFaY1znV5vNsj+wUu6MGxNEUNbDKk9dxKUkkxOyk2KZOK5uhzWL0p5H5yZQ==",
"dependencies": {
"@babel/parser": "^7.14.0",
- "flow-parser": "^0.121.0",
+ "flow-parser": "^0.185.0",
"jscodeshift": "^0.13.1",
"nullthrows": "^1.1.1"
}
@@ -18453,9 +18348,9 @@
"integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs="
},
"node_modules/react-native-gesture-handler": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.8.0.tgz",
- "integrity": "sha512-poOSfz/w0IyD6Qwq7aaIRRfEaVTl1ecQFoyiIbpOpfNTjm2B1niY2FLrdVQIOtIOe+K9nH55Qal04nr4jGkHdQ==",
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.9.0.tgz",
+ "integrity": "sha512-a0BcH3Qb1tgVqUutc6d3VuWQkI1AM3+fJx8dkxzZs9t06qA27QgURYFoklpabuWpsUTzuKRpxleykp25E8m7tg==",
"dependencies": {
"@egjs/hammerjs": "^2.0.17",
"hoist-non-react-statics": "^3.3.0",
@@ -18469,9 +18364,9 @@
}
},
"node_modules/react-native-gradle-plugin": {
- "version": "0.70.3",
- "resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz",
- "integrity": "sha512-oOanj84fJEXUg9FoEAQomA8ISG+DVIrTZ3qF7m69VQUJyOGYyDZmPqKcjvRku4KXlEH6hWO9i4ACLzNBh8gC0A=="
+ "version": "0.71.13",
+ "resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.13.tgz",
+ "integrity": "sha512-C66LNZAXbU0YDRkWx8d/8kjesdu7fsUAc/3QPJNftSXKEvEtnFZK2aH/rIgu1s5dbTcE0fjhdVPNJMRIfKo61w=="
},
"node_modules/react-native-haptic-feedback": {
"version": "1.14.0",
@@ -18490,9 +18385,9 @@
}
},
"node_modules/react-native-image-picker": {
- "version": "4.10.3",
- "resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-4.10.3.tgz",
- "integrity": "sha512-gLX8J6jCBkUt6jogpSdA7YyaGVLGYywRzMEwBciXshihpFZjc/cRlKymAVlu6Q7HMw0j3vrho6pI8ZGC5O/FGg==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-5.0.1.tgz",
+ "integrity": "sha512-+poQTHOnEGrbxJnut591XA9006svFOyfPg/i5bv+fLuwoSHh5HW0E/PVhvT8lbX0Z5C108vh3DAsnrfFFnPBGw==",
"peerDependencies": {
"react": "*",
"react-native": "*"
@@ -18589,9 +18484,9 @@
}
},
"node_modules/react-native-navigation": {
- "version": "7.30.6",
- "resolved": "https://registry.npmjs.org/react-native-navigation/-/react-native-navigation-7.30.6.tgz",
- "integrity": "sha512-rnJ7VbMjnt8H1HkuaM65NkcFFca2QQRgsCQEF6yAe9J4Yb3I3XnywFd309D6yso4ZqRuK7EhuzP33/nReV1c/A==",
+ "version": "7.31.1",
+ "resolved": "https://registry.npmjs.org/react-native-navigation/-/react-native-navigation-7.31.1.tgz",
+ "integrity": "sha512-thChSqaoi/QHGGofG/4CEyO2v6ko41RsbjQrJzAnHkp7iw1K8pjxkW3KX0qx2rlR/A69kA31VskOLj8kl+7sQw==",
"dependencies": {
"hoist-non-react-statics": "3.x.x",
"lodash": "4.17.x",
@@ -18655,13 +18550,13 @@
}
},
"node_modules/react-native-reanimated": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.13.0.tgz",
- "integrity": "sha512-yUHyYVIegWWIza4+nVyS3CSmI/Mc8kLFVHw2c6gnSHaYhYA4LeEjH/jBkoMzHk9Xd0Ra3cwtjYKAMG8OTp6JVg==",
+ "version": "2.14.4",
+ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.14.4.tgz",
+ "integrity": "sha512-DquSbl7P8j4SAmc+kRdd75Ianm8G+IYQ9T4AQ6lrpLVeDkhZmjWI0wkutKWnp6L7c5XNVUrFDUf69dwETLCItQ==",
"dependencies": {
"@babel/plugin-transform-object-assign": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
- "@types/invariant": "^2.2.35",
+ "convert-source-map": "^1.7.0",
"invariant": "^2.2.4",
"lodash.isequal": "^4.5.0",
"setimmediate": "^1.0.5",
@@ -18674,18 +18569,18 @@
}
},
"node_modules/react-native-safe-area-context": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz",
- "integrity": "sha512-N9XTjiuD73ZpVlejHrUWIFZc+6Z14co1K/p1IFMkImU7+avD69F3y+lhkqA2hN/+vljdZrBSiOwXPkuo43nFQA==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.5.0.tgz",
+ "integrity": "sha512-0WORnk9SkREGUg2V7jHZbuN5x4vcxj/1B0QOcXJjdYWrzZHgLcUzYWWIUecUPJh747Mwjt/42RZDOaFn3L8kPQ==",
"peerDependencies": {
"react": "*",
"react-native": "*"
}
},
"node_modules/react-native-screens": {
- "version": "3.18.2",
- "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.18.2.tgz",
- "integrity": "sha512-ANUEuvMUlsYJ1QKukEhzhfrvOUO9BVH9Nzg+6eWxpn3cfD/O83yPBOF8Mx6x5H/2+sMy+VS5x/chWOOo/U7QJw==",
+ "version": "3.19.0",
+ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.19.0.tgz",
+ "integrity": "sha512-Ehsmy7jr3H3j5pmN+/FqsAaIAD+k+xkcdePfLcg4rYRbN5X7fJPgaqhcmiCcZ0YxsU8ttsstP9IvRLNQuIkRRA==",
"dependencies": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -18726,9 +18621,9 @@
}
},
"node_modules/react-native-svg": {
- "version": "13.6.0",
- "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.6.0.tgz",
- "integrity": "sha512-1wjHCMJ8siyZbDZ0MX5wM+Jr7YOkb6GADn4/Z+/u1UwJX8WfjarypxDF3UO1ugMHa+7qor39oY+URMcrgPpiww==",
+ "version": "13.7.0",
+ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.7.0.tgz",
+ "integrity": "sha512-WR5CIURvee5cAfvMhmdoeOjh1SC8KdLq5u5eFsz4pbYzCtIFClGSkLnNgkMSDMVV5LV0qQa4jeIk75ieIBzaDA==",
"dependencies": {
"css-select": "^5.1.0",
"css-tree": "^1.1.3"
@@ -18860,9 +18755,9 @@
}
},
"node_modules/react-native-walkthrough-tooltip": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/react-native-walkthrough-tooltip/-/react-native-walkthrough-tooltip-1.4.0.tgz",
- "integrity": "sha512-nyBuynmCuzPKJN9NRGhSzCutGOk7/WqszGtX01gjDtlRfoJ25cSM0h+TEi/lsLbSCTEdB+e65qOTvoVhIq2gzA==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/react-native-walkthrough-tooltip/-/react-native-walkthrough-tooltip-1.5.0.tgz",
+ "integrity": "sha512-xzpTs3JQkUMkmurc7WJDSAWaH2KRiRL2YoTXVCRqEEWxIvLQTn9eQv0jBzs1geR0wL+ezRpjkBEGAlfQ6eMimw==",
"dependencies": {
"prop-types": "^15.6.1",
"react-fast-compare": "^2.0.4"
@@ -18987,6 +18882,16 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "node_modules/react-native/node_modules/deprecated-react-native-prop-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-3.0.1.tgz",
+ "integrity": "sha512-J0jCJcsk4hMlIb7xwOZKLfMpuJn6l8UtrPEzzQV5ewz5gvKNYakhBuq9h2rWX7YwHHJZFhU5W8ye7dB9oN8VcQ==",
+ "dependencies": {
+ "@react-native/normalize-color": "*",
+ "invariant": "*",
+ "prop-types": "*"
+ }
+ },
"node_modules/react-native/node_modules/has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -19009,35 +18914,6 @@
"node": ">= 10"
}
},
- "node_modules/react-native/node_modules/react-devtools-core": {
- "version": "4.24.0",
- "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.24.0.tgz",
- "integrity": "sha512-Rw7FzYOOzcfyUPaAm9P3g0tFdGqGq2LLiAI+wjYcp6CsF3DeeMrRS3HZAho4s273C29G/DJhx0e8BpRE/QZNGg==",
- "dependencies": {
- "shell-quote": "^1.6.1",
- "ws": "^7"
- }
- },
- "node_modules/react-native/node_modules/react-devtools-core/node_modules/ws": {
- "version": "7.5.9",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
- "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
- "engines": {
- "node": ">=8.3.0"
- },
- "peerDependencies": {
- "bufferutil": "^4.0.1",
- "utf-8-validate": "^5.0.2"
- },
- "peerDependenciesMeta": {
- "bufferutil": {
- "optional": true
- },
- "utf-8-validate": {
- "optional": true
- }
- }
- },
"node_modules/react-native/node_modules/react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@@ -19117,15 +18993,6 @@
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
},
- "node_modules/react-test-renderer/node_modules/scheduler": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
- "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
- "dev": true,
- "dependencies": {
- "loose-envify": "^1.1.0"
- }
- },
"node_modules/read-env": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/read-env/-/read-env-1.3.0.tgz",
@@ -19388,9 +19255,9 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"node_modules/reselect": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
- "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==",
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
+ "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==",
"dev": true
},
"node_modules/resolve": {
@@ -19507,7 +19374,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
"dependencies": {
"glob": "^7.1.3"
},
@@ -19610,9 +19476,9 @@
}
},
"node_modules/scheduler": {
- "version": "0.22.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.22.0.tgz",
- "integrity": "sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==",
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"dependencies": {
"loose-envify": "^1.1.0"
}
@@ -20292,7 +20158,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz",
"integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==",
- "dev": true,
"dependencies": {
"escape-string-regexp": "^2.0.0"
},
@@ -20304,7 +20169,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
"integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
- "dev": true,
"engines": {
"node": ">=8"
}
@@ -20768,8 +20632,6 @@
"version": "5.15.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
"integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
- "dev": true,
- "peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0",
@@ -20881,9 +20743,7 @@
"node_modules/terser/node_modules/commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true,
- "peer": true
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
},
"node_modules/test-exclude": {
"version": "6.0.0",
@@ -21082,15 +20942,15 @@
}
},
"node_modules/ts-jest": {
- "version": "29.0.3",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
- "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
+ "version": "29.0.5",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz",
+ "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==",
"dev": true,
"dependencies": {
"bs-logger": "0.x",
"fast-json-stable-stringify": "2.x",
"jest-util": "^29.0.0",
- "json5": "^2.2.1",
+ "json5": "^2.2.3",
"lodash.memoize": "4.x",
"make-error": "1.x",
"semver": "7.x",
@@ -21151,9 +21011,9 @@
}
},
"node_modules/tsconfig-paths/node_modules/json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"dependencies": {
"minimist": "^1.2.0"
@@ -21213,7 +21073,6 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
"integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
- "dev": true,
"engines": {
"node": ">=4"
}
@@ -22158,9 +22017,9 @@
}
},
"node_modules/zod": {
- "version": "3.19.1",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.19.1.tgz",
- "integrity": "sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA==",
+ "version": "3.20.2",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.20.2.tgz",
+ "integrity": "sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ==",
"funding": {
"url": "https://github.com/sponsors/colinhacks"
}
@@ -22322,9 +22181,9 @@
}
},
"@babel/helper-create-class-features-plugin": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.7.tgz",
- "integrity": "sha512-LtoWbDXOaidEf50hmdDqn9g8VEzsorMexoWMQdQODbvmqYmaF23pBP5VNPAGIFHsFQCIeKokDiz3CH5Y2jlY6w==",
+ "version": "7.20.12",
+ "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.20.12.tgz",
+ "integrity": "sha512-9OunRkbT0JQcednL0UFvbfXpAsUXiGjUk0a7sN8fUXX7Mue79cUSMjHGDRRi/Vz9vYlpIhLV5fMD5dKoMhhsNQ==",
"requires": {
"@babel/helper-annotate-as-pure": "^7.18.6",
"@babel/helper-environment-visitor": "^7.18.9",
@@ -22332,6 +22191,7 @@
"@babel/helper-member-expression-to-functions": "^7.20.7",
"@babel/helper-optimise-call-expression": "^7.18.6",
"@babel/helper-replace-supers": "^7.20.7",
+ "@babel/helper-skip-transparent-expression-wrappers": "^7.20.0",
"@babel/helper-split-export-declaration": "^7.18.6"
}
},
@@ -22471,11 +22331,11 @@
}
},
"@babel/helper-skip-transparent-expression-wrappers": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz",
- "integrity": "sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw==",
+ "version": "7.20.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.20.0.tgz",
+ "integrity": "sha512-5y1JYeNKfvnT8sZcK9DVRtpTbGiomYIHviSP3OQWmDPU3DeH4a1ZlT/N2lyQ5P8egjcRaT/Y9aNqUxK0WsnIIg==",
"requires": {
- "@babel/types": "^7.18.9"
+ "@babel/types": "^7.20.0"
}
},
"@babel/helper-split-export-declaration": {
@@ -22586,12 +22446,12 @@
}
},
"@babel/plugin-proposal-decorators": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.7.tgz",
- "integrity": "sha512-JB45hbUweYpwAGjkiM7uCyXMENH2lG+9r3G2E+ttc2PRXAoEkpfd/KW5jDg4j8RS6tLtTG1jZi9LbHZVSfs1/A==",
+ "version": "7.20.13",
+ "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.20.13.tgz",
+ "integrity": "sha512-7T6BKHa9Cpd7lCueHBBzP0nkXNina+h5giOZw+a8ZpMfPFY19VjJAjIxyFHuWkhCWgL6QMqRiY/wB1fLXzm6Mw==",
"dev": true,
"requires": {
- "@babel/helper-create-class-features-plugin": "^7.20.7",
+ "@babel/helper-create-class-features-plugin": "^7.20.12",
"@babel/helper-plugin-utils": "^7.20.2",
"@babel/helper-replace-supers": "^7.20.7",
"@babel/helper-split-export-declaration": "^7.18.6",
@@ -23417,9 +23277,9 @@
}
},
"@babel/runtime": {
- "version": "7.20.7",
- "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.7.tgz",
- "integrity": "sha512-UF0tvkUtxwAgZ5W/KrkHf0Rn0fdnLDU9ScxBrEVNUprE/MzirjK4MJUX1/BVDv00Sv8cljtukVK1aky++X1SjQ==",
+ "version": "7.20.13",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.13.tgz",
+ "integrity": "sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA==",
"requires": {
"regenerator-runtime": "^0.13.11"
}
@@ -23921,83 +23781,17 @@
}
},
"@jest/create-cache-key-function": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz",
- "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==",
+ "version": "29.3.1",
+ "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-29.3.1.tgz",
+ "integrity": "sha512-4i+E+E40gK13K78ffD/8cy4lSSqeWwyXeTZoq16tndiCP12hC8uQsPJdIu5C6Kf22fD8UbBk71so7s/6VwpUOQ==",
"requires": {
- "@jest/types": "^27.5.1"
- },
- "dependencies": {
- "@jest/types": {
- "version": "27.5.1",
- "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz",
- "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==",
- "requires": {
- "@types/istanbul-lib-coverage": "^2.0.0",
- "@types/istanbul-reports": "^3.0.0",
- "@types/node": "*",
- "@types/yargs": "^16.0.0",
- "chalk": "^4.0.0"
- }
- },
- "@types/yargs": {
- "version": "16.0.4",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
- "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
- "requires": {
- "@types/yargs-parser": "*"
- }
- },
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
- "chalk": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
- "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "requires": {
- "ansi-styles": "^4.1.0",
- "supports-color": "^7.1.0"
- }
- },
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
- "has-flag": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
- },
- "supports-color": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
- "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "requires": {
- "has-flag": "^4.0.0"
- }
- }
+ "@jest/types": "^29.3.1"
}
},
"@jest/environment": {
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz",
"integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==",
- "dev": true,
"requires": {
"@jest/fake-timers": "^29.3.1",
"@jest/types": "^29.3.1",
@@ -24028,7 +23822,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz",
"integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==",
- "dev": true,
"requires": {
"@jest/types": "^29.3.1",
"@sinonjs/fake-timers": "^9.1.2",
@@ -24143,7 +23936,6 @@
"version": "29.0.0",
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz",
"integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==",
- "dev": true,
"requires": {
"@sinclair/typebox": "^0.24.1"
}
@@ -24281,7 +24073,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz",
"integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==",
- "dev": true,
"requires": {
"@jest/schemas": "^29.0.0",
"@types/istanbul-lib-coverage": "^2.0.0",
@@ -24295,7 +24086,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"requires": {
"color-convert": "^2.0.1"
}
@@ -24304,7 +24094,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -24314,7 +24103,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"requires": {
"color-name": "~1.1.4"
}
@@ -24322,20 +24110,17 @@
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"requires": {
"has-flag": "^4.0.0"
}
@@ -24366,8 +24151,6 @@
"version": "0.3.2",
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.2.tgz",
"integrity": "sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw==",
- "dev": true,
- "peer": true,
"requires": {
"@jridgewell/gen-mapping": "^0.3.0",
"@jridgewell/trace-mapping": "^0.3.9"
@@ -24414,38 +24197,38 @@
"integrity": "sha512-qCZjvU6Vsl7cg/0urrq8ItK5CXnt3DqjFq/w9mBpWuem/YhMWLMVBoSuASAx9S2HV7Vr/iMdsMGWH/4qXkXCBg=="
},
"@mattermost/react-native-emm": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-emm/-/react-native-emm-1.3.3.tgz",
- "integrity": "sha512-mOPlp3C0ba1XOANTYi3i2dL9gBdQLoJZ4zvOzhqYeg5FQXBXXoJomPKAzxJH27aX3k92bu+U0BmEbnKIitKKEA==",
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-emm/-/react-native-emm-1.3.4.tgz",
+ "integrity": "sha512-xdFPfAH3d9pa1og6rr+kHCWlLYMnHe7kY1IxIjhvfZ28ElNExjOhOF7JOL/s4RUvk8bZS7H72+ldRYZ6ERHlWw==",
"requires": {}
},
"@mattermost/react-native-network-client": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.0.2.tgz",
- "integrity": "sha512-ywVxTKPT1A8eEccPpCrHXYqO9BvvEx+xdecn/VILUDeEIfpOVETLh5952SQjoc3PP0RRME0bv92+fzoxiOZ4YQ==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-network-client/-/react-native-network-client-1.1.0.tgz",
+ "integrity": "sha512-iZemjWqUaGkfSY+7Ve+m6MUJc8blUOzHoY9J5miKjez7QPiknYGMIdVFMYAiuO9jUtgQ4XSG7/nENqYR5jSwCg==",
"requires": {
"validator": "13.7.0",
- "zod": "3.19.1"
+ "zod": "3.20.2"
}
},
"@mattermost/react-native-paste-input": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-paste-input/-/react-native-paste-input-0.5.2.tgz",
- "integrity": "sha512-aQdLUidSAbWPLXWmwM1x8AhnZIO4EN5uWx813/G3+mL8kWD7mpXrQEvMpcdtKWatD705kCyKZkvnNY4yjq0TkA==",
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-paste-input/-/react-native-paste-input-0.6.0.tgz",
+ "integrity": "sha512-Hy4w8RaiiXl2AKcLXT0FjJJsh4FXtLiWCxfh6zaBtCkx7jsr4d9xwJ/zqrnjv0jkG7XbRUCp40dgNBpWYZ1pyQ==",
"requires": {
- "deprecated-react-native-prop-types": "^2.3.0"
+ "semver": "7.3.8"
}
},
"@mattermost/react-native-turbo-log": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-log/-/react-native-turbo-log-0.2.1.tgz",
- "integrity": "sha512-c5Wx82gYLEUY70lIoA3jWg2sWo+l/Ah8vAfvu2cYkGnX4NArB/NKWnC4GWaclDSuNO4Tm5DrXgFeSqqArs7IJQ==",
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-log/-/react-native-turbo-log-0.2.2.tgz",
+ "integrity": "sha512-UjatbzMyB3jp/tAI1B8lmqZtF8om103hzUAlRVnUIPvzDQl5u2OtiwkwdYlnyN1P72WiIKhNcx7W+NZO0/wjyg==",
"requires": {}
},
"@mattermost/react-native-turbo-mailer": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-mailer/-/react-native-turbo-mailer-0.2.0.tgz",
- "integrity": "sha512-KMrEkMa30zjFv8ofvQsE1c1ln+8ntGDKJWDjScK02jvN3rtD8jMz1derz1py8tbDU9uU2nQPqWu4lP4b3g27Tw==",
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/@mattermost/react-native-turbo-mailer/-/react-native-turbo-mailer-0.2.3.tgz",
+ "integrity": "sha512-m49wYLOx6TCiv5IDZKNAzhY8hnib+CgZ31jenR5rMiEmykmnI4VIyan1nNcPTyZPRGGmBb4UYzrcPd3hdIaOSg==",
"requires": {}
},
"@msgpack/msgpack": {
@@ -24506,28 +24289,18 @@
"integrity": "sha512-wKTFGvgf5V+bYlhXdukOWKH0XgdG0NmUQwLWG7w5Yk4EUeQS29D5uWPCeWT1Ac/NzDKuHsYP6KVOJDbJSauAAg=="
},
"@nozbe/watermelondb": {
- "version": "0.24.0",
- "resolved": "https://registry.npmjs.org/@nozbe/watermelondb/-/watermelondb-0.24.0.tgz",
- "integrity": "sha512-CPCsRLQY2Lyq1MwUeK6zDsjfMKpW2KWYQJlF+ijGeKWv84xND0QC6a6EBWWiflvcdAwLSuGclojoah1HZYfs0g==",
+ "version": "0.25.1",
+ "resolved": "https://registry.npmjs.org/@nozbe/watermelondb/-/watermelondb-0.25.1.tgz",
+ "integrity": "sha512-Yd4gXttVlfl2e8rDsduTmPWgZWidaVAMpDcJr1fmsmHJQnNWdYRR+1V07Io4muNMSSq7rdn0Yl8GHNpNzN+rfQ==",
"requires": {
"@babel/runtime": "^7.11.2",
"@nozbe/simdjson": "1.0.0",
"@nozbe/sqlite": "3.36.0",
- "@nozbe/with-observables": "1.4.0",
+ "@nozbe/with-observables": "1.4.1",
"hoist-non-react-statics": "^3.3.2",
- "lokijs": "npm:@nozbe/lokijs@1.5.12-wmelon4",
- "rxjs": "^7.3.0",
+ "lokijs": "npm:@nozbe/lokijs@1.5.12-wmelon6",
+ "rxjs": "^7.4.0",
"sql-escape-string": "^1.1.0"
- },
- "dependencies": {
- "@nozbe/with-observables": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/@nozbe/with-observables/-/with-observables-1.4.0.tgz",
- "integrity": "sha512-vzc0QiYcXK/GmflBGBXTs02ayL25e1l4Cr9aYgSuYCZVqpyMfep9xp89RygNbiibAfVLbgEUa7thxlm3jw8hFw==",
- "requires": {
- "hoist-non-react-statics": "^3.3.2"
- }
- }
}
},
"@nozbe/with-observables": {
@@ -24539,9 +24312,9 @@
}
},
"@react-native-camera-roll/camera-roll": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-camera-roll/camera-roll/-/camera-roll-5.2.1.tgz",
- "integrity": "sha512-axWwlLj/3E5PIjXcN2y2XZzK/hYTx73kDlQJpHpcurejmQR9sU22w3cs+YltaNkZGl3y7Eu/LbiPEkGIwNVQow==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/@react-native-camera-roll/camera-roll/-/camera-roll-5.2.2.tgz",
+ "integrity": "sha512-LVzUX1KdKvOXJGiV/9tlkDyDSOEjvAzuiV8OkSUD13TXN/Tk5u2KVHTYRYJz5pmXanLN2dmEamctJcqKCeXYxg==",
"requires": {}
},
"@react-native-clipboard/clipboard": {
@@ -24551,21 +24324,21 @@
"requires": {}
},
"@react-native-community/cli": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-9.3.2.tgz",
- "integrity": "sha512-IAW4X0vmX/xozNpp/JVZaX7MrC85KV0OP2DF4o7lNGOfpUhzJAEWqTfkxFYS+VsRjZHDve4wSTiGIuXwE7FG1w==",
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli/-/cli-10.1.3.tgz",
+ "integrity": "sha512-kzh6bYLGN1q1q0IiczKSP1LTrovFeVzppYRTKohPI9VdyZwp7b5JOgaQMB/Ijtwm3MxBDrZgV9AveH/eUmUcKQ==",
"requires": {
- "@react-native-community/cli-clean": "^9.2.1",
- "@react-native-community/cli-config": "^9.2.1",
- "@react-native-community/cli-debugger-ui": "^9.0.0",
- "@react-native-community/cli-doctor": "^9.3.0",
- "@react-native-community/cli-hermes": "^9.3.1",
- "@react-native-community/cli-plugin-metro": "^9.2.1",
- "@react-native-community/cli-server-api": "^9.2.1",
- "@react-native-community/cli-tools": "^9.2.1",
- "@react-native-community/cli-types": "^9.1.0",
+ "@react-native-community/cli-clean": "^10.1.1",
+ "@react-native-community/cli-config": "^10.1.1",
+ "@react-native-community/cli-debugger-ui": "^10.0.0",
+ "@react-native-community/cli-doctor": "^10.1.1",
+ "@react-native-community/cli-hermes": "^10.1.3",
+ "@react-native-community/cli-plugin-metro": "^10.1.1",
+ "@react-native-community/cli-server-api": "^10.1.1",
+ "@react-native-community/cli-tools": "^10.1.1",
+ "@react-native-community/cli-types": "^10.0.0",
"chalk": "^4.1.2",
- "commander": "^9.4.0",
+ "commander": "^9.4.1",
"execa": "^1.0.0",
"find-up": "^4.1.0",
"fs-extra": "^8.1.0",
@@ -24605,9 +24378,9 @@
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"commander": {
- "version": "9.4.1",
- "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz",
- "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw=="
+ "version": "9.5.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.5.0.tgz",
+ "integrity": "sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ=="
},
"cross-spawn": {
"version": "6.0.5",
@@ -24699,11 +24472,11 @@
}
},
"@react-native-community/cli-clean": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-9.2.1.tgz",
- "integrity": "sha512-dyNWFrqRe31UEvNO+OFWmQ4hmqA07bR9Ief/6NnGwx67IO9q83D5PEAf/o96ML6jhSbDwCmpPKhPwwBbsyM3mQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-clean/-/cli-clean-10.1.1.tgz",
+ "integrity": "sha512-iNsrjzjIRv9yb5y309SWJ8NDHdwYtnCpmxZouQDyOljUdC9MwdZ4ChbtA4rwQyAwgOVfS9F/j56ML3Cslmvrxg==",
"requires": {
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"execa": "^1.0.0",
"prompts": "^2.4.0"
@@ -24812,40 +24585,84 @@
}
},
"@react-native-community/cli-config": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-9.2.1.tgz",
- "integrity": "sha512-gHJlBBXUgDN9vrr3aWkRqnYrPXZLztBDQoY97Mm5Yo6MidsEpYo2JIP6FH4N/N2p1TdjxJL4EFtdd/mBpiR2MQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-config/-/cli-config-10.1.1.tgz",
+ "integrity": "sha512-p4mHrjC+s/ayiNVG6T35GdEGdP6TuyBUg5plVGRJfTl8WT6LBfLYLk+fz/iETrEZ/YkhQIsQcEUQC47MqLNHog==",
"requires": {
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-tools": "^10.1.1",
+ "chalk": "^4.1.2",
"cosmiconfig": "^5.1.0",
"deepmerge": "^3.2.0",
"glob": "^7.1.3",
"joi": "^17.2.1"
},
"dependencies": {
+ "ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "requires": {
+ "color-convert": "^2.0.1"
+ }
+ },
+ "chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "requires": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ }
+ },
+ "color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "requires": {
+ "color-name": "~1.1.4"
+ }
+ },
+ "color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+ },
"deepmerge": {
"version": "3.3.0",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-3.3.0.tgz",
"integrity": "sha512-GRQOafGHwMHpjPx9iCvTgpu9NojZ49q794EEL94JVEw6VaeA8XTUyBKvAkOOjBX9oJNiV6G3P+T+tihFjo2TqA=="
+ },
+ "has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
+ },
+ "supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "requires": {
+ "has-flag": "^4.0.0"
+ }
}
}
},
"@react-native-community/cli-debugger-ui": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-9.0.0.tgz",
- "integrity": "sha512-7hH05ZwU9Tp0yS6xJW0bqcZPVt0YCK7gwj7gnRu1jDNN2kughf6Lg0Ys29rAvtZ7VO1PK5c1O+zs7yFnylQDUA==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-debugger-ui/-/cli-debugger-ui-10.0.0.tgz",
+ "integrity": "sha512-8UKLcvpSNxnUTRy8CkCl27GGLqZunQ9ncGYhSrWyKrU9SWBJJGeZwi2k2KaoJi5FvF2+cD0t8z8cU6lsq2ZZmA==",
"requires": {
"serve-static": "^1.13.1"
}
},
"@react-native-community/cli-doctor": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-9.3.0.tgz",
- "integrity": "sha512-/fiuG2eDGC2/OrXMOWI5ifq4X1gdYTQhvW2m0TT5Lk1LuFiZsbTCp1lR+XILKekuTvmYNjEGdVpeDpdIWlXdEA==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-doctor/-/cli-doctor-10.1.1.tgz",
+ "integrity": "sha512-9uvUhr6aJu4C7pCTsD9iRS/38tx1mzIrWuEQoh2JffTXg9MOq4jesvobkyKFRD90nOvqunEvfpnWnRdWcZO0Wg==",
"requires": {
- "@react-native-community/cli-config": "^9.2.1",
- "@react-native-community/cli-platform-ios": "^9.3.0",
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-config": "^10.1.1",
+ "@react-native-community/cli-platform-ios": "^10.1.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"command-exists": "^1.2.8",
"envinfo": "^7.7.2",
@@ -24984,12 +24801,12 @@
}
},
"@react-native-community/cli-hermes": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-9.3.1.tgz",
- "integrity": "sha512-Mq4PK8m5YqIdaVq5IdRfp4qK09aVO+aiCtd6vjzjNUgk1+1X5cgUqV6L65h4N+TFJYJHcp2AnB+ik1FAYXvYPQ==",
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-hermes/-/cli-hermes-10.1.3.tgz",
+ "integrity": "sha512-uYl8MLBtuu6bj0tDUzVGf30nK5i9haBv7F0u+NCOq31+zVjcwiUplrCuLorb2dMLMF+Fno9wDxi66W9MxoW4nA==",
"requires": {
- "@react-native-community/cli-platform-android": "^9.3.1",
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-platform-android": "^10.1.3",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"hermes-profile-transformer": "^0.0.6",
"ip": "^1.1.5"
@@ -25041,17 +24858,15 @@
}
},
"@react-native-community/cli-platform-android": {
- "version": "9.3.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-9.3.1.tgz",
- "integrity": "sha512-m0bQ6Twewl7OEZoVf79I2GZmsDqh+Gh0bxfxWgwxobsKDxLx8/RNItAo1lVtTCgzuCR75cX4EEO8idIF9jYhew==",
+ "version": "10.1.3",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-android/-/cli-platform-android-10.1.3.tgz",
+ "integrity": "sha512-8YZEpBL6yd9l4CIoFcLOgrV8x2GDujdqrdWrNsNERDAbsiFwqAQvfjyyb57GAZVuEPEJCoqUlGlMCwOh3XQb9A==",
"requires": {
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"execa": "^1.0.0",
- "fs-extra": "^8.1.0",
"glob": "^7.1.3",
- "logkitty": "^0.7.1",
- "slash": "^3.0.0"
+ "logkitty": "^0.7.1"
},
"dependencies": {
"ansi-styles": {
@@ -25110,16 +24925,6 @@
"strip-eof": "^1.0.0"
}
},
- "fs-extra": {
- "version": "8.1.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz",
- "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
- "requires": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^4.0.0",
- "universalify": "^0.1.0"
- }
- },
"get-stream": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -25156,11 +24961,6 @@
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
"integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
},
- "slash": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
- },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -25172,11 +24972,11 @@
}
},
"@react-native-community/cli-platform-ios": {
- "version": "9.3.0",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-9.3.0.tgz",
- "integrity": "sha512-nihTX53BhF2Q8p4B67oG3RGe1XwggoGBrMb6vXdcu2aN0WeXJOXdBLgR900DAA1O8g7oy1Sudu6we+JsVTKnjw==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-platform-ios/-/cli-platform-ios-10.1.1.tgz",
+ "integrity": "sha512-EB9/L8j1LqrqyfJtLRixU+d8FIP6Pr83rEgUgXgya/u8wk3h/bvX70w+Ff2skwjdPLr5dLUQ/n5KFX4r3bsNmA==",
"requires": {
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
"execa": "^1.0.0",
"glob": "^7.1.3",
@@ -25286,19 +25086,20 @@
}
},
"@react-native-community/cli-plugin-metro": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-9.2.1.tgz",
- "integrity": "sha512-byBGBH6jDfUvcHGFA45W/sDwMlliv7flJ8Ns9foCh3VsIeYYPoDjjK7SawE9cPqRdMAD4SY7EVwqJnOtRbwLiQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-plugin-metro/-/cli-plugin-metro-10.1.1.tgz",
+ "integrity": "sha512-wEp47le4mzlelDF5sfkaaujUDYcuLep5HZqlcMx7PkL7BA3/fSHdDo1SblqaLgZ1ca6vFU+kfbHueLDct+xwFg==",
"requires": {
- "@react-native-community/cli-server-api": "^9.2.1",
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-server-api": "^10.1.1",
+ "@react-native-community/cli-tools": "^10.1.1",
"chalk": "^4.1.2",
- "metro": "0.72.3",
- "metro-config": "0.72.3",
- "metro-core": "0.72.3",
- "metro-react-native-babel-transformer": "0.72.3",
- "metro-resolver": "0.72.3",
- "metro-runtime": "0.72.3",
+ "execa": "^1.0.0",
+ "metro": "0.73.7",
+ "metro-config": "0.73.7",
+ "metro-core": "0.73.7",
+ "metro-react-native-babel-transformer": "0.73.7",
+ "metro-resolver": "0.73.7",
+ "metro-runtime": "0.73.7",
"readline": "^1.3.0"
},
"dependencies": {
@@ -25332,11 +25133,68 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ=="
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==",
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw=="
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ },
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -25348,12 +25206,12 @@
}
},
"@react-native-community/cli-server-api": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-9.2.1.tgz",
- "integrity": "sha512-EI+9MUxEbWBQhWw2PkhejXfkcRqPl+58+whlXJvKHiiUd7oVbewFs0uLW0yZffUutt4FGx6Uh88JWEgwOzAdkw==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-server-api/-/cli-server-api-10.1.1.tgz",
+ "integrity": "sha512-NZDo/wh4zlm8as31UEBno2bui8+ufzsZV+KN7QjEJWEM0levzBtxaD+4je0OpfhRIIkhaRm2gl/vVf7OYAzg4g==",
"requires": {
- "@react-native-community/cli-debugger-ui": "^9.0.0",
- "@react-native-community/cli-tools": "^9.2.1",
+ "@react-native-community/cli-debugger-ui": "^10.0.0",
+ "@react-native-community/cli-tools": "^10.1.1",
"compression": "^1.7.1",
"connect": "^3.6.5",
"errorhandler": "^1.5.0",
@@ -25376,9 +25234,9 @@
}
},
"@types/yargs": {
- "version": "15.0.14",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
- "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
+ "version": "15.0.15",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz",
+ "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==",
"requires": {
"@types/yargs-parser": "*"
}
@@ -25445,9 +25303,9 @@
}
},
"@react-native-community/cli-tools": {
- "version": "9.2.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-9.2.1.tgz",
- "integrity": "sha512-bHmL/wrKmBphz25eMtoJQgwwmeCylbPxqFJnFSbkqJPXQz3ManQ6q/gVVMqFyz7D3v+riaus/VXz3sEDa97uiQ==",
+ "version": "10.1.1",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-tools/-/cli-tools-10.1.1.tgz",
+ "integrity": "sha512-+FlwOnZBV+ailEzXjcD8afY2ogFEBeHOw/8+XXzMgPaquU2Zly9B+8W089tnnohO3yfiQiZqkQlElP423MY74g==",
"requires": {
"appdirsjs": "^1.2.4",
"chalk": "^4.1.2",
@@ -25562,17 +25420,17 @@
}
},
"@react-native-community/cli-types": {
- "version": "9.1.0",
- "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-9.1.0.tgz",
- "integrity": "sha512-KDybF9XHvafLEILsbiKwz5Iobd+gxRaPyn4zSaAerBxedug4er5VUWa8Szy+2GeYKZzMh/gsb1o9lCToUwdT/g==",
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/@react-native-community/cli-types/-/cli-types-10.0.0.tgz",
+ "integrity": "sha512-31oUM6/rFBZQfSmDQsT1DX/5fjqfxg7sf2u8kTPJK7rXVya5SRpAMaCXsPAG0omsmJxXt+J9HxUi3Ic+5Ux5Iw==",
"requires": {
"joi": "^17.2.1"
}
},
"@react-native-community/datetimepicker": {
- "version": "6.7.1",
- "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-6.7.1.tgz",
- "integrity": "sha512-NPW1YITG7N+3TsqXc4LZV3c5IEpTD5iX18r0bvFsHdIblo5qi0ykpeK3TffmMM5gbTjgKJ4DNVHOjLiWKxFUxw==",
+ "version": "6.7.3",
+ "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-6.7.3.tgz",
+ "integrity": "sha512-fXWbEdHMLW/e8cts3snEsbOTbnFXfUHeO2pkiDFX3fWpFoDtUrRWvn50xbY13IJUUKHDhoJ+mj24nMRVIXfX1A==",
"requires": {
"invariant": "^2.2.4"
}
@@ -25635,9 +25493,9 @@
"integrity": "sha512-KrwSpS1tKI70wuKl68DwJZYEvXktDHdZMG0k2AXD/rJVSlB23/X2CB2cutVR0HwNMJIal9HOUOBB2rVfa6UGtQ=="
},
"@react-native/normalize-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-2.0.0.tgz",
- "integrity": "sha512-Wip/xsc5lw8vsBlmY2MO/gFLp3MvuZ2baBZjDeTjjndMgM0h5sxz7AZR62RDPGgstp8Np7JzjvVqVT7tpFZqsw=="
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@react-native/normalize-color/-/normalize-color-2.1.0.tgz",
+ "integrity": "sha512-Z1jQI2NpdFJCVgpY+8Dq/Bt3d+YUi1928Q+/CZm/oh66fzM0RUl54vvuXlPJKybH4pdCZey1eDTPaLHkMPNgWA=="
},
"@react-native/polyfills": {
"version": "2.0.0",
@@ -25645,11 +25503,11 @@
"integrity": "sha512-K0aGNn1TjalKj+65D7ycc1//H9roAQ51GJVk5ZJQFb2teECGmzd86bYDC0aYdbRf7gtovescq4Zt6FR0tgXiHQ=="
},
"@react-navigation/bottom-tabs": {
- "version": "6.5.2",
- "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.2.tgz",
- "integrity": "sha512-iN3B1cgXdo64lqXdsTsCjN7n+5ILYKRexAu0VtW6EO8E6Z/0obK5JcCEropSiimRqVRs0kyuYj3F94Oth+hMrw==",
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/@react-navigation/bottom-tabs/-/bottom-tabs-6.5.3.tgz",
+ "integrity": "sha512-ZA2Ko9fNwNaaSNn7738KpEk8Doi+yjRfTg8Wb/WvduIaK/28qNLAYWBCUEVjBC55y/9zJOzwc4R8Av2J2MG/4g==",
"requires": {
- "@react-navigation/elements": "^1.3.12",
+ "@react-navigation/elements": "^1.3.13",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -25679,9 +25537,9 @@
}
},
"@react-navigation/core": {
- "version": "6.4.5",
- "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.5.tgz",
- "integrity": "sha512-wcde35HeOM5r2P25EwLQZyJ1yhXDGKuWpnKfsSI1xrgYIvWdYi3j/yGnwgNGDelCmtUt1Fyk2pmOv8sEku9KkA==",
+ "version": "6.4.6",
+ "resolved": "https://registry.npmjs.org/@react-navigation/core/-/core-6.4.6.tgz",
+ "integrity": "sha512-6zaAgUT5k4vhJlddUk2l52RZyMkMelHdrRv1cL57ALi2RZzERdgmbiMKhJerxFLn9S8E3PUe8vwxHzjHOZKG4w==",
"requires": {
"@react-navigation/routers": "^6.1.6",
"escape-string-regexp": "^4.0.0",
@@ -25692,17 +25550,17 @@
}
},
"@react-navigation/elements": {
- "version": "1.3.12",
- "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.12.tgz",
- "integrity": "sha512-iVcLIYg/XJk1p6X1rSFhNhCjAJ3ORqNT2/bJqw7I/liujeJAoz1oZ5JDoEcZaA0wMDts1txxLuqAYJmhCgU2aA==",
+ "version": "1.3.13",
+ "resolved": "https://registry.npmjs.org/@react-navigation/elements/-/elements-1.3.13.tgz",
+ "integrity": "sha512-LqqK5s2ZfYHn2cQ376jC5V9dQztLH5ixkkJj9WR7JY2g4SghDd39WJhL3Jillw1Mu3F3b9sZwvAK+QkXhnDeAA==",
"requires": {}
},
"@react-navigation/native": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.1.tgz",
- "integrity": "sha512-iIozx9c66EjSFyzKrZPixnk6vBuivYXp0jmbKCJXNIa7MY+8OLx9CXj/+1py/l/OGlXDhI6jiUWWetOfOtMaBQ==",
+ "version": "6.1.2",
+ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-6.1.2.tgz",
+ "integrity": "sha512-qLUe0asHofr5EhxKjvUBJ9DrPPmR4535IEwmW3oU4DRb3cLbNysjajJKHL8kcYtqPvn9Bx9QZG2x0PMb2vN23A==",
"requires": {
- "@react-navigation/core": "^6.4.5",
+ "@react-navigation/core": "^6.4.6",
"escape-string-regexp": "^4.0.0",
"fast-deep-equal": "^3.1.3",
"nanoid": "^3.1.23"
@@ -25717,11 +25575,11 @@
}
},
"@react-navigation/stack": {
- "version": "6.3.10",
- "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.10.tgz",
- "integrity": "sha512-mghQpCbGBI9jpwYmhXDI5drGOxz6F9hLxQgLeu1IsTSA9767Edov7TDt5n/PTJqhpOru7/xoNMs4yhp9ykVhng==",
+ "version": "6.3.11",
+ "resolved": "https://registry.npmjs.org/@react-navigation/stack/-/stack-6.3.11.tgz",
+ "integrity": "sha512-GWOAyJfPEsjVwDWec1ERwWL5LvManJucCRUZetJqCBs4/mV7HXEt2x6l3SMitHxH1+K+9XuYXI+wBTbK1WDYOA==",
"requires": {
- "@react-navigation/elements": "^1.3.12",
+ "@react-navigation/elements": "^1.3.13",
"color": "^4.2.3",
"warn-once": "^0.1.0"
},
@@ -25751,34 +25609,20 @@
}
},
"@rudderstack/rudder-sdk-react-native": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/@rudderstack/rudder-sdk-react-native/-/rudder-sdk-react-native-1.5.1.tgz",
- "integrity": "sha512-nyacl2EpJ3l2NBMm7YhijyjD1jIk0GeBpBgFMZavMdAChA+Ak7sl+quKOfewYHLuFf/g2xh07p4ULLQpLqBpZw==",
- "requires": {
- "@babel/runtime": "^7.7.7",
- "@types/async-lock": "^1.1.3",
- "@types/react-native": "^0.62.2",
- "async-lock": "^1.3.0"
- },
- "dependencies": {
- "@types/react-native": {
- "version": "0.62.18",
- "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.62.18.tgz",
- "integrity": "sha512-7QfU8EzIYxYqeXpPf8QNv2xi8hrePlgTbRATRo+plRSdVfJu7N6sAXqrFxKJp6bGLvp82GV1gczl93gqiAfXPA==",
- "requires": {
- "@types/react": "*"
- }
- }
- }
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@rudderstack/rudder-sdk-react-native/-/rudder-sdk-react-native-1.5.2.tgz",
+ "integrity": "sha512-M6dqOHqmbDzFE3R+TfjA0AppQfS8TSuv+qLtiq57V47zlLlkusszfZvHLQ8O63iTi5XsVciO1oTyj2ZCLtJUHA==",
+ "requires": {}
},
"@sentry/browser": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.26.0.tgz",
- "integrity": "sha512-S6uW+Ni2VLGHUV9eAUtTy5QEvqKeOhcnWnv+2yTGDtQCJ0SuHfXRCM7ASAQYBiKffZqIFc9Z2XNU/2cuWcXJmw==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/browser/-/browser-7.29.0.tgz",
+ "integrity": "sha512-Af+dIcntaw405Wt7myDOMGDxiszfy4aBdshrEKYbGgcfHjgXBIdF3iKlNatvl6nrOm+IOVuKgSpCLOr2hiCwzw==",
"requires": {
- "@sentry/core": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/core": "7.29.0",
+ "@sentry/replay": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"tslib": "^1.9.3"
},
"dependencies": {
@@ -25814,12 +25658,12 @@
}
},
"@sentry/core": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.26.0.tgz",
- "integrity": "sha512-ydi236ZoP/xpvLdf7B8seKjCcGc5Z+q9c14tHCFusplPZgLSXcYpiiLIDWmF7OAXO89sSbb1NaFt9YB0LkYdLQ==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/core/-/core-7.29.0.tgz",
+ "integrity": "sha512-+e9aIp2ljtT4EJq3901z6TfEVEeqZd5cWzbKEuQzPn2UO6If9+Utd7kY2Y31eQYb4QnJgZfiIEz1HonuYY6zqQ==",
"requires": {
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"tslib": "^1.9.3"
},
"dependencies": {
@@ -25831,13 +25675,13 @@
}
},
"@sentry/hub": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.26.0.tgz",
- "integrity": "sha512-djAMuA4/Jy28dOSy9z5ccXBDyYk1N9m0ljle+dKqjfJwv440tCGyoxm2arqJFHbXvqwJTt2Giv8ASR4uGD1UNg==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-7.29.0.tgz",
+ "integrity": "sha512-nIV2NtTn16VukTtWFhROHJ35NyUIXgEGtesG8a1i7D4iRSvkfLkLrQ9i6D0BAE2huqKqQemO3zGEPR00szqsiA==",
"requires": {
- "@sentry/core": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/core": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"tslib": "^1.9.3"
},
"dependencies": {
@@ -25849,12 +25693,12 @@
}
},
"@sentry/integrations": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.26.0.tgz",
- "integrity": "sha512-5tyBA5BnZEuosSIvBP7mJz66xJaZTb/k1EzHEc0hR2Mw8QpLgMneDZBfi4vdbhxtGpJKC/gURoUGZf9hpwW+DA==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/integrations/-/integrations-7.29.0.tgz",
+ "integrity": "sha512-BkZe3ALij320VtC5bNkeSz3OUhT9oxZsj2lf5rCuRFqcqw4tvVNADF/Y98mf0L4VCy582M9MlNXmwfewJjxGOA==",
"requires": {
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"localforage": "^1.8.1",
"tslib": "^1.9.3"
},
@@ -25867,13 +25711,13 @@
}
},
"@sentry/react": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.26.0.tgz",
- "integrity": "sha512-v5XKpG1PF4qnWvG8E0N1kcUk74lTp+TDfKx5x996NIja2oOTp/JL9V0Q+lAMlB1EKgJuxLe92IeqD5/DTtzE7A==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react/-/react-7.29.0.tgz",
+ "integrity": "sha512-pJ138QTChfAiYzFrCgycBgXrAVARV6TdVvLB8z/HsqbHzPq17RhyF9M1xPE4ffeLDQAEuSudwED9CLOpJqKnAw==",
"requires": {
- "@sentry/browser": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/browser": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"hoist-non-react-statics": "^3.3.2",
"tslib": "^1.9.3"
},
@@ -25886,30 +25730,40 @@
}
},
"@sentry/react-native": {
- "version": "4.12.0",
- "resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-4.12.0.tgz",
- "integrity": "sha512-KBRXXqqGg67oqhtGzZQ8Ls4rxxUozDyL8tMLmRLk//bkSWBC6XslyjkZkQrB1VZsv2ikEYCUgyAP7fzcj6Bbig==",
+ "version": "4.13.0",
+ "resolved": "https://registry.npmjs.org/@sentry/react-native/-/react-native-4.13.0.tgz",
+ "integrity": "sha512-CxQd5jWPKEPgR1SH5ppf555h7DMhSBZMU3eSZ/VNT+BocgzxxBnf/tcJj92+gpwrzt2m7MiZ3uDfyfQOgyMc8Q==",
"requires": {
- "@sentry/browser": "7.26.0",
+ "@sentry/browser": "7.29.0",
"@sentry/cli": "1.74.4",
- "@sentry/core": "7.26.0",
- "@sentry/hub": "7.26.0",
- "@sentry/integrations": "7.26.0",
- "@sentry/react": "7.26.0",
- "@sentry/tracing": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/core": "7.29.0",
+ "@sentry/hub": "7.29.0",
+ "@sentry/integrations": "7.29.0",
+ "@sentry/react": "7.29.0",
+ "@sentry/tracing": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"@sentry/wizard": "1.4.0"
}
},
- "@sentry/tracing": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.26.0.tgz",
- "integrity": "sha512-UK8EiXxJrDTWD82Oasj2WP/QuQ+wzPlg74vYmxl1ie/LRs6C6wHkilBZwDV9HnDdqAqSjl0al8oBa075lK+U3Q==",
+ "@sentry/replay": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/replay/-/replay-7.29.0.tgz",
+ "integrity": "sha512-Gw7HgviJQu6pX5RFQGVY38Av4qFn9otrZdwSSl/QK5hIyg6yhlh5h7U0ydZkrYYGiW6Z6SYYRpEWCJc/Wbh+ZQ==",
"requires": {
- "@sentry/core": "7.26.0",
- "@sentry/types": "7.26.0",
- "@sentry/utils": "7.26.0",
+ "@sentry/core": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0"
+ }
+ },
+ "@sentry/tracing": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-7.29.0.tgz",
+ "integrity": "sha512-MAN/G6XROtRhzo/KDjddb6VJn/Q1TaPLwdyj9vvfkUkBNtlt5k16oXp+u7eHWX0uujER9wnZtj2ivXaPeqq0VA==",
+ "requires": {
+ "@sentry/core": "7.29.0",
+ "@sentry/types": "7.29.0",
+ "@sentry/utils": "7.29.0",
"tslib": "^1.9.3"
},
"dependencies": {
@@ -25921,16 +25775,16 @@
}
},
"@sentry/types": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.26.0.tgz",
- "integrity": "sha512-U2s0q3ALwWFdHJBgn8nrG9bCTJZ3hAqL/I2Si4Mf0ZWnJ/KTJKbtyrputHr8wMbHvX0NZTJGTxFVUO46J+GBRA=="
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-DmoEpoqHPty3VxqubS/5gxarwebHRlcBd/yuno+PS3xy++/i9YPjOWLZhU2jYs1cW68M9R6CcCOiC9f2ckJjdw=="
},
"@sentry/utils": {
- "version": "7.26.0",
- "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.26.0.tgz",
- "integrity": "sha512-nIC1PRyoMBi4QB7XNCWaPDqaQbPayMwAvUm6W3MC5bHPfVZmmFt+3sLZQKUD/E0NeQnJ3vTyPewPF/LfxLOE5A==",
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-7.29.0.tgz",
+ "integrity": "sha512-ICcBwTiBGK8NQA8H2BJo0JcMN6yCeKLqNKNMVampRgS6wSfSk1edvcTdhRkW3bSktIGrIPZrKskBHyMwDGF2XQ==",
"requires": {
- "@sentry/types": "7.26.0",
+ "@sentry/types": "7.29.0",
"tslib": "^1.9.3"
},
"dependencies": {
@@ -25968,9 +25822,9 @@
}
},
"@sideway/formula": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
- "integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg=="
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
+ "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg=="
},
"@sideway/pinpoint": {
"version": "2.0.0",
@@ -25980,14 +25834,12 @@
"@sinclair/typebox": {
"version": "0.24.44",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.44.tgz",
- "integrity": "sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg==",
- "dev": true
+ "integrity": "sha512-ka0W0KN5i6LfrSocduwliMMpqVgohtPFidKdMEOUjoOFCHcOOYkKsPRxfs5f15oPNHTm6ERAm0GV/+/LTKeiWg=="
},
"@sinonjs/commons": {
"version": "1.8.6",
"resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz",
"integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==",
- "dev": true,
"requires": {
"type-detect": "4.0.8"
}
@@ -25996,7 +25848,6 @@
"version": "9.1.2",
"resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz",
"integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==",
- "dev": true,
"requires": {
"@sinonjs/commons": "^1.7.0"
}
@@ -26192,11 +26043,6 @@
"integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==",
"dev": true
},
- "@types/async-lock": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/@types/async-lock/-/async-lock-1.1.3.tgz",
- "integrity": "sha512-UpeDcjGKsYEQMeqEbfESm8OWJI305I7b9KE4ji3aBjoKWyN5CTdn8izcA1FM1DVDne30R5fNEnIy89vZw5LXJQ=="
- },
"@types/babel__core": {
"version": "7.1.19",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz",
@@ -26326,11 +26172,6 @@
"hoist-non-react-statics": "^3.3.0"
}
},
- "@types/invariant": {
- "version": "2.2.35",
- "resolved": "https://registry.npmjs.org/@types/invariant/-/invariant-2.2.35.tgz",
- "integrity": "sha512-DxX1V9P8zdJPYQat1gHyY0xj3efl8gnMVjiM9iCY6y27lj+PoQWkgjt8jDqmovPqULkKVpKRg8J36iQiA+EtEg=="
- },
"@types/istanbul-lib-coverage": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz",
@@ -26353,9 +26194,9 @@
}
},
"@types/jest": {
- "version": "29.2.5",
- "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.5.tgz",
- "integrity": "sha512-H2cSxkKgVmqNHXP7TC2L/WUorrZu8ZigyRywfVzv6EyBlxj39n4C00hjXYQWsbwqgElaj/CiAeSRmk5GoaKTgw==",
+ "version": "29.2.6",
+ "resolved": "https://registry.npmjs.org/@types/jest/-/jest-29.2.6.tgz",
+ "integrity": "sha512-XEUC/Tgw3uMh6Ho8GkUtQ2lPhY5Fmgyp3TdlkTJs1W9VgNxs+Ow/x3Elh8lHQKqCbZL0AubQuqWjHVT033Hhrw==",
"dev": true,
"requires": {
"expect": "^29.0.0",
@@ -26415,9 +26256,9 @@
"dev": true
},
"@types/react": {
- "version": "18.0.26",
- "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz",
- "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==",
+ "version": "18.0.27",
+ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz",
+ "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==",
"requires": {
"@types/prop-types": "*",
"@types/scheduler": "*",
@@ -26531,8 +26372,7 @@
"@types/stack-utils": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz",
- "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==",
- "dev": true
+ "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw=="
},
"@types/tinycolor2": {
"version": "1.4.3",
@@ -26567,7 +26407,6 @@
"version": "17.0.13",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz",
"integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==",
- "dev": true,
"requires": {
"@types/yargs-parser": "*"
}
@@ -26578,14 +26417,14 @@
"integrity": "sha512-7tFImggNeNBVMsn0vLrpn1H1uPrUBdnARPTpZoitY37ZrdJREzf7I16tMrlK3hen349gr1NYh8CmZQa7CTG6Aw=="
},
"@typescript-eslint/eslint-plugin": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.48.0.tgz",
- "integrity": "sha512-SVLafp0NXpoJY7ut6VFVUU9I+YeFsDzeQwtK0WZ+xbRN3mtxJ08je+6Oi2N89qDn087COdO0u3blKZNv9VetRQ==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.49.0.tgz",
+ "integrity": "sha512-IhxabIpcf++TBaBa1h7jtOWyon80SXPRLDq0dVz5SLFC/eW6tofkw/O7Ar3lkx5z5U6wzbKDrl2larprp5kk5Q==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "5.48.0",
- "@typescript-eslint/type-utils": "5.48.0",
- "@typescript-eslint/utils": "5.48.0",
+ "@typescript-eslint/scope-manager": "5.49.0",
+ "@typescript-eslint/type-utils": "5.49.0",
+ "@typescript-eslint/utils": "5.49.0",
"debug": "^4.3.4",
"ignore": "^5.2.0",
"natural-compare-lite": "^1.4.0",
@@ -26595,31 +26434,31 @@
}
},
"@typescript-eslint/parser": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.48.0.tgz",
- "integrity": "sha512-1mxNA8qfgxX8kBvRDIHEzrRGrKHQfQlbW6iHyfHYS0Q4X1af+S6mkLNtgCOsGVl8+/LUPrqdHMssAemkrQ01qg==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.49.0.tgz",
+ "integrity": "sha512-veDlZN9mUhGqU31Qiv2qEp+XrJj5fgZpJ8PW30sHU+j/8/e5ruAhLaVDAeznS7A7i4ucb/s8IozpDtt9NqCkZg==",
"dev": true,
"requires": {
- "@typescript-eslint/scope-manager": "5.48.0",
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/typescript-estree": "5.48.0",
+ "@typescript-eslint/scope-manager": "5.49.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/typescript-estree": "5.49.0",
"debug": "^4.3.4"
},
"dependencies": {
"@typescript-eslint/types": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
- "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz",
+ "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
- "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz",
+ "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/visitor-keys": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/visitor-keys": "5.49.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -26628,12 +26467,12 @@
}
},
"@typescript-eslint/visitor-keys": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
- "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz",
+ "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -26646,28 +26485,28 @@
}
},
"@typescript-eslint/scope-manager": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.48.0.tgz",
- "integrity": "sha512-0AA4LviDtVtZqlyUQnZMVHydDATpD9SAX/RC5qh6cBd3xmyWvmXYF+WT1oOmxkeMnWDlUVTwdODeucUnjz3gow==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.49.0.tgz",
+ "integrity": "sha512-clpROBOiMIzpbWNxCe1xDK14uPZh35u4QaZO1GddilEzoCLAEz4szb51rBpdgurs5k2YzPtJeTEN3qVbG+LRUQ==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/visitor-keys": "5.48.0"
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/visitor-keys": "5.49.0"
},
"dependencies": {
"@typescript-eslint/types": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
- "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz",
+ "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==",
"dev": true
},
"@typescript-eslint/visitor-keys": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
- "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz",
+ "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -26680,31 +26519,31 @@
}
},
"@typescript-eslint/type-utils": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.48.0.tgz",
- "integrity": "sha512-vbtPO5sJyFjtHkGlGK4Sthmta0Bbls4Onv0bEqOGm7hP9h8UpRsHJwsrCiWtCUndTRNQO/qe6Ijz9rnT/DB+7g==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.49.0.tgz",
+ "integrity": "sha512-eUgLTYq0tR0FGU5g1YHm4rt5H/+V2IPVkP0cBmbhRyEmyGe4XvJ2YJ6sYTmONfjmdMqyMLad7SB8GvblbeESZA==",
"dev": true,
"requires": {
- "@typescript-eslint/typescript-estree": "5.48.0",
- "@typescript-eslint/utils": "5.48.0",
+ "@typescript-eslint/typescript-estree": "5.49.0",
+ "@typescript-eslint/utils": "5.49.0",
"debug": "^4.3.4",
"tsutils": "^3.21.0"
},
"dependencies": {
"@typescript-eslint/types": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
- "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz",
+ "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
- "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz",
+ "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/visitor-keys": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/visitor-keys": "5.49.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -26713,12 +26552,12 @@
}
},
"@typescript-eslint/visitor-keys": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
- "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz",
+ "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -26752,35 +26591,35 @@
}
},
"@typescript-eslint/utils": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.48.0.tgz",
- "integrity": "sha512-x2jrMcPaMfsHRRIkL+x96++xdzvrdBCnYRd5QiW5Wgo1OB4kDYPbC1XjWP/TNqlfK93K/lUL92erq5zPLgFScQ==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.49.0.tgz",
+ "integrity": "sha512-cPJue/4Si25FViIb74sHCLtM4nTSBXtLx1d3/QT6mirQ/c65bV8arBEebBJJizfq8W2YyMoPI/WWPFWitmNqnQ==",
"dev": true,
"requires": {
"@types/json-schema": "^7.0.9",
"@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.48.0",
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/typescript-estree": "5.48.0",
+ "@typescript-eslint/scope-manager": "5.49.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/typescript-estree": "5.49.0",
"eslint-scope": "^5.1.1",
"eslint-utils": "^3.0.0",
"semver": "^7.3.7"
},
"dependencies": {
"@typescript-eslint/types": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.48.0.tgz",
- "integrity": "sha512-UTe67B0Ypius0fnEE518NB2N8gGutIlTojeTg4nt0GQvikReVkurqxd2LvYa9q9M5MQ6rtpNyWTBxdscw40Xhw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.49.0.tgz",
+ "integrity": "sha512-7If46kusG+sSnEpu0yOz2xFv5nRz158nzEXnJFCGVEHWnuzolXKwrH5Bsf9zsNlOQkyZuk0BZKKoJQI+1JPBBg==",
"dev": true
},
"@typescript-eslint/typescript-estree": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.48.0.tgz",
- "integrity": "sha512-7pjd94vvIjI1zTz6aq/5wwE/YrfIyEPLtGJmRfyNR9NYIW+rOvzzUv3Cmq2hRKpvt6e9vpvPUQ7puzX7VSmsEw==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.49.0.tgz",
+ "integrity": "sha512-PBdx+V7deZT/3GjNYPVQv1Nc0U46dAHbIuOG8AZ3on3vuEKiPDwFE/lG1snN2eUB9IhF7EyF7K1hmTcLztNIsA==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.48.0",
- "@typescript-eslint/visitor-keys": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
+ "@typescript-eslint/visitor-keys": "5.49.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
@@ -26789,12 +26628,12 @@
}
},
"@typescript-eslint/visitor-keys": {
- "version": "5.48.0",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.48.0.tgz",
- "integrity": "sha512-5motVPz5EgxQ0bHjut3chzBkJ3Z3sheYVcSwS5BpHZpLqSptSmELNtGixmgj65+rIfhvtQTz5i9OP2vtzdDH7Q==",
+ "version": "5.49.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.49.0.tgz",
+ "integrity": "sha512-v9jBMjpNWyn8B6k/Mjt6VbUS4J1GvUlR4x3Y+ibnP1z7y7V4n0WRz+50DY6+Myj0UaXVSuUlHohO+eZ8IJEnkg==",
"dev": true,
"requires": {
- "@typescript-eslint/types": "5.48.0",
+ "@typescript-eslint/types": "5.49.0",
"eslint-visitor-keys": "^3.3.0"
}
},
@@ -27053,8 +26892,7 @@
"acorn": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
- "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
- "dev": true
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w=="
},
"acorn-import-assertions": {
"version": "1.8.0",
@@ -27273,14 +27111,15 @@
"integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ=="
},
"array.prototype.flat": {
- "version": "1.2.5",
- "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.5.tgz",
- "integrity": "sha512-KaYU+S+ndVqyUnignHftkwc58o3uVU1jzczILJ1tN2YaIZpFIKBiP/x/j97E5MVPsaCloPbqWLB/8qCTVvT2qg==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz",
+ "integrity": "sha512-roTU0KWIOmJ4DRLmwKd19Otg0/mT3qPNt0Qb3GWW8iObuZXxrjB/pzn0R3hqpRSWg4HCwqx+0vwOnWnvlOyeIA==",
"dev": true,
"requires": {
"call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "es-abstract": "^1.19.0"
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0"
}
},
"array.prototype.flatmap": {
@@ -27342,9 +27181,10 @@
"integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ=="
},
"async-lock": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.3.0.tgz",
- "integrity": "sha512-8A7SkiisnEgME2zEedtDYPxUPzdv3x//E7n5IFktPAtMYSEAV7eNJF0rMwrVyUFj6d/8rgajLantbjcNRQYXIg=="
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/async-lock/-/async-lock-1.4.0.tgz",
+ "integrity": "sha512-coglx5yIWuetakm3/1dsX9hxCNox22h7+V80RQOu2XUUMidtArxKoZoOtHUPuR84SycKTXzgGzAUR5hJxujyJQ==",
+ "peer": true
},
"asynckit": {
"version": "0.4.0",
@@ -27369,9 +27209,9 @@
"integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw=="
},
"axios": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.2.tgz",
- "integrity": "sha512-bz/J4gS2S3I7mpN/YZfGFTqhXTYzRho8Ay38w2otuuDR322KzFIWm/4W2K6gIwvWaws5n+mnb7D1lN9uD+QH6Q==",
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-1.2.3.tgz",
+ "integrity": "sha512-pdDkMYJeuXLZ6Xj/Q5J3Phpe+jbGdsSzlQaFVkMQzRUL05+6+tetX8TV3p4HrU4kzuO9bt+io/yGQxuyxA/xcw==",
"dev": true,
"requires": {
"follow-redirects": "^1.15.0",
@@ -27539,16 +27379,60 @@
}
},
"babel-plugin-module-resolver": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-4.1.0.tgz",
- "integrity": "sha512-MlX10UDheRr3lb3P0WcaIdtCSRlxdQsB1sBqL7W0raF070bGl1HQQq5K3T2vf2XAYie+ww+5AKC/WrkjRO2knA==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/babel-plugin-module-resolver/-/babel-plugin-module-resolver-5.0.0.tgz",
+ "integrity": "sha512-g0u+/ChLSJ5+PzYwLwP8Rp8Rcfowz58TJNCe+L/ui4rpzE/mg//JVX0EWBUYoxaextqnwuGHzfGp2hh0PPV25Q==",
"dev": true,
"requires": {
- "find-babel-config": "^1.2.0",
- "glob": "^7.1.6",
+ "find-babel-config": "^2.0.0",
+ "glob": "^8.0.3",
"pkg-up": "^3.1.0",
- "reselect": "^4.0.0",
- "resolve": "^1.13.1"
+ "reselect": "^4.1.7",
+ "resolve": "^1.22.1"
+ },
+ "dependencies": {
+ "brace-expansion": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "8.0.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
+ "integrity": "sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^5.0.1",
+ "once": "^1.3.0"
+ }
+ },
+ "minimatch": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.2.tgz",
+ "integrity": "sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^2.0.1"
+ }
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ }
}
},
"babel-plugin-polyfill-corejs2": {
@@ -28665,9 +28549,9 @@
"dev": true
},
"detox": {
- "version": "20.1.1",
- "resolved": "https://registry.npmjs.org/detox/-/detox-20.1.1.tgz",
- "integrity": "sha512-0ieeWAyo2f3YKeFwm7KCz4lBkCJIydyqzCQVN1sw/ZU9x9Qc8kz+itKAEiH4DHUlLkb4YLzfEbAXfO09wvrQ3w==",
+ "version": "20.1.2",
+ "resolved": "https://registry.npmjs.org/detox/-/detox-20.1.2.tgz",
+ "integrity": "sha512-SGxLyuzE8TjIc4Lg49YKD0buj3JLaX+KtprSeFvn7ZTdWd4fH6o5Szd4KM21uBSpnYEEgXTgiCypPQst6dt5mQ==",
"dev": true,
"requires": {
"ajv": "^8.6.3",
@@ -28682,7 +28566,7 @@
"glob": "^8.0.3",
"ini": "^1.3.4",
"json-cycle": "^1.3.0",
- "lodash": "^4.17.5",
+ "lodash": "^4.17.11",
"multi-sort-stream": "^1.0.3",
"multipipe": "^4.0.0",
"node-ipc": "^9.2.1",
@@ -29086,9 +28970,9 @@
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="
},
"eslint": {
- "version": "8.31.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.31.0.tgz",
- "integrity": "sha512-0tQQEVdmPZ1UtUKXjX7EMm9BlgJ08G90IhWh0PKDCb3ZLsgAOHI8fYSIzYVZej92zsgq+ft0FGsxhJ3xo2tbuA==",
+ "version": "8.32.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.32.0.tgz",
+ "integrity": "sha512-nETVXpnthqKPFyuY2FNjz/bEd6nbosRgKbkgS/y1C7LJop96gYHWpiguLecMHQ2XCPxn77DS0P+68WzG6vkZSQ==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.4.1",
@@ -29324,13 +29208,14 @@
"requires": {}
},
"eslint-import-resolver-node": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz",
- "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==",
+ "version": "0.3.7",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz",
+ "integrity": "sha512-gozW2blMLJCeFpBwugLTGyvVjNoeo1knonXAcatC6bjPBZitotxdWf7Gimr25N4c0AAOo4eOUfaG82IJPDpqCA==",
"dev": true,
"requires": {
"debug": "^3.2.7",
- "resolve": "^1.20.0"
+ "is-core-module": "^2.11.0",
+ "resolve": "^1.22.1"
},
"dependencies": {
"debug": {
@@ -29341,17 +29226,27 @@
"requires": {
"ms": "^2.1.1"
}
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
}
}
},
"eslint-module-utils": {
- "version": "2.7.3",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
- "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==",
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz",
+ "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==",
"dev": true,
"requires": {
- "debug": "^3.2.7",
- "find-up": "^2.1.0"
+ "debug": "^3.2.7"
},
"dependencies": {
"debug": {
@@ -29362,49 +29257,6 @@
"requires": {
"ms": "^2.1.1"
}
- },
- "find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
- "dev": true,
- "requires": {
- "locate-path": "^2.0.0"
- }
- },
- "locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
- "dev": true,
- "requires": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
- }
- },
- "p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
- "dev": true,
- "requires": {
- "p-try": "^1.0.0"
- }
- },
- "p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
- "dev": true,
- "requires": {
- "p-limit": "^1.1.0"
- }
- },
- "p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
- "dev": true
}
}
},
@@ -29444,33 +29296,35 @@
"requires": {}
},
"eslint-plugin-import": {
- "version": "2.26.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz",
- "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==",
+ "version": "2.27.5",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz",
+ "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==",
"dev": true,
"requires": {
- "array-includes": "^3.1.4",
- "array.prototype.flat": "^1.2.5",
- "debug": "^2.6.9",
+ "array-includes": "^3.1.6",
+ "array.prototype.flat": "^1.3.1",
+ "array.prototype.flatmap": "^1.3.1",
+ "debug": "^3.2.7",
"doctrine": "^2.1.0",
- "eslint-import-resolver-node": "^0.3.6",
- "eslint-module-utils": "^2.7.3",
+ "eslint-import-resolver-node": "^0.3.7",
+ "eslint-module-utils": "^2.7.4",
"has": "^1.0.3",
- "is-core-module": "^2.8.1",
+ "is-core-module": "^2.11.0",
"is-glob": "^4.0.3",
"minimatch": "^3.1.2",
- "object.values": "^1.1.5",
- "resolve": "^1.22.0",
+ "object.values": "^1.1.6",
+ "resolve": "^1.22.1",
+ "semver": "^6.3.0",
"tsconfig-paths": "^3.14.1"
},
"dependencies": {
"debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "version": "3.2.7",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz",
+ "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==",
"dev": true,
"requires": {
- "ms": "2.0.0"
+ "ms": "^2.1.1"
}
},
"doctrine": {
@@ -29482,10 +29336,21 @@
"esutils": "^2.0.2"
}
},
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "dev": true,
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
"dev": true
}
}
@@ -29509,9 +29374,9 @@
}
},
"eslint-plugin-react": {
- "version": "7.31.11",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz",
- "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==",
+ "version": "7.32.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.32.1.tgz",
+ "integrity": "sha512-vOjdgyd0ZHBXNsmvU+785xY8Bfe57EFbTYYk8XrROzWpr9QBvpjITvAXt9xqcE6+8cjR/g1+mfumPToxsl1www==",
"dev": true,
"requires": {
"array-includes": "^3.1.6",
@@ -29526,7 +29391,7 @@
"object.hasown": "^1.1.2",
"object.values": "^1.1.6",
"prop-types": "^15.8.1",
- "resolve": "^2.0.0-next.3",
+ "resolve": "^2.0.0-next.4",
"semver": "^6.3.0",
"string.prototype.matchall": "^4.0.8"
},
@@ -29541,13 +29406,14 @@
}
},
"resolve": {
- "version": "2.0.0-next.3",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz",
- "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==",
+ "version": "2.0.0-next.4",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.4.tgz",
+ "integrity": "sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==",
"dev": true,
"requires": {
- "is-core-module": "^2.2.0",
- "path-parse": "^1.0.6"
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
}
},
"semver": {
@@ -30150,19 +30016,19 @@
}
},
"find-babel-config": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-1.2.0.tgz",
- "integrity": "sha512-jB2CHJeqy6a820ssiqwrKMeyC6nNdmrcgkKWJWmpoxpE8RKciYJXCcXRq1h2AzCo5I5BJeN2tkGEO3hLTuePRA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/find-babel-config/-/find-babel-config-2.0.0.tgz",
+ "integrity": "sha512-dOKT7jvF3hGzlW60Gc3ONox/0rRZ/tz7WCil0bqA1In/3I8f1BctpXahRnEKDySZqci7u+dqq93sZST9fOJpFw==",
"dev": true,
"requires": {
- "json5": "^0.5.1",
- "path-exists": "^3.0.0"
+ "json5": "^2.1.1",
+ "path-exists": "^4.0.0"
},
"dependencies": {
- "json5": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz",
- "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=",
+ "path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"dev": true
}
}
@@ -30260,9 +30126,9 @@
"dev": true
},
"flow-parser": {
- "version": "0.121.0",
- "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.121.0.tgz",
- "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg=="
+ "version": "0.185.2",
+ "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.185.2.tgz",
+ "integrity": "sha512-2hJ5ACYeJCzNtiVULov6pljKOLygy0zddoqSI1fFetM+XRPpRshFdGEijtqlamA1XwyZ+7rhryI6FQFzvtLWUQ=="
},
"follow-redirects": {
"version": "1.15.2",
@@ -31085,9 +30951,9 @@
}
},
"is-core-module": {
- "version": "2.8.1",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
- "integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
+ "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
"requires": {
"has": "^1.0.3"
}
@@ -31928,7 +31794,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz",
"integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==",
- "dev": true,
"requires": {
"@jest/environment": "^29.3.1",
"@jest/fake-timers": "^29.3.1",
@@ -32041,7 +31906,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz",
"integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==",
- "dev": true,
"requires": {
"@babel/code-frame": "^7.12.13",
"@jest/types": "^29.3.1",
@@ -32058,7 +31922,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"requires": {
"color-convert": "^2.0.1"
}
@@ -32067,7 +31930,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -32077,7 +31939,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"requires": {
"color-name": "~1.1.4"
}
@@ -32085,26 +31946,22 @@
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"slash": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
- "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
- "dev": true
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"requires": {
"has-flag": "^4.0.0"
}
@@ -32115,7 +31972,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz",
"integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==",
- "dev": true,
"requires": {
"@jest/types": "^29.3.1",
"@types/node": "*",
@@ -32501,7 +32357,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz",
"integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==",
- "dev": true,
"requires": {
"@jest/types": "^29.3.1",
"@types/node": "*",
@@ -32515,7 +32370,6 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
"requires": {
"color-convert": "^2.0.1"
}
@@ -32524,7 +32378,6 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
- "dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
@@ -32534,7 +32387,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
"requires": {
"color-name": "~1.1.4"
}
@@ -32542,20 +32394,17 @@
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
- "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
- "dev": true
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
- "dev": true,
"requires": {
"has-flag": "^4.0.0"
}
@@ -33066,14 +32915,6 @@
"resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz",
"integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
},
- "klaw": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
- "integrity": "sha512-TED5xi9gGQjGpNnvRWknrwAB1eL5GciPfVFOt3Vk1OJCVDQbzuSfrF3hkUQKlsgKrG1F+0t5W0m+Fje1jIt8rw==",
- "requires": {
- "graceful-fs": "^4.1.9"
- }
- },
"klaw-sync": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/klaw-sync/-/klaw-sync-6.0.0.tgz",
@@ -33347,9 +33188,9 @@
}
},
"lokijs": {
- "version": "npm:@nozbe/lokijs@1.5.12-wmelon4",
- "resolved": "https://registry.npmjs.org/@nozbe/lokijs/-/lokijs-1.5.12-wmelon4.tgz",
- "integrity": "sha512-3sYrhLI2GkdXW/VOi1w6D2tENxxL+n1LJHRIAkaSCoehTVDiysAjxa/1GQq7gb7T4CFxJ+brMGvSx0sugEwqjQ=="
+ "version": "npm:@nozbe/lokijs@1.5.12-wmelon6",
+ "resolved": "https://registry.npmjs.org/@nozbe/lokijs/-/lokijs-1.5.12-wmelon6.tgz",
+ "integrity": "sha512-GXsaqY8qTJ6xdCrGyno2t+ON2aj6PrUDdvhbrkxK/0Fp12C4FGvDg1wS+voLU9BANYHEnr7KRWfItDZnQkjoAg=="
},
"loose-envify": {
"version": "1.4.0",
@@ -33459,17 +33300,17 @@
"dev": true
},
"metro": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro/-/metro-0.72.3.tgz",
- "integrity": "sha512-Hb3xTvPqex8kJ1hutQNZhQadUKUwmns/Du9GikmWKBFrkiG3k3xstGAyO5t5rN9JSUEzQT6y9SWzSSOGogUKIg==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro/-/metro-0.73.7.tgz",
+ "integrity": "sha512-pkRqFhuGUvkiu8HxKPUQelbCuyy6te6okMssTyLzQwsKilNLK4YMI2uD6PHnypg5SiMJ58lwfqkp/t5w72jEvw==",
"requires": {
"@babel/code-frame": "^7.0.0",
- "@babel/core": "^7.14.0",
- "@babel/generator": "^7.14.0",
- "@babel/parser": "^7.14.0",
+ "@babel/core": "^7.20.0",
+ "@babel/generator": "^7.20.0",
+ "@babel/parser": "^7.20.0",
"@babel/template": "^7.0.0",
- "@babel/traverse": "^7.14.0",
- "@babel/types": "^7.0.0",
+ "@babel/traverse": "^7.20.0",
+ "@babel/types": "^7.20.0",
"absolute-path": "^0.0.0",
"accepts": "^1.3.7",
"async": "^3.2.2",
@@ -33479,40 +33320,40 @@
"debug": "^2.2.0",
"denodeify": "^1.2.1",
"error-stack-parser": "^2.0.6",
- "fs-extra": "^1.0.0",
"graceful-fs": "^4.2.4",
"hermes-parser": "0.8.0",
"image-size": "^0.6.0",
"invariant": "^2.2.4",
"jest-worker": "^27.2.0",
"lodash.throttle": "^4.1.1",
- "metro-babel-transformer": "0.72.3",
- "metro-cache": "0.72.3",
- "metro-cache-key": "0.72.3",
- "metro-config": "0.72.3",
- "metro-core": "0.72.3",
- "metro-file-map": "0.72.3",
- "metro-hermes-compiler": "0.72.3",
- "metro-inspector-proxy": "0.72.3",
- "metro-minify-uglify": "0.72.3",
- "metro-react-native-babel-preset": "0.72.3",
- "metro-resolver": "0.72.3",
- "metro-runtime": "0.72.3",
- "metro-source-map": "0.72.3",
- "metro-symbolicate": "0.72.3",
- "metro-transform-plugins": "0.72.3",
- "metro-transform-worker": "0.72.3",
+ "metro-babel-transformer": "0.73.7",
+ "metro-cache": "0.73.7",
+ "metro-cache-key": "0.73.7",
+ "metro-config": "0.73.7",
+ "metro-core": "0.73.7",
+ "metro-file-map": "0.73.7",
+ "metro-hermes-compiler": "0.73.7",
+ "metro-inspector-proxy": "0.73.7",
+ "metro-minify-terser": "0.73.7",
+ "metro-minify-uglify": "0.73.7",
+ "metro-react-native-babel-preset": "0.73.7",
+ "metro-resolver": "0.73.7",
+ "metro-runtime": "0.73.7",
+ "metro-source-map": "0.73.7",
+ "metro-symbolicate": "0.73.7",
+ "metro-transform-plugins": "0.73.7",
+ "metro-transform-worker": "0.73.7",
"mime-types": "^2.1.27",
"node-fetch": "^2.2.0",
"nullthrows": "^1.1.1",
- "rimraf": "^2.5.4",
+ "rimraf": "^3.0.2",
"serialize-error": "^2.1.0",
"source-map": "^0.5.6",
"strip-ansi": "^6.0.0",
"temp": "0.8.3",
"throat": "^5.0.0",
"ws": "^7.5.1",
- "yargs": "^15.3.1"
+ "yargs": "^17.5.1"
},
"dependencies": {
"ansi-styles": {
@@ -33538,13 +33379,13 @@
"integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ=="
},
"cliui": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
- "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"requires": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
}
},
"color-convert": {
@@ -33568,26 +33409,11 @@
"ms": "2.0.0"
}
},
- "decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
- },
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
},
- "fs-extra": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
- "integrity": "sha512-VerQV6vEKuhDWD2HGOybV6v5I73syoc/cXAbKlgTC7M/oFVEtklWlp9QH2Ijw3IaWDOQcMkldSPa7zXy79Z/UQ==",
- "requires": {
- "graceful-fs": "^4.1.2",
- "jsonfile": "^2.1.0",
- "klaw": "^1.0.0"
- }
- },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -33618,20 +33444,12 @@
}
}
},
- "jsonfile": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
- "integrity": "sha512-PKllAqbgLgxHaj8TElYymKCAgrASebJrWpTnEkOaTowt23VKXXN0sUeriJ+eh7y6ufb/CC5ap11pz71/cM0hUw==",
- "requires": {
- "graceful-fs": "^4.1.6"
- }
- },
"metro-react-native-babel-preset": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.72.3.tgz",
- "integrity": "sha512-uJx9y/1NIqoYTp6ZW1osJ7U5ZrXGAJbOQ/Qzl05BdGYvN1S7Qmbzid6xOirgK0EIT0pJKEEh1s8qbassYZe4cw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.7.tgz",
+ "integrity": "sha512-RKcmRZREjJCzHKP+JhC9QTCohkeb3xa/DtqHU14U5KWzJHdC0mMrkTZYNXhV0cryxsaVKVEw5873KhbZyZHMVw==",
"requires": {
- "@babel/core": "^7.14.0",
+ "@babel/core": "^7.20.0",
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
@@ -33641,7 +33459,7 @@
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-export-default-from": "^7.0.0",
- "@babel/plugin-syntax-flow": "^7.2.0",
+ "@babel/plugin-syntax-flow": "^7.18.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-syntax-optional-chaining": "^7.0.0",
"@babel/plugin-transform-arrow-functions": "^7.0.0",
@@ -33650,7 +33468,6 @@
"@babel/plugin-transform-classes": "^7.0.0",
"@babel/plugin-transform-computed-properties": "^7.0.0",
"@babel/plugin-transform-destructuring": "^7.0.0",
- "@babel/plugin-transform-exponentiation-operator": "^7.0.0",
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
"@babel/plugin-transform-function-name": "^7.0.0",
"@babel/plugin-transform-literals": "^7.0.0",
@@ -33677,14 +33494,6 @@
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
},
- "rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "requires": {
- "glob": "^7.1.3"
- }
- },
"serialize-error": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-2.1.0.tgz",
@@ -33713,96 +33522,63 @@
"has-flag": "^4.0.0"
}
},
- "wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "y18n": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
- "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
- },
"yargs": {
- "version": "15.4.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
- "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
"requires": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
}
},
"yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
}
}
},
"metro-babel-transformer": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.72.3.tgz",
- "integrity": "sha512-PTOR2zww0vJbWeeM3qN90WKENxCLzv9xrwWaNtwVlhcV8/diNdNe82sE1xIxLFI6OQuAVwNMv1Y7VsO2I7Ejrw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-babel-transformer/-/metro-babel-transformer-0.73.7.tgz",
+ "integrity": "sha512-s7UVkwovGTEXYEQrv5hcmSBbFJ9s9lhCRNMScn4Itgj3UMdqRr9lU8DXKEFlJ7osgRxN6n5+eXqcvhE4B1H1VQ==",
"requires": {
- "@babel/core": "^7.14.0",
+ "@babel/core": "^7.20.0",
"hermes-parser": "0.8.0",
- "metro-source-map": "0.72.3",
+ "metro-source-map": "0.73.7",
"nullthrows": "^1.1.1"
}
},
"metro-cache": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.72.3.tgz",
- "integrity": "sha512-++eyZzwkXvijWRV3CkDbueaXXGlVzH9GA52QWqTgAOgSHYp5jWaDwLQ8qpsMkQzpwSyIF4LLK9aI3eA7Xa132A==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-cache/-/metro-cache-0.73.7.tgz",
+ "integrity": "sha512-CPPgI+i9yVzOEDCdmEEZ67JgOvZyNDs8kStmGUFgDuLSjj3//HhkqT5XyfWjGeH6KmyGiS8ip3cgLOVn3IsOSA==",
"requires": {
- "metro-core": "0.72.3",
- "rimraf": "^2.5.4"
- },
- "dependencies": {
- "rimraf": {
- "version": "2.7.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
- "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
- "requires": {
- "glob": "^7.1.3"
- }
- }
+ "metro-core": "0.73.7",
+ "rimraf": "^3.0.2"
}
},
"metro-cache-key": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.72.3.tgz",
- "integrity": "sha512-kQzmF5s3qMlzqkQcDwDxrOaVxJ2Bh6WRXWdzPnnhsq9LcD3B3cYqQbRBS+3tSuXmathb4gsOdhWslOuIsYS8Rg=="
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-cache-key/-/metro-cache-key-0.73.7.tgz",
+ "integrity": "sha512-GngYzrHwZU9U0Xl81H4aq9Tn5cjQyU12v9/flB0hzpeiYO5A89TIeilb4Kg8jtfC6JcmmsdK9nxYIGEq7odHhQ=="
},
"metro-config": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.72.3.tgz",
- "integrity": "sha512-VEsAIVDkrIhgCByq8HKTWMBjJG6RlYwWSu1Gnv3PpHa0IyTjKJtB7wC02rbTjSaemcr82scldf2R+h6ygMEvsw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-config/-/metro-config-0.73.7.tgz",
+ "integrity": "sha512-pD/F+vK3u37cbj1skYmI6cUsEEscqNRtW2KlDKu1m+n8nooDB2oGTOZatlS5WQa7Ga6jYQRydftlq4CLDexAfA==",
"requires": {
"cosmiconfig": "^5.0.5",
"jest-validate": "^26.5.2",
- "metro": "0.72.3",
- "metro-cache": "0.72.3",
- "metro-core": "0.72.3",
- "metro-runtime": "0.72.3"
+ "metro": "0.73.7",
+ "metro-cache": "0.73.7",
+ "metro-core": "0.73.7",
+ "metro-runtime": "0.73.7"
},
"dependencies": {
"@jest/types": {
@@ -33818,9 +33594,9 @@
}
},
"@types/yargs": {
- "version": "15.0.14",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz",
- "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==",
+ "version": "15.0.15",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.15.tgz",
+ "integrity": "sha512-IziEYMU9XoVj8hWg7k+UJrXALkGFjWJhn5QFEv9q4p+v40oZhSuC135M38st8XPjICL7Ey4TV64ferBGUoJhBg==",
"requires": {
"@types/yargs-parser": "*"
}
@@ -33910,24 +33686,24 @@
}
},
"metro-core": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.72.3.tgz",
- "integrity": "sha512-KuYWBMmLB4+LxSMcZ1dmWabVExNCjZe3KysgoECAIV+wyIc2r4xANq15GhS94xYvX1+RqZrxU1pa0jQ5OK+/6A==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-core/-/metro-core-0.73.7.tgz",
+ "integrity": "sha512-H7j1Egj1VnNnsSYf9ZKv0SRwijgtRKIcaGNQq/T+er73vqqb4kR9H+2VIJYPXi6R8lT+QLIMfs6CWSUHAJUgtg==",
"requires": {
"lodash.throttle": "^4.1.1",
- "metro-resolver": "0.72.3"
+ "metro-resolver": "0.73.7"
}
},
"metro-file-map": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.72.3.tgz",
- "integrity": "sha512-LhuRnuZ2i2uxkpFsz1XCDIQSixxBkBG7oICAFyLyEMDGbcfeY6/NexphfLdJLTghkaoJR5ARFMiIxUg9fIY/pA==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-file-map/-/metro-file-map-0.73.7.tgz",
+ "integrity": "sha512-BYaCo2e/4FMN4nOajeN+Za5cPfecfikzUYuFWWMyLAmHU6dj7B+PFkaJ4OEJO3vmRoeq5vMOmhpKXgysYbNXJg==",
"requires": {
"abort-controller": "^3.0.0",
"anymatch": "^3.0.3",
"debug": "^2.2.0",
"fb-watchman": "^2.0.0",
- "fsevents": "^2.1.2",
+ "fsevents": "^2.3.2",
"graceful-fs": "^4.2.4",
"invariant": "^2.2.4",
"jest-regex-util": "^27.0.6",
@@ -33935,6 +33711,7 @@
"jest-util": "^27.2.0",
"jest-worker": "^27.2.0",
"micromatch": "^4.0.4",
+ "nullthrows": "^1.1.1",
"walker": "^1.0.7"
},
"dependencies": {
@@ -33951,9 +33728,9 @@
}
},
"@types/yargs": {
- "version": "16.0.4",
- "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz",
- "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==",
+ "version": "16.0.5",
+ "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz",
+ "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==",
"requires": {
"@types/yargs-parser": "*"
}
@@ -34055,52 +33832,31 @@
}
},
"metro-hermes-compiler": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.72.3.tgz",
- "integrity": "sha512-QWDQASMiXNW3j8uIQbzIzCdGYv5PpAX/ZiF4/lTWqKRWuhlkP4auhVY4eqdAKj5syPx45ggpjkVE0p8hAPDZYg=="
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-hermes-compiler/-/metro-hermes-compiler-0.73.7.tgz",
+ "integrity": "sha512-F8PlJ8mWEEumGNH3eMRA3gjgP70ZvH4Ex5F1KY6ofD/gpn7w5HJHSPTeVw8gtUb1pYLN4nevptpyXGg04Jfcog=="
},
"metro-inspector-proxy": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.72.3.tgz",
- "integrity": "sha512-UPFkaq2k93RaOi+eqqt7UUmqy2ywCkuxJLasQ55+xavTUS+TQSyeTnTczaYn+YKw+izLTLllGcvqnQcZiWYhGw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-inspector-proxy/-/metro-inspector-proxy-0.73.7.tgz",
+ "integrity": "sha512-TsAtQeKr9X7NaQHlpshu+ZkGWlPi5fFKNqieLkfqvT1oXN4PQF/4q38INyiZtWLPvoUzTR6PRnm4pcUbJ7+Nzg==",
"requires": {
"connect": "^3.6.5",
"debug": "^2.2.0",
"ws": "^7.5.1",
- "yargs": "^15.3.1"
+ "yargs": "^17.5.1"
},
"dependencies": {
- "ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "requires": {
- "color-convert": "^2.0.1"
- }
- },
"cliui": {
- "version": "6.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
- "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
"requires": {
"string-width": "^4.2.0",
- "strip-ansi": "^6.0.0",
- "wrap-ansi": "^6.2.0"
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
}
},
- "color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "requires": {
- "color-name": "~1.1.4"
- }
- },
- "color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
- },
"debug": {
"version": "2.6.9",
"resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -34109,11 +33865,6 @@
"ms": "2.0.0"
}
},
- "decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
- },
"emoji-regex": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
@@ -34139,62 +33890,47 @@
"strip-ansi": "^6.0.1"
}
},
- "wrap-ansi": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
- "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
- "requires": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- }
- },
- "y18n": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz",
- "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ=="
- },
"yargs": {
- "version": "15.4.1",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz",
- "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==",
+ "version": "17.6.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
+ "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
"requires": {
- "cliui": "^6.0.0",
- "decamelize": "^1.2.0",
- "find-up": "^4.1.0",
- "get-caller-file": "^2.0.1",
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
"require-directory": "^2.1.1",
- "require-main-filename": "^2.0.0",
- "set-blocking": "^2.0.0",
- "string-width": "^4.2.0",
- "which-module": "^2.0.0",
- "y18n": "^4.0.0",
- "yargs-parser": "^18.1.2"
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
}
},
"yargs-parser": {
- "version": "18.1.3",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
- "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
- "requires": {
- "camelcase": "^5.0.0",
- "decamelize": "^1.2.0"
- }
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="
}
}
},
+ "metro-minify-terser": {
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-minify-terser/-/metro-minify-terser-0.73.7.tgz",
+ "integrity": "sha512-gbv1fmMOZm6gJ6dQoD+QktlCi2wk6nlTR8j8lQCjeeXGbs6O9e5XLWNPOexHqo7S69bdbohEnfZnLJFcxgHeNw==",
+ "requires": {
+ "terser": "^5.15.0"
+ }
+ },
"metro-minify-uglify": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.72.3.tgz",
- "integrity": "sha512-dPXqtMI8TQcj0g7ZrdhC8X3mx3m3rtjtMuHKGIiEXH9CMBvrET8IwrgujQw2rkPcXiSiX8vFDbGMIlfxefDsKA==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-minify-uglify/-/metro-minify-uglify-0.73.7.tgz",
+ "integrity": "sha512-DmDCzfdbaPExQuQ7NQozCNOSOAgp5Ux9kWzmKAT8seQ38/3NtUepW+PTgxXIHmwNjJV4oHsHwlBlTwJmYihKXg==",
"requires": {
"uglify-es": "^3.1.9"
}
},
"metro-react-native-babel-preset": {
- "version": "0.73.7",
- "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.7.tgz",
- "integrity": "sha512-RKcmRZREjJCzHKP+JhC9QTCohkeb3xa/DtqHU14U5KWzJHdC0mMrkTZYNXhV0cryxsaVKVEw5873KhbZyZHMVw==",
+ "version": "0.74.1",
+ "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.74.1.tgz",
+ "integrity": "sha512-DjsG9nqm5C7cjB2SlgbcNJOn9y5MBUd3bRlCfnoj8CxAeGTGkS+yXd183lHR3C1bhmQNjuUE0abzzpE1CFh6JQ==",
"dev": true,
"requires": {
"@babel/core": "^7.20.0",
@@ -34202,6 +33938,7 @@
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
"@babel/plugin-proposal-nullish-coalescing-operator": "^7.0.0",
+ "@babel/plugin-proposal-numeric-separator": "^7.0.0",
"@babel/plugin-proposal-object-rest-spread": "^7.0.0",
"@babel/plugin-proposal-optional-catch-binding": "^7.0.0",
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
@@ -34230,7 +33967,6 @@
"@babel/plugin-transform-shorthand-properties": "^7.0.0",
"@babel/plugin-transform-spread": "^7.0.0",
"@babel/plugin-transform-sticky-regex": "^7.0.0",
- "@babel/plugin-transform-template-literals": "^7.0.0",
"@babel/plugin-transform-typescript": "^7.5.0",
"@babel/plugin-transform-unicode-regex": "^7.0.0",
"@babel/template": "^7.0.0",
@@ -34238,25 +33974,25 @@
}
},
"metro-react-native-babel-transformer": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.72.3.tgz",
- "integrity": "sha512-Ogst/M6ujYrl/+9mpEWqE3zF7l2mTuftDTy3L8wZYwX1pWUQWQpfU1aJBeWiLxt1XlIq+uriRjKzKoRoIK57EA==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-react-native-babel-transformer/-/metro-react-native-babel-transformer-0.73.7.tgz",
+ "integrity": "sha512-73HW8betjX+VPm3iqsMBe8F/F2Tt+hONO6YJwcF7FonTqQYW1oTz0dOp0dClZGfHUXxpJBz6Vuo7J6TpdzDD+w==",
"requires": {
- "@babel/core": "^7.14.0",
+ "@babel/core": "^7.20.0",
"babel-preset-fbjs": "^3.4.0",
"hermes-parser": "0.8.0",
- "metro-babel-transformer": "0.72.3",
- "metro-react-native-babel-preset": "0.72.3",
- "metro-source-map": "0.72.3",
+ "metro-babel-transformer": "0.73.7",
+ "metro-react-native-babel-preset": "0.73.7",
+ "metro-source-map": "0.73.7",
"nullthrows": "^1.1.1"
},
"dependencies": {
"metro-react-native-babel-preset": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.72.3.tgz",
- "integrity": "sha512-uJx9y/1NIqoYTp6ZW1osJ7U5ZrXGAJbOQ/Qzl05BdGYvN1S7Qmbzid6xOirgK0EIT0pJKEEh1s8qbassYZe4cw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-react-native-babel-preset/-/metro-react-native-babel-preset-0.73.7.tgz",
+ "integrity": "sha512-RKcmRZREjJCzHKP+JhC9QTCohkeb3xa/DtqHU14U5KWzJHdC0mMrkTZYNXhV0cryxsaVKVEw5873KhbZyZHMVw==",
"requires": {
- "@babel/core": "^7.14.0",
+ "@babel/core": "^7.20.0",
"@babel/plugin-proposal-async-generator-functions": "^7.0.0",
"@babel/plugin-proposal-class-properties": "^7.0.0",
"@babel/plugin-proposal-export-default-from": "^7.0.0",
@@ -34266,7 +34002,7 @@
"@babel/plugin-proposal-optional-chaining": "^7.0.0",
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
"@babel/plugin-syntax-export-default-from": "^7.0.0",
- "@babel/plugin-syntax-flow": "^7.2.0",
+ "@babel/plugin-syntax-flow": "^7.18.0",
"@babel/plugin-syntax-nullish-coalescing-operator": "^7.0.0",
"@babel/plugin-syntax-optional-chaining": "^7.0.0",
"@babel/plugin-transform-arrow-functions": "^7.0.0",
@@ -34275,7 +34011,6 @@
"@babel/plugin-transform-classes": "^7.0.0",
"@babel/plugin-transform-computed-properties": "^7.0.0",
"@babel/plugin-transform-destructuring": "^7.0.0",
- "@babel/plugin-transform-exponentiation-operator": "^7.0.0",
"@babel/plugin-transform-flow-strip-types": "^7.0.0",
"@babel/plugin-transform-function-name": "^7.0.0",
"@babel/plugin-transform-literals": "^7.0.0",
@@ -34300,33 +34035,33 @@
}
},
"metro-resolver": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.72.3.tgz",
- "integrity": "sha512-wu9zSMGdxpKmfECE7FtCdpfC+vrWGTdVr57lDA0piKhZV6VN6acZIvqQ1yZKtS2WfKsngncv5VbB8Y5eHRQP3w==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-resolver/-/metro-resolver-0.73.7.tgz",
+ "integrity": "sha512-mGW3XPeKBCwZnkHcKo1dhFa9olcx7SyNzG1vb5kjzJYe4Qs3yx04r/qFXIJLcIgLItB69TIGvosznUhpeOOXzg==",
"requires": {
"absolute-path": "^0.0.0"
}
},
"metro-runtime": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.72.3.tgz",
- "integrity": "sha512-3MhvDKfxMg2u7dmTdpFOfdR71NgNNo4tzAyJumDVQKwnHYHN44f2QFZQqpPBEmqhWlojNeOxsqFsjYgeyMx6VA==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-runtime/-/metro-runtime-0.73.7.tgz",
+ "integrity": "sha512-2fxRGrF8FyrwwHY0TCitdUljzutfW6CWEpdvPilfrs8p0PI5X8xOWg8ficeYtw+DldHtHIAL2phT59PqzHTyVA==",
"requires": {
"@babel/runtime": "^7.0.0",
"react-refresh": "^0.4.0"
}
},
"metro-source-map": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.72.3.tgz",
- "integrity": "sha512-eNtpjbjxSheXu/jYCIDrbNEKzMGOvYW6/ePYpRM7gDdEagUOqKOCsi3St8NJIQJzZCsxD2JZ2pYOiomUSkT1yQ==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-source-map/-/metro-source-map-0.73.7.tgz",
+ "integrity": "sha512-gbC/lfUN52TtQhEsTTA+987MaFUpQlufuCI05blLGLosDcFCsARikHsxa65Gtslm/rG2MqvFLiPA5hviONNv9g==",
"requires": {
- "@babel/traverse": "^7.14.0",
- "@babel/types": "^7.0.0",
+ "@babel/traverse": "^7.20.0",
+ "@babel/types": "^7.20.0",
"invariant": "^2.2.4",
- "metro-symbolicate": "0.72.3",
+ "metro-symbolicate": "0.73.7",
"nullthrows": "^1.1.1",
- "ob1": "0.72.3",
+ "ob1": "0.73.7",
"source-map": "^0.5.6",
"vlq": "^1.0.0"
},
@@ -34339,12 +34074,12 @@
}
},
"metro-symbolicate": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.72.3.tgz",
- "integrity": "sha512-eXG0NX2PJzJ/jTG4q5yyYeN2dr1cUqUaY7worBB0SP5bRWRc3besfb+rXwfh49wTFiL5qR0oOawkU4ZiD4eHXw==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-symbolicate/-/metro-symbolicate-0.73.7.tgz",
+ "integrity": "sha512-571ThWmX5o8yGNzoXjlcdhmXqpByHU/bSZtWKhtgV2TyIAzYCYt4hawJAS5+/qDazUvjHdm8BbdqFUheM0EKNQ==",
"requires": {
"invariant": "^2.2.4",
- "metro-source-map": "0.72.3",
+ "metro-source-map": "0.73.7",
"nullthrows": "^1.1.1",
"source-map": "^0.5.6",
"through2": "^2.0.1",
@@ -34359,34 +34094,34 @@
}
},
"metro-transform-plugins": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.72.3.tgz",
- "integrity": "sha512-D+TcUvCKZbRua1+qujE0wV1onZvslW6cVTs7dLCyC2pv20lNHjFr1GtW01jN2fyKR2PcRyMjDCppFd9VwDKnSg==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-transform-plugins/-/metro-transform-plugins-0.73.7.tgz",
+ "integrity": "sha512-M5isiWEau0jMudb5ezaNBZnYqXxcATMqnAYc+Cu25IahT1NHi5aWwLok9EBmBpN5641IZUZXScf+KnS7fPxPCQ==",
"requires": {
- "@babel/core": "^7.14.0",
- "@babel/generator": "^7.14.0",
+ "@babel/core": "^7.20.0",
+ "@babel/generator": "^7.20.0",
"@babel/template": "^7.0.0",
- "@babel/traverse": "^7.14.0",
+ "@babel/traverse": "^7.20.0",
"nullthrows": "^1.1.1"
}
},
"metro-transform-worker": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.72.3.tgz",
- "integrity": "sha512-WsuWj9H7i6cHuJuy+BgbWht9DK5FOgJxHLGAyULD5FJdTG9rSMFaHDO5WfC0OwQU5h4w6cPT40iDuEGksM7+YQ==",
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/metro-transform-worker/-/metro-transform-worker-0.73.7.tgz",
+ "integrity": "sha512-gZYIu9JAqEI9Rxi0xGMuMW6QsHGbMSptozlTOwOd7T7yXX3WwYS/I3yLPbLhbZTjOhwMHkTt8Nhm2qBo8nh14g==",
"requires": {
- "@babel/core": "^7.14.0",
- "@babel/generator": "^7.14.0",
- "@babel/parser": "^7.14.0",
- "@babel/types": "^7.0.0",
+ "@babel/core": "^7.20.0",
+ "@babel/generator": "^7.20.0",
+ "@babel/parser": "^7.20.0",
+ "@babel/types": "^7.20.0",
"babel-preset-fbjs": "^3.4.0",
- "metro": "0.72.3",
- "metro-babel-transformer": "0.72.3",
- "metro-cache": "0.72.3",
- "metro-cache-key": "0.72.3",
- "metro-hermes-compiler": "0.72.3",
- "metro-source-map": "0.72.3",
- "metro-transform-plugins": "0.72.3",
+ "metro": "0.73.7",
+ "metro-babel-transformer": "0.73.7",
+ "metro-cache": "0.73.7",
+ "metro-cache-key": "0.73.7",
+ "metro-hermes-compiler": "0.73.7",
+ "metro-source-map": "0.73.7",
+ "metro-transform-plugins": "0.73.7",
"nullthrows": "^1.1.1"
}
},
@@ -34684,9 +34419,9 @@
"integrity": "sha512-WDD0bdg9mbq6F4mRxEYcPWwfA1vxd0mrvKOyxI7Xj/atfRHVeutzuWByG//jfm4uPzp0y4Kj051EORCBSQMycw=="
},
"nock": {
- "version": "13.2.9",
- "resolved": "https://registry.npmjs.org/nock/-/nock-13.2.9.tgz",
- "integrity": "sha512-1+XfJNYF1cjGB+TKMWi29eZ0b82QOvQs2YoLNzbpWGqFMtRQHTa57osqdGj4FrFPgkO4D4AZinzUJR9VvW3QUA==",
+ "version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/nock/-/nock-13.3.0.tgz",
+ "integrity": "sha512-HHqYQ6mBeiMc+N038w8LkMpDCRquCHWeNmN3v6645P3NhN2+qXOBqvPqo7Rt1VyCMzKhJ733wZqw5B7cQVFNPg==",
"dev": true,
"requires": {
"debug": "^4.1.0",
@@ -34808,9 +34543,9 @@
"integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ=="
},
"ob1": {
- "version": "0.72.3",
- "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.72.3.tgz",
- "integrity": "sha512-OnVto25Sj7Ghp0vVm2THsngdze3tVq0LOg9LUHsAVXMecpqOP0Y8zaATW8M9gEgs2lNEAcCqV0P/hlmOPhVRvg=="
+ "version": "0.73.7",
+ "resolved": "https://registry.npmjs.org/ob1/-/ob1-0.73.7.tgz",
+ "integrity": "sha512-DfelfvR843KADhSUATGGhuepVMRcf5VQX+6MQLy5AW0BKDLlO7Usj6YZeAAZP7P86QwsoTxB0RXCFiA7t6S1IQ=="
},
"object-assign": {
"version": "4.1.1",
@@ -35465,7 +35200,6 @@
"version": "29.3.1",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz",
"integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==",
- "dev": true,
"requires": {
"@jest/schemas": "^29.0.0",
"ansi-styles": "^5.0.0",
@@ -35475,14 +35209,12 @@
"ansi-styles": {
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
- "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
- "dev": true
+ "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA=="
},
"react-is": {
"version": "18.2.0",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
- "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
- "dev": true
+ "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w=="
}
}
},
@@ -35650,7 +35382,6 @@
"version": "4.27.1",
"resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.27.1.tgz",
"integrity": "sha512-qXhcxxDWiFmFAOq48jts9YQYe1+wVoUXzJTlY4jbaATzyio6dd6CUGu3dXBhREeVgpZ+y4kg6vFJzIOZh6vY2w==",
- "dev": true,
"requires": {
"shell-quote": "^1.6.1",
"ws": "^7"
@@ -35704,42 +35435,44 @@
"integrity": "sha512-txfpPCQYiazVdcbMRhatqWKcAxJweUu2wDXvts5/7Wyp6+Y9cHojqXHsLPEckzutfHlxZhG8Oiundbmp8Fd6eQ=="
},
"react-native": {
- "version": "0.70.6",
- "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.70.6.tgz",
- "integrity": "sha512-xtQdImPHnwgraEx3HIZFOF+D1hJ9bC5mfpIdUGoMHRws6OmvHAjmFpO6qfdnaQ29vwbmZRq7yf14sbury74R/w==",
+ "version": "0.71.1",
+ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.71.1.tgz",
+ "integrity": "sha512-bLP5+IBj2IX6tgF9WnC/UL2ZPYkVUPsU4xqZV1jntTC2TH4xyLrvfKACjGlz5nQ3Mx4BmOFqsnMxithm53+6Aw==",
"requires": {
- "@jest/create-cache-key-function": "^27.0.1",
- "@react-native-community/cli": "9.3.2",
- "@react-native-community/cli-platform-android": "9.3.1",
- "@react-native-community/cli-platform-ios": "9.3.0",
+ "@jest/create-cache-key-function": "^29.2.1",
+ "@react-native-community/cli": "10.1.3",
+ "@react-native-community/cli-platform-android": "10.1.3",
+ "@react-native-community/cli-platform-ios": "10.1.1",
"@react-native/assets": "1.0.0",
- "@react-native/normalize-color": "2.0.0",
+ "@react-native/normalize-color": "2.1.0",
"@react-native/polyfills": "2.0.0",
"abort-controller": "^3.0.0",
"anser": "^1.4.9",
"base64-js": "^1.1.2",
+ "deprecated-react-native-prop-types": "^3.0.1",
"event-target-shim": "^5.0.1",
"invariant": "^2.2.4",
+ "jest-environment-node": "^29.2.1",
"jsc-android": "^250230.2.1",
"memoize-one": "^5.0.0",
- "metro-react-native-babel-transformer": "0.72.3",
- "metro-runtime": "0.72.3",
- "metro-source-map": "0.72.3",
+ "metro-react-native-babel-transformer": "0.73.7",
+ "metro-runtime": "0.73.7",
+ "metro-source-map": "0.73.7",
"mkdirp": "^0.5.1",
"nullthrows": "^1.1.1",
"pretty-format": "^26.5.2",
"promise": "^8.3.0",
- "react-devtools-core": "4.24.0",
- "react-native-codegen": "^0.70.6",
- "react-native-gradle-plugin": "^0.70.3",
+ "react-devtools-core": "^4.26.1",
+ "react-native-codegen": "^0.71.3",
+ "react-native-gradle-plugin": "^0.71.13",
"react-refresh": "^0.4.0",
"react-shallow-renderer": "^16.15.0",
"regenerator-runtime": "^0.13.2",
- "scheduler": "^0.22.0",
+ "scheduler": "^0.23.0",
"stacktrace-parser": "^0.1.3",
"use-sync-external-store": "^1.0.0",
"whatwg-fetch": "^3.0.0",
- "ws": "^6.1.4"
+ "ws": "^6.2.2"
},
"dependencies": {
"@jest/types": {
@@ -35792,6 +35525,16 @@
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
},
+ "deprecated-react-native-prop-types": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/deprecated-react-native-prop-types/-/deprecated-react-native-prop-types-3.0.1.tgz",
+ "integrity": "sha512-J0jCJcsk4hMlIb7xwOZKLfMpuJn6l8UtrPEzzQV5ewz5gvKNYakhBuq9h2rWX7YwHHJZFhU5W8ye7dB9oN8VcQ==",
+ "requires": {
+ "@react-native/normalize-color": "*",
+ "invariant": "*",
+ "prop-types": "*"
+ }
+ },
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
@@ -35808,23 +35551,6 @@
"react-is": "^17.0.1"
}
},
- "react-devtools-core": {
- "version": "4.24.0",
- "resolved": "https://registry.npmjs.org/react-devtools-core/-/react-devtools-core-4.24.0.tgz",
- "integrity": "sha512-Rw7FzYOOzcfyUPaAm9P3g0tFdGqGq2LLiAI+wjYcp6CsF3DeeMrRS3HZAho4s273C29G/DJhx0e8BpRE/QZNGg==",
- "requires": {
- "shell-quote": "^1.6.1",
- "ws": "^7"
- },
- "dependencies": {
- "ws": {
- "version": "7.5.9",
- "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz",
- "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==",
- "requires": {}
- }
- }
- },
"react-is": {
"version": "17.0.2",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
@@ -35892,12 +35618,12 @@
}
},
"react-native-codegen": {
- "version": "0.70.6",
- "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.70.6.tgz",
- "integrity": "sha512-kdwIhH2hi+cFnG5Nb8Ji2JwmcCxnaOOo9440ov7XDzSvGfmUStnCzl+MCW8jLjqHcE4icT7N9y+xx4f50vfBTw==",
+ "version": "0.71.3",
+ "resolved": "https://registry.npmjs.org/react-native-codegen/-/react-native-codegen-0.71.3.tgz",
+ "integrity": "sha512-5AvdHVU1sAaXg05i0dG664ZTaCaIFaY1znV5vNsj+wUu6MGxNEUNbDKk9dxKUkkxOyk2KZOK5uhzWL0p5H5yZQ==",
"requires": {
"@babel/parser": "^7.14.0",
- "flow-parser": "^0.121.0",
+ "flow-parser": "^0.185.0",
"jscodeshift": "^0.13.1",
"nullthrows": "^1.1.1"
}
@@ -35980,9 +35706,9 @@
}
},
"react-native-gesture-handler": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.8.0.tgz",
- "integrity": "sha512-poOSfz/w0IyD6Qwq7aaIRRfEaVTl1ecQFoyiIbpOpfNTjm2B1niY2FLrdVQIOtIOe+K9nH55Qal04nr4jGkHdQ==",
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.9.0.tgz",
+ "integrity": "sha512-a0BcH3Qb1tgVqUutc6d3VuWQkI1AM3+fJx8dkxzZs9t06qA27QgURYFoklpabuWpsUTzuKRpxleykp25E8m7tg==",
"requires": {
"@egjs/hammerjs": "^2.0.17",
"hoist-non-react-statics": "^3.3.0",
@@ -35992,9 +35718,9 @@
}
},
"react-native-gradle-plugin": {
- "version": "0.70.3",
- "resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.70.3.tgz",
- "integrity": "sha512-oOanj84fJEXUg9FoEAQomA8ISG+DVIrTZ3qF7m69VQUJyOGYyDZmPqKcjvRku4KXlEH6hWO9i4ACLzNBh8gC0A=="
+ "version": "0.71.13",
+ "resolved": "https://registry.npmjs.org/react-native-gradle-plugin/-/react-native-gradle-plugin-0.71.13.tgz",
+ "integrity": "sha512-C66LNZAXbU0YDRkWx8d/8kjesdu7fsUAc/3QPJNftSXKEvEtnFZK2aH/rIgu1s5dbTcE0fjhdVPNJMRIfKo61w=="
},
"react-native-haptic-feedback": {
"version": "1.14.0",
@@ -36009,9 +35735,9 @@
"requires": {}
},
"react-native-image-picker": {
- "version": "4.10.3",
- "resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-4.10.3.tgz",
- "integrity": "sha512-gLX8J6jCBkUt6jogpSdA7YyaGVLGYywRzMEwBciXshihpFZjc/cRlKymAVlu6Q7HMw0j3vrho6pI8ZGC5O/FGg==",
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-5.0.1.tgz",
+ "integrity": "sha512-+poQTHOnEGrbxJnut591XA9006svFOyfPg/i5bv+fLuwoSHh5HW0E/PVhvT8lbX0Z5C108vh3DAsnrfFFnPBGw==",
"requires": {}
},
"react-native-in-app-review": {
@@ -36074,9 +35800,9 @@
}
},
"react-native-navigation": {
- "version": "7.30.6",
- "resolved": "https://registry.npmjs.org/react-native-navigation/-/react-native-navigation-7.30.6.tgz",
- "integrity": "sha512-rnJ7VbMjnt8H1HkuaM65NkcFFca2QQRgsCQEF6yAe9J4Yb3I3XnywFd309D6yso4ZqRuK7EhuzP33/nReV1c/A==",
+ "version": "7.31.1",
+ "resolved": "https://registry.npmjs.org/react-native-navigation/-/react-native-navigation-7.31.1.tgz",
+ "integrity": "sha512-thChSqaoi/QHGGofG/4CEyO2v6ko41RsbjQrJzAnHkp7iw1K8pjxkW3KX0qx2rlR/A69kA31VskOLj8kl+7sQw==",
"requires": {
"hoist-non-react-statics": "3.x.x",
"lodash": "4.17.x",
@@ -36113,13 +35839,13 @@
}
},
"react-native-reanimated": {
- "version": "2.13.0",
- "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.13.0.tgz",
- "integrity": "sha512-yUHyYVIegWWIza4+nVyS3CSmI/Mc8kLFVHw2c6gnSHaYhYA4LeEjH/jBkoMzHk9Xd0Ra3cwtjYKAMG8OTp6JVg==",
+ "version": "2.14.4",
+ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-2.14.4.tgz",
+ "integrity": "sha512-DquSbl7P8j4SAmc+kRdd75Ianm8G+IYQ9T4AQ6lrpLVeDkhZmjWI0wkutKWnp6L7c5XNVUrFDUf69dwETLCItQ==",
"requires": {
"@babel/plugin-transform-object-assign": "^7.16.7",
"@babel/preset-typescript": "^7.16.7",
- "@types/invariant": "^2.2.35",
+ "convert-source-map": "^1.7.0",
"invariant": "^2.2.4",
"lodash.isequal": "^4.5.0",
"setimmediate": "^1.0.5",
@@ -36127,15 +35853,15 @@
}
},
"react-native-safe-area-context": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.4.1.tgz",
- "integrity": "sha512-N9XTjiuD73ZpVlejHrUWIFZc+6Z14co1K/p1IFMkImU7+avD69F3y+lhkqA2hN/+vljdZrBSiOwXPkuo43nFQA==",
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-4.5.0.tgz",
+ "integrity": "sha512-0WORnk9SkREGUg2V7jHZbuN5x4vcxj/1B0QOcXJjdYWrzZHgLcUzYWWIUecUPJh747Mwjt/42RZDOaFn3L8kPQ==",
"requires": {}
},
"react-native-screens": {
- "version": "3.18.2",
- "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.18.2.tgz",
- "integrity": "sha512-ANUEuvMUlsYJ1QKukEhzhfrvOUO9BVH9Nzg+6eWxpn3cfD/O83yPBOF8Mx6x5H/2+sMy+VS5x/chWOOo/U7QJw==",
+ "version": "3.19.0",
+ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-3.19.0.tgz",
+ "integrity": "sha512-Ehsmy7jr3H3j5pmN+/FqsAaIAD+k+xkcdePfLcg4rYRbN5X7fJPgaqhcmiCcZ0YxsU8ttsstP9IvRLNQuIkRRA==",
"requires": {
"react-freeze": "^1.0.0",
"warn-once": "^0.1.0"
@@ -36166,9 +35892,9 @@
"requires": {}
},
"react-native-svg": {
- "version": "13.6.0",
- "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.6.0.tgz",
- "integrity": "sha512-1wjHCMJ8siyZbDZ0MX5wM+Jr7YOkb6GADn4/Z+/u1UwJX8WfjarypxDF3UO1ugMHa+7qor39oY+URMcrgPpiww==",
+ "version": "13.7.0",
+ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-13.7.0.tgz",
+ "integrity": "sha512-WR5CIURvee5cAfvMhmdoeOjh1SC8KdLq5u5eFsz4pbYzCtIFClGSkLnNgkMSDMVV5LV0qQa4jeIk75ieIBzaDA==",
"requires": {
"css-select": "^5.1.0",
"css-tree": "^1.1.3"
@@ -36263,9 +35989,9 @@
}
},
"react-native-walkthrough-tooltip": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/react-native-walkthrough-tooltip/-/react-native-walkthrough-tooltip-1.4.0.tgz",
- "integrity": "sha512-nyBuynmCuzPKJN9NRGhSzCutGOk7/WqszGtX01gjDtlRfoJ25cSM0h+TEi/lsLbSCTEdB+e65qOTvoVhIq2gzA==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/react-native-walkthrough-tooltip/-/react-native-walkthrough-tooltip-1.5.0.tgz",
+ "integrity": "sha512-xzpTs3JQkUMkmurc7WJDSAWaH2KRiRL2YoTXVCRqEEWxIvLQTn9eQv0jBzs1geR0wL+ezRpjkBEGAlfQ6eMimw==",
"requires": {
"prop-types": "^15.6.1",
"react-fast-compare": "^2.0.4"
@@ -36351,15 +36077,6 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz",
"integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==",
"dev": true
- },
- "scheduler": {
- "version": "0.23.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
- "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
- "dev": true,
- "requires": {
- "loose-envify": "^1.1.0"
- }
}
}
},
@@ -36569,9 +36286,9 @@
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
},
"reselect": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.0.0.tgz",
- "integrity": "sha512-qUgANli03jjAyGlnbYVAV5vvnOmJnODyABz51RdBN7M4WaVu8mecZWgyQNkG8Yqe3KRGRt0l4K4B3XVEULC4CA==",
+ "version": "4.1.7",
+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.7.tgz",
+ "integrity": "sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==",
"dev": true
},
"resolve": {
@@ -36655,7 +36372,6 @@
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
- "dev": true,
"requires": {
"glob": "^7.1.3"
}
@@ -36734,9 +36450,9 @@
}
},
"scheduler": {
- "version": "0.22.0",
- "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.22.0.tgz",
- "integrity": "sha512-6QAm1BgQI88NPYymgGQLCZgvep4FyePDWFpXVK+zNSUgHwlqpJy8VEh8Et0KxTACS4VWwMousBElAZOH9nkkoQ==",
+ "version": "0.23.0",
+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz",
+ "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
"requires": {
"loose-envify": "^1.1.0"
}
@@ -37292,7 +37008,6 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz",
"integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==",
- "dev": true,
"requires": {
"escape-string-regexp": "^2.0.0"
},
@@ -37300,8 +37015,7 @@
"escape-string-regexp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz",
- "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==",
- "dev": true
+ "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="
}
}
},
@@ -37661,8 +37375,6 @@
"version": "5.15.1",
"resolved": "https://registry.npmjs.org/terser/-/terser-5.15.1.tgz",
"integrity": "sha512-K1faMUvpm/FBxjBXud0LWVAGxmvoPbZbfTCYbSgaaYQaIXI3/TdI7a7ZGA73Zrou6Q8Zmz3oeUTsp/dj+ag2Xw==",
- "dev": true,
- "peer": true,
"requires": {
"@jridgewell/source-map": "^0.3.2",
"acorn": "^8.5.0",
@@ -37673,9 +37385,7 @@
"commander": {
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
- "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
- "dev": true,
- "peer": true
+ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
}
}
},
@@ -37903,15 +37613,15 @@
}
},
"ts-jest": {
- "version": "29.0.3",
- "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.3.tgz",
- "integrity": "sha512-Ibygvmuyq1qp/z3yTh9QTwVVAbFdDy/+4BtIQR2sp6baF2SJU/8CKK/hhnGIDY2L90Az2jIqTwZPnN2p+BweiQ==",
+ "version": "29.0.5",
+ "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-29.0.5.tgz",
+ "integrity": "sha512-PL3UciSgIpQ7f6XjVOmbi96vmDHUqAyqDr8YxzopDqX3kfgYtX1cuNeBjP+L9sFXi6nzsGGA6R3fP3DDDJyrxA==",
"dev": true,
"requires": {
"bs-logger": "0.x",
"fast-json-stable-stringify": "2.x",
"jest-util": "^29.0.0",
- "json5": "^2.2.1",
+ "json5": "^2.2.3",
"lodash.memoize": "4.x",
"make-error": "1.x",
"semver": "7.x",
@@ -37944,9 +37654,9 @@
},
"dependencies": {
"json5": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
- "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz",
+ "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==",
"dev": true,
"requires": {
"minimist": "^1.2.0"
@@ -37994,8 +37704,7 @@
"type-detect": {
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
- "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
- "dev": true
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g=="
},
"type-fest": {
"version": "0.21.3",
@@ -38687,9 +38396,9 @@
"integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="
},
"zod": {
- "version": "3.19.1",
- "resolved": "https://registry.npmjs.org/zod/-/zod-3.19.1.tgz",
- "integrity": "sha512-LYjZsEDhCdYET9ikFu6dVPGp2YH9DegXjdJToSzD9rO6fy4qiRYFoyEYwps88OseJlPyl2NOe2iJuhEhL7IpEA=="
+ "version": "3.20.2",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.20.2.tgz",
+ "integrity": "sha512-1MzNQdAvO+54H+EaK5YpyEy0T+Ejo/7YLHS93G3RnYWh5gaotGHwGeN/ZO687qEDU2y4CdStQYXVHIgrUl5UVQ=="
},
"zwitch": {
"version": "2.0.2",
diff --git a/package.json b/package.json
index ec95a39221..39fb2bb305 100644
--- a/package.json
+++ b/package.json
@@ -15,24 +15,24 @@
"@formatjs/intl-relativetimeformat": "11.1.8",
"@gorhom/bottom-sheet": "4.4.5",
"@mattermost/compass-icons": "0.1.35",
- "@mattermost/react-native-emm": "1.3.3",
- "@mattermost/react-native-network-client": "1.0.2",
- "@mattermost/react-native-paste-input": "0.5.2",
- "@mattermost/react-native-turbo-log": "0.2.1",
- "@mattermost/react-native-turbo-mailer": "0.2.0",
+ "@mattermost/react-native-emm": "1.3.4",
+ "@mattermost/react-native-network-client": "1.1.0",
+ "@mattermost/react-native-paste-input": "0.6.0",
+ "@mattermost/react-native-turbo-log": "0.2.2",
+ "@mattermost/react-native-turbo-mailer": "0.2.3",
"@msgpack/msgpack": "2.8.0",
- "@nozbe/watermelondb": "0.24.0",
+ "@nozbe/watermelondb": "0.25.1",
"@nozbe/with-observables": "1.4.1",
- "@react-native-camera-roll/camera-roll": "5.2.1",
+ "@react-native-camera-roll/camera-roll": "5.2.2",
"@react-native-clipboard/clipboard": "1.11.1",
- "@react-native-community/datetimepicker": "6.7.1",
+ "@react-native-community/datetimepicker": "6.7.3",
"@react-native-community/netinfo": "9.3.7",
"@react-native-cookies/cookies": "6.2.1",
- "@react-navigation/bottom-tabs": "6.5.2",
- "@react-navigation/native": "6.1.1",
- "@react-navigation/stack": "6.3.10",
- "@rudderstack/rudder-sdk-react-native": "1.5.1",
- "@sentry/react-native": "4.12.0",
+ "@react-navigation/bottom-tabs": "6.5.3",
+ "@react-navigation/native": "6.1.2",
+ "@react-navigation/stack": "6.3.11",
+ "@rudderstack/rudder-sdk-react-native": "1.5.2",
+ "@sentry/react-native": "4.13.0",
"@stream-io/flat-list-mvcp": "0.10.2",
"base-64": "1.0.0",
"commonmark": "npm:@mattermost/commonmark@0.30.1-0",
@@ -49,7 +49,7 @@
"react": "18.2.0",
"react-freeze": "1.0.3",
"react-intl": "6.2.5",
- "react-native": "0.70.6",
+ "react-native": "0.71.1",
"react-native-android-open-settings": "1.3.0",
"react-native-animated-numbers": "0.4.1",
"react-native-background-timer": "2.4.1",
@@ -64,10 +64,10 @@
"react-native-fast-image": "8.6.3",
"react-native-file-viewer": "2.1.5",
"react-native-fs": "2.20.0",
- "react-native-gesture-handler": "2.8.0",
+ "react-native-gesture-handler": "2.9.0",
"react-native-haptic-feedback": "1.14.0",
"react-native-hw-keyboard-event": "0.0.4",
- "react-native-image-picker": "4.10.3",
+ "react-native-image-picker": "5.0.1",
"react-native-in-app-review": "4.2.1",
"react-native-incall-manager": "github:cpoile/react-native-incall-manager",
"react-native-keyboard-aware-scroll-view": "0.9.5",
@@ -76,19 +76,19 @@
"react-native-linear-gradient": "2.6.2",
"react-native-localize": "2.2.4",
"react-native-math-view": "3.9.5",
- "react-native-navigation": "7.30.6",
+ "react-native-navigation": "7.31.1",
"react-native-notifications": "4.3.3",
"react-native-permissions": "3.6.1",
- "react-native-reanimated": "2.13.0",
- "react-native-safe-area-context": "4.4.1",
- "react-native-screens": "3.18.2",
+ "react-native-reanimated": "2.14.4",
+ "react-native-safe-area-context": "4.5.0",
+ "react-native-screens": "3.19.0",
"react-native-section-list-get-item-layout": "2.2.3",
"react-native-shadow-2": "7.0.6",
"react-native-share": "8.1.0",
- "react-native-svg": "13.6.0",
+ "react-native-svg": "13.7.0",
"react-native-vector-icons": "9.2.0",
"react-native-video": "5.2.1",
- "react-native-walkthrough-tooltip": "1.4.0",
+ "react-native-walkthrough-tooltip": "1.5.0",
"react-native-webrtc": "github:mattermost/react-native-webrtc",
"react-native-webview": "11.26.0",
"react-syntax-highlighter": "15.5.0",
@@ -104,13 +104,13 @@
"@babel/core": "7.20.12",
"@babel/eslint-parser": "7.19.1",
"@babel/plugin-proposal-class-properties": "7.18.6",
- "@babel/plugin-proposal-decorators": "7.20.7",
+ "@babel/plugin-proposal-decorators": "7.20.13",
"@babel/plugin-transform-flow-strip-types": "7.19.0",
"@babel/plugin-transform-runtime": "7.19.6",
"@babel/preset-env": "7.20.2",
"@babel/preset-typescript": "7.18.6",
"@babel/register": "7.18.9",
- "@babel/runtime": "7.20.7",
+ "@babel/runtime": "7.20.13",
"@react-native-community/eslint-config": "3.2.0",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/react-native": "11.5.0",
@@ -118,12 +118,11 @@
"@types/commonmark": "0.27.5",
"@types/commonmark-react-renderer": "4.3.1",
"@types/deep-equal": "1.0.1",
- "@types/jest": "29.2.5",
+ "@types/jest": "29.2.6",
"@types/lodash": "4.14.191",
"@types/mime-db": "1.43.1",
"@types/querystringify": "2.0.0",
- "@types/react": "18.0.26",
- "@types/react-native": "0.70.8",
+ "@types/react": "18.0.27",
"@types/react-native-background-timer": "2.0.0",
"@types/react-native-button": "3.0.1",
"@types/react-native-dotenv": "0.2.0",
@@ -138,36 +137,36 @@
"@types/tough-cookie": "4.0.2",
"@types/url-parse": "1.4.8",
"@types/uuid": "9.0.0",
- "@typescript-eslint/eslint-plugin": "5.48.0",
- "@typescript-eslint/parser": "5.48.0",
- "axios": "1.2.2",
+ "@typescript-eslint/eslint-plugin": "5.49.0",
+ "@typescript-eslint/parser": "5.49.0",
+ "axios": "1.2.3",
"axios-cookiejar-support": "4.0.6",
"babel-jest": "29.3.1",
"babel-loader": "9.1.2",
- "babel-plugin-module-resolver": "4.1.0",
+ "babel-plugin-module-resolver": "5.0.0",
"deep-freeze": "0.0.1",
- "detox": "20.1.1",
- "eslint": "8.31.0",
+ "detox": "20.1.2",
+ "eslint": "8.32.0",
"eslint-plugin-header": "3.1.1",
- "eslint-plugin-import": "2.26.0",
+ "eslint-plugin-import": "2.27.5",
"eslint-plugin-jest": "27.2.1",
- "eslint-plugin-react": "7.31.11",
+ "eslint-plugin-react": "7.32.1",
"eslint-plugin-react-hooks": "4.6.0",
"husky": "8.0.3",
"isomorphic-fetch": "3.0.0",
"jest": "29.3.1",
"jest-cli": "29.3.1",
"jetifier": "2.0.0",
- "metro-react-native-babel-preset": "0.73.7",
+ "metro-react-native-babel-preset": "0.74.1",
"mmjstool": "github:mattermost/mattermost-utilities#010f456ea8be5beebafdb8776177cba515c1969e",
"mock-async-storage": "2.2.0",
- "nock": "13.2.9",
+ "nock": "13.3.0",
"patch-package": "6.5.1",
"react-devtools-core": "4.27.1",
"react-native-svg-transformer": "1.0.0",
"react-test-renderer": "18.2.0",
"tough-cookie": "4.1.2",
- "ts-jest": "29.0.3",
+ "ts-jest": "29.0.5",
"typescript": "4.9.4",
"underscore": "1.13.6",
"util": "0.12.5",
@@ -211,7 +210,8 @@
"react": "^18.2.0"
},
"@rudderstack/rudder-sdk-react-native": {
- "react-native": "^0.70.0"
+ "react": "^18.2.0",
+ "react-native": "^0.71.0"
},
"@testing-library/react-hooks": {
"@types/react": "^18.0.15",
@@ -222,7 +222,7 @@
"react": "^18.2.0"
},
"react-native-elements": {
- "react-native-safe-area-context": "^4.3.1"
+ "react-native-safe-area-context": "^4.5.0"
},
"react-native-fast-image": {
"react": "^18.2.0"
diff --git a/patches/@nozbe+watermelondb+0.24.0.patch b/patches/@nozbe+watermelondb+0.24.0.patch
deleted file mode 100644
index 284f8ede0d..0000000000
--- a/patches/@nozbe+watermelondb+0.24.0.patch
+++ /dev/null
@@ -1,183 +0,0 @@
-diff --git a/node_modules/@nozbe/watermelondb/Database/index.js b/node_modules/@nozbe/watermelondb/Database/index.js
-index 8d71c6f..9ad75d6 100644
---- a/node_modules/@nozbe/watermelondb/Database/index.js
-+++ b/node_modules/@nozbe/watermelondb/Database/index.js
-@@ -126,6 +126,10 @@ var Database = /*#__PURE__*/function () {
- // subsequent changes to the record don't trip up the invariant
- // TODO: What if this fails?
- record._preparedState = null;
-+
-+ if ('update' === preparedState) {
-+ record.__original = null;
-+ }
- }
-
- if (!changeNotifications[table]) {
-diff --git a/node_modules/@nozbe/watermelondb/Model/index.d.ts b/node_modules/@nozbe/watermelondb/Model/index.d.ts
-index 1a7c99e..0cb7b87 100644
---- a/node_modules/@nozbe/watermelondb/Model/index.d.ts
-+++ b/node_modules/@nozbe/watermelondb/Model/index.d.ts
-@@ -44,6 +44,8 @@ declare module '@nozbe/watermelondb/Model' {
-
- public update(recordUpdater?: (record: this) => void): Promise
-
-+ public cancelPrepareUpdate(): void;
-+
- public prepareUpdate(recordUpdater?: (record: this) => void): this
-
- public markAsDeleted(): Promise
-diff --git a/node_modules/@nozbe/watermelondb/Model/index.js b/node_modules/@nozbe/watermelondb/Model/index.js
-index 075a047..5a1604d 100644
---- a/node_modules/@nozbe/watermelondb/Model/index.js
-+++ b/node_modules/@nozbe/watermelondb/Model/index.js
-@@ -78,10 +78,22 @@ var Model = /*#__PURE__*/function () {
- // database.batch()
- ;
-
-+ _proto.cancelPrepareUpdate = function cancelPrepareUpdate() {
-+ if ('test' !== process.env.NODE_ENV && 'undefined' !== typeof process && process) {
-+ (0, _invariant.default)('update' !== _this._preparedState, "Cannot cancel an update on a model that has not been prepared");
-+ }
-+ this.__changes = null;
-+ this._preparedState = null;
-+ if (this.__original) {
-+ this._raw = this.__original;
-+ }
-+ this.__original = undefined;
-+ }
-+
- _proto.prepareUpdate = function prepareUpdate(recordUpdater = _noop.default) {
- var _this = this;
-
-- (0, _invariant.default)(!this._preparedState, "Cannot update a record with pending changes");
-+ (0, _invariant.default)(!this._preparedState, "Cannot update a record with pending changes in table " + _this.table);
-
- this.__ensureNotDisposable("Model.prepareUpdate()");
-
-@@ -92,6 +104,7 @@ var Model = /*#__PURE__*/function () {
- } // Perform updates
-
-
-+ this.__original = Object.assign({}, this._raw);
- (0, _ensureSync.default)(recordUpdater(this));
- this._isEditing = false;
- this._preparedState = 'update'; // TODO: `process.nextTick` doesn't work on React Native
-diff --git a/node_modules/@nozbe/watermelondb/WatermelonDB.podspec b/node_modules/@nozbe/watermelondb/WatermelonDB.podspec
-index 1f3af50..e9fea58 100644
---- a/node_modules/@nozbe/watermelondb/WatermelonDB.podspec
-+++ b/node_modules/@nozbe/watermelondb/WatermelonDB.podspec
-@@ -13,7 +13,10 @@ Pod::Spec.new do |s|
- s.platforms = { :ios => "9.0", :tvos => "9.0" }
- s.source = { :git => "https://github.com/Nozbe/WatermelonDB.git", :tag => "v#{s.version}" }
- s.source_files = "native/ios/**/*.{h,m,mm,swift,c,cpp}", "native/shared/**/*.{h,c,cpp}"
-- s.public_header_files = 'native/ios/WatermelonDB/SupportingFiles/Bridging.h'
-+ s.public_header_files = [
-+ 'native/ios/WatermelonDB/SupportingFiles/Bridging.h',
-+ 'native/ios/WatermelonDB/JSIInstaller.h',
-+ ]
- s.requires_arc = true
- # simdjson is annoyingly slow without compiler optimization, disable for debugging
- s.compiler_flags = '-Os'
-diff --git a/node_modules/@nozbe/watermelondb/native/android/build.gradle b/node_modules/@nozbe/watermelondb/native/android/build.gradle
-index 90ddf7a..e5ec9ec 100644
---- a/node_modules/@nozbe/watermelondb/native/android/build.gradle
-+++ b/node_modules/@nozbe/watermelondb/native/android/build.gradle
-@@ -9,7 +9,8 @@ buildscript {
- }
-
- repositories {
-- jcenter()
-+ mavenCentral()
-+ mavenLocal()
- }
-
- dependencies {
-@@ -40,5 +41,6 @@ dependencies {
-
- repositories {
- mavenCentral()
-+ mavenLocal()
- }
-
-diff --git a/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt b/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
-index ca31e20..b45c753 100644
---- a/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
-+++ b/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
-@@ -22,6 +22,21 @@ class Database(
- if (name == ":memory:" || name.contains("mode=memory")) {
- context.cacheDir.delete()
- File(context.cacheDir, name).path
-+ } else if (name.contains("/") || name.contains("file")) {
-+ // Extracts the database name from the path
-+ val dbName = name.substringAfterLast("/")
-+
-+ // Extracts the real path where the *.db file will be created
-+ val truePath = name.substringAfterLast("file://").substringBeforeLast("/")
-+
-+ // Creates the directory
-+ if (!truePath.contains("databases")) {
-+ val fileObj = File(truePath, "databases")
-+ fileObj.mkdir()
-+ File("${truePath}/databases", dbName).path
-+ } else {
-+ File(truePath, dbName).path
-+ }
- } else {
- // On some systems there is some kind of lock on `/databases` folder ¯\_(ツ)_/¯
- context.getDatabasePath("$name.db").path.replace("/databases", "")
-diff --git a/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/Bridging.h b/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/Bridging.h
-index 135118d..8324550 100644
---- a/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/Bridging.h
-+++ b/node_modules/@nozbe/watermelondb/native/ios/WatermelonDB/SupportingFiles/Bridging.h
-@@ -6,12 +6,6 @@
-
- #import
-
--#if __has_include("JSIInstaller.h")
--#import "JSIInstaller.h"
--#else
--#import "../JSIInstaller.h"
--#endif
--
- #if __has_include("DatabaseDeleteHelper.h")
- #import "DatabaseDeleteHelper.h"
- #else
-diff --git a/node_modules/@nozbe/watermelondb/native/shared/Database.cpp b/node_modules/@nozbe/watermelondb/native/shared/Database.cpp
-index a2bd410..44e1a58 100644
---- a/node_modules/@nozbe/watermelondb/native/shared/Database.cpp
-+++ b/node_modules/@nozbe/watermelondb/native/shared/Database.cpp
-@@ -54,6 +54,7 @@ void Database::destroy() {
- const std::lock_guard lock(mutex_);
-
- if (isDestroyed_) {
-+ db_->markAsDestroyed();
- return;
- }
- isDestroyed_ = true;
-diff --git a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp
-index 4108e6c..0fa554c 100644
---- a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp
-+++ b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp
-@@ -69,6 +69,10 @@ void SqliteDb::destroy() {
- }
- }
-
-+void SqliteDb::markAsDestroyed() {
-+ isDestroyed_ = true;
-+}
-+
- SqliteDb::~SqliteDb() {
- destroy();
- }
-diff --git a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.h b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.h
-index 22cffa7..4b74a7f 100644
---- a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.h
-+++ b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.h
-@@ -11,6 +11,7 @@ public:
- SqliteDb(std::string path);
- ~SqliteDb();
- void destroy();
-+ void markAsDestroyed();
-
- sqlite3 *sqlite;
-
diff --git a/patches/@nozbe+watermelondb+0.25.1.patch b/patches/@nozbe+watermelondb+0.25.1.patch
new file mode 100644
index 0000000000..140816529b
--- /dev/null
+++ b/patches/@nozbe+watermelondb+0.25.1.patch
@@ -0,0 +1,292 @@
+diff --git a/node_modules/@nozbe/watermelondb/Database/index.js b/node_modules/@nozbe/watermelondb/Database/index.js
+index 8d71c6f..9ad75d6 100644
+--- a/node_modules/@nozbe/watermelondb/Database/index.js
++++ b/node_modules/@nozbe/watermelondb/Database/index.js
+@@ -126,6 +126,10 @@ var Database = /*#__PURE__*/function () {
+ // subsequent changes to the record don't trip up the invariant
+ // TODO: What if this fails?
+ record._preparedState = null;
++
++ if ('update' === preparedState) {
++ record.__original = null;
++ }
+ }
+
+ if (!changeNotifications[table]) {
+diff --git a/node_modules/@nozbe/watermelondb/DatabaseProvider/index.d.ts b/node_modules/@nozbe/watermelondb/DatabaseProvider/index.d.ts
+index 7c00164..10e5388 100644
+--- a/node_modules/@nozbe/watermelondb/DatabaseProvider/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/DatabaseProvider/index.d.ts
+@@ -1,4 +1,4 @@
+-import { ElementType, ReactNode } from 'react'
++import React, { ReactNode } from 'react'
+ import Database from '../Database'
+ import { Provider } from './DatabaseContext'
+
+@@ -11,7 +11,7 @@ export type Props = {
+ * Database provider to create the database context
+ * to allow child components to consume the database without prop drilling
+ */
+-declare function DatabaseProvider({ children, database }: Props): ElementType
++declare function DatabaseProvider({ children, database }: Props): JSX.Element
+
+ export { default as withDatabase } from './withDatabase'
+ export { default as DatabaseContext, DatabaseConsumer } from './DatabaseContext'
+diff --git a/node_modules/@nozbe/watermelondb/DatabaseProvider/withDatabase.d.ts b/node_modules/@nozbe/watermelondb/DatabaseProvider/withDatabase.d.ts
+index b29d8aa..b70faa9 100644
+--- a/node_modules/@nozbe/watermelondb/DatabaseProvider/withDatabase.d.ts
++++ b/node_modules/@nozbe/watermelondb/DatabaseProvider/withDatabase.d.ts
+@@ -1,4 +1,5 @@
+-import { ComponentType } from 'react'
++import type { NonReactStatics } from 'hoist-non-react-statics'
++import React, { ComponentType } from 'react'
+ import type Database from '../Database'
+ import { DatabaseConsumer } from './DatabaseContext'
+
+@@ -8,4 +9,4 @@ type WithDatabaseProps = T & {
+ // HoC to inject the database into the props of consumers
+ export default function withDatabase(
+ Component: ComponentType>,
+-): DatabaseConsumer
++): React.FunctionComponent> & NonReactStatics
+diff --git a/node_modules/@nozbe/watermelondb/Model/index.d.ts b/node_modules/@nozbe/watermelondb/Model/index.d.ts
+index 43cd902..baefb53 100644
+--- a/node_modules/@nozbe/watermelondb/Model/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/Model/index.d.ts
+@@ -52,14 +52,16 @@ export default class Model {
+ // someTask.update(task => {
+ // task.name = 'New name'
+ // })
+- update(recordUpdater: (this) => void): Promise
++ update(recordUpdater: (record: this) => void): Promise
+
+ // Prepares an update to the database (using passed function).
+ // Touches `updatedAt` if available.
+ //
+ // After preparing an update, you must execute it synchronously using
+ // database.batch()
+- prepareUpdate(recordUpdater: (this) => void): this
++ prepareUpdate(recordUpdater: (record: this) => void): this
++
++ cancelPrepareUpdate(): void
+
+ prepareMarkAsDeleted(): this
+
+diff --git a/node_modules/@nozbe/watermelondb/Model/index.js b/node_modules/@nozbe/watermelondb/Model/index.js
+index b0e3a83..47313d4 100644
+--- a/node_modules/@nozbe/watermelondb/Model/index.js
++++ b/node_modules/@nozbe/watermelondb/Model/index.js
+@@ -81,7 +81,7 @@ var Model = /*#__PURE__*/function () {
+ _proto.prepareUpdate = function prepareUpdate(recordUpdater = _noop.default) {
+ var _this = this;
+
+- (0, _invariant.default)(!this._preparedState, "Cannot update a record with pending changes");
++ (0, _invariant.default)(!this._preparedState, "Cannot update a record with pending changes in table " + _this.table);
+
+ this.__ensureNotDisposable("Model.prepareUpdate()");
+
+@@ -92,6 +92,7 @@ var Model = /*#__PURE__*/function () {
+ } // Perform updates
+
+
++ this.__original = Object.assign({}, this._raw);
+ (0, _ensureSync.default)(recordUpdater(this));
+ this._isEditing = false;
+ this._preparedState = 'update'; // TODO: `process.nextTick` doesn't work on React Native
+@@ -107,6 +108,18 @@ var Model = /*#__PURE__*/function () {
+ return this;
+ };
+
++ _proto.cancelPrepareUpdate = function cancelPrepareUpdate() {
++ if ('test' !== process.env.NODE_ENV && 'undefined' !== typeof process && process) {
++ (0, _invariant.default)('update' !== _this._preparedState, "Cannot cancel an update on a model that has not been prepared in table " + this.table);
++ }
++ this.__changes = null;
++ this._preparedState = null;
++ if (this.__original) {
++ this._raw = this.__original;
++ }
++ this.__original = undefined;
++ };
++
+ _proto.prepareMarkAsDeleted = function prepareMarkAsDeleted() {
+ (0, _invariant.default)(!this._preparedState, "Cannot mark a record with pending changes as deleted");
+
+diff --git a/node_modules/@nozbe/watermelondb/Query/index.d.ts b/node_modules/@nozbe/watermelondb/Query/index.d.ts
+index eb2bd84..eb02824 100644
+--- a/node_modules/@nozbe/watermelondb/Query/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/Query/index.d.ts
+@@ -73,7 +73,7 @@ export default class Query {
+
+ // Emits the number of matching records, then emits a new count every time it changes
+ // Note: By default, the Observable is throttled!
+- observeCount(isThrottled: boolean): Observable
++ observeCount(isThrottled?: boolean): Observable
+
+ // Queries database and returns an array with IDs of matching records
+ fetchIds(): Promise
+diff --git a/node_modules/@nozbe/watermelondb/QueryDescription/index.d.ts b/node_modules/@nozbe/watermelondb/QueryDescription/index.d.ts
+index cf2e1e0..6910974 100644
+--- a/node_modules/@nozbe/watermelondb/QueryDescription/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/QueryDescription/index.d.ts
+@@ -193,7 +193,7 @@ export function and(...clauses: Where[]): And
+
+ export function or(...clauses: Where[]): Or
+
+-export function sortBy(sortColumn: ColumnName, sortOrder: SortOrder): SortBy
++export function sortBy(sortColumn: ColumnName, sortOrder?: SortOrder): SortBy
+
+ export function take(count: number): Take
+
+@@ -230,7 +230,7 @@ export function experimentalJoinTables(tables: TableName[]): JoinTables
+
+ export function experimentalNestedJoin(from: TableName, to: TableName): NestedJoinTable
+
+-export function unsafeSqlQuery(sql: string, values: Value[]): SqlQuery
++export function unsafeSqlQuery(sql: string, values?: Value[]): SqlQuery
+
+ // const extractClauses: (clauses: Clause[]) => QueryDescription;
+
+diff --git a/node_modules/@nozbe/watermelondb/decorators/children/index.d.ts b/node_modules/@nozbe/watermelondb/decorators/children/index.d.ts
+index 53d3daf..b26a60a 100644
+--- a/node_modules/@nozbe/watermelondb/decorators/children/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/decorators/children/index.d.ts
+@@ -1,4 +1,4 @@
+ import { TableName } from '../../Schema'
+
+-type children = (childTable: TableName) => PropertyDecorator
++const children = (childTable: TableName) => PropertyDecorator
+ export default children
+diff --git a/node_modules/@nozbe/watermelondb/decorators/date/index.d.ts b/node_modules/@nozbe/watermelondb/decorators/date/index.d.ts
+index 10381e6..020654e 100644
+--- a/node_modules/@nozbe/watermelondb/decorators/date/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/decorators/date/index.d.ts
+@@ -1,4 +1,4 @@
+ import { ColumnName } from '../../Schema'
+
+-type date = (columnName: ColumnName) => PropertyDecorator
++const date = (columnName: ColumnName) => PropertyDecorator
+ export default date
+diff --git a/node_modules/@nozbe/watermelondb/decorators/field/index.d.ts b/node_modules/@nozbe/watermelondb/decorators/field/index.d.ts
+index 87625ac..520f15e 100644
+--- a/node_modules/@nozbe/watermelondb/decorators/field/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/decorators/field/index.d.ts
+@@ -1,4 +1,4 @@
+ import { ColumnName } from '../../Schema'
+
+-type field = (columnName: ColumnName) => PropertyDecorator
++const field = (columnName: ColumnName) => PropertyDecorator
+ export default field
+diff --git a/node_modules/@nozbe/watermelondb/decorators/immutableRelation/index.d.ts b/node_modules/@nozbe/watermelondb/decorators/immutableRelation/index.d.ts
+index 6a7e860..529bcd9 100644
+--- a/node_modules/@nozbe/watermelondb/decorators/immutableRelation/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/decorators/immutableRelation/index.d.ts
+@@ -1,6 +1,6 @@
+ import { ColumnName, TableName } from '../../Schema'
+
+-type immutableRelation = (
++const immutableRelation = (
+ relationTable: TableName,
+ relationIdColumn: ColumnName,
+ ) => PropertyDecorator
+diff --git a/node_modules/@nozbe/watermelondb/decorators/json/index.d.ts b/node_modules/@nozbe/watermelondb/decorators/json/index.d.ts
+index 55de0d8..4aae413 100644
+--- a/node_modules/@nozbe/watermelondb/decorators/json/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/decorators/json/index.d.ts
+@@ -3,6 +3,6 @@ import Model from '../../Model'
+
+ type Sanitizer = (source: any, model?: Model) => any
+
+-type json = (rawFieldName: ColumnName, sanitizer: Sanitizer) => PropertyDecorator
++const json = (rawFieldName: ColumnName, sanitizer: Sanitizer) => PropertyDecorator
+
+ export default json
+diff --git a/node_modules/@nozbe/watermelondb/decorators/relation/index.d.ts b/node_modules/@nozbe/watermelondb/decorators/relation/index.d.ts
+index 9fea99e..ef7baae 100644
+--- a/node_modules/@nozbe/watermelondb/decorators/relation/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/decorators/relation/index.d.ts
+@@ -1,7 +1,7 @@
+ import { ColumnName, TableName } from '../../Schema'
+ import { Options } from '../../Relation'
+
+-type relation = (
++const relation = (
+ relationTable: TableName,
+ relationIdColumn: ColumnName,
+ options?: Options,
+diff --git a/node_modules/@nozbe/watermelondb/decorators/text/index.d.ts b/node_modules/@nozbe/watermelondb/decorators/text/index.d.ts
+index 330f187..334adbd 100644
+--- a/node_modules/@nozbe/watermelondb/decorators/text/index.d.ts
++++ b/node_modules/@nozbe/watermelondb/decorators/text/index.d.ts
+@@ -1,5 +1,5 @@
+ import { ColumnName } from '../../Schema'
+
+-type text = (columnName: ColumnName) => PropertyDecorator
++const text = (columnName: ColumnName) => PropertyDecorator
+
+ export default text
+diff --git a/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt b/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
+index ca31e20..b45c753 100644
+--- a/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
++++ b/node_modules/@nozbe/watermelondb/native/android/src/main/java/com/nozbe/watermelondb/Database.kt
+@@ -22,6 +22,21 @@ class Database(
+ if (name == ":memory:" || name.contains("mode=memory")) {
+ context.cacheDir.delete()
+ File(context.cacheDir, name).path
++ } else if (name.contains("/") || name.contains("file")) {
++ // Extracts the database name from the path
++ val dbName = name.substringAfterLast("/")
++
++ // Extracts the real path where the *.db file will be created
++ val truePath = name.substringAfterLast("file://").substringBeforeLast("/")
++
++ // Creates the directory
++ if (!truePath.contains("databases")) {
++ val fileObj = File(truePath, "databases")
++ fileObj.mkdir()
++ File("${truePath}/databases", dbName).path
++ } else {
++ File(truePath, dbName).path
++ }
+ } else {
+ // On some systems there is some kind of lock on `/databases` folder ¯\_(ツ)_/¯
+ context.getDatabasePath("$name.db").path.replace("/databases", "")
+diff --git a/node_modules/@nozbe/watermelondb/native/shared/Database.cpp b/node_modules/@nozbe/watermelondb/native/shared/Database.cpp
+index 1a1cabf..01bbb2b 100644
+--- a/node_modules/@nozbe/watermelondb/native/shared/Database.cpp
++++ b/node_modules/@nozbe/watermelondb/native/shared/Database.cpp
+@@ -54,6 +54,7 @@ void Database::destroy() {
+ const std::lock_guard lock(mutex_);
+
+ if (isDestroyed_) {
++ db_->markAsDestroyed();
+ return;
+ }
+ isDestroyed_ = true;
+diff --git a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp
+index e740c29..6963734 100644
+--- a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp
++++ b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp
+@@ -67,6 +67,10 @@ void SqliteDb::destroy() {
+ }
+ }
+
++void SqliteDb::markAsDestroyed() {
++ isDestroyed_ = true;
++}
++
+ SqliteDb::~SqliteDb() {
+ destroy();
+ }
+diff --git a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.h b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.h
+index 22cffa7..4b74a7f 100644
+--- a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.h
++++ b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.h
+@@ -11,6 +11,7 @@ public:
+ SqliteDb(std::string path);
+ ~SqliteDb();
+ void destroy();
++ void markAsDestroyed();
+
+ sqlite3 *sqlite;
+
diff --git a/patches/@rudderstack+rudder-sdk-react-native+1.5.1.patch b/patches/@rudderstack+rudder-sdk-react-native+1.5.1.patch
deleted file mode 100644
index 716513169e..0000000000
--- a/patches/@rudderstack+rudder-sdk-react-native+1.5.1.patch
+++ /dev/null
@@ -1,27 +0,0 @@
-diff --git a/node_modules/@rudderstack/rudder-sdk-react-native/android/build.gradle b/node_modules/@rudderstack/rudder-sdk-react-native/android/build.gradle
-index 24400ea..c69c39f 100644
---- a/node_modules/@rudderstack/rudder-sdk-react-native/android/build.gradle
-+++ b/node_modules/@rudderstack/rudder-sdk-react-native/android/build.gradle
-@@ -15,7 +15,7 @@ android {
- compileSdkVersion 30
-
- defaultConfig {
-- minSdkVersion 16
-+ minSdkVersion rootProject.hasProperty('minSdkVersion') ? rootProject.minSdkVersion : 21
- targetSdkVersion 30
- versionCode 1
- versionName "1.0"
-diff --git a/node_modules/@rudderstack/rudder-sdk-react-native/ios/RNRudderSdkModule.h b/node_modules/@rudderstack/rudder-sdk-react-native/ios/RNRudderSdkModule.h
-index f9020d1..7962e7b 100644
---- a/node_modules/@rudderstack/rudder-sdk-react-native/ios/RNRudderSdkModule.h
-+++ b/node_modules/@rudderstack/rudder-sdk-react-native/ios/RNRudderSdkModule.h
-@@ -1,9 +1,5 @@
-
--#if __has_include("RCTBridgeModule.h")
--#import "RCTBridgeModule.h"
--#else
- #import
--#endif
-
- @interface RNRudderSdkModule : NSObject
-
diff --git a/patches/@rudderstack+rudder-sdk-react-native+1.5.2.patch b/patches/@rudderstack+rudder-sdk-react-native+1.5.2.patch
new file mode 100644
index 0000000000..fff40d0312
--- /dev/null
+++ b/patches/@rudderstack+rudder-sdk-react-native+1.5.2.patch
@@ -0,0 +1,14 @@
+diff --git a/node_modules/@rudderstack/rudder-sdk-react-native/ios/RNRudderSdkModule.h b/node_modules/@rudderstack/rudder-sdk-react-native/ios/RNRudderSdkModule.h
+index f9020d1..7962e7b 100644
+--- a/node_modules/@rudderstack/rudder-sdk-react-native/ios/RNRudderSdkModule.h
++++ b/node_modules/@rudderstack/rudder-sdk-react-native/ios/RNRudderSdkModule.h
+@@ -1,9 +1,5 @@
+
+-#if __has_include("RCTBridgeModule.h")
+-#import "RCTBridgeModule.h"
+-#else
+ #import
+-#endif
+
+ @interface RNRudderSdkModule : NSObject
+
diff --git a/patches/react-native+0.70.6.patch b/patches/react-native+0.70.6.patch
deleted file mode 100644
index 28b2f81302..0000000000
--- a/patches/react-native+0.70.6.patch
+++ /dev/null
@@ -1,205 +0,0 @@
-diff --git a/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js b/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js
-index 698b62a..c855146 100644
---- a/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js
-+++ b/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js
-@@ -1780,9 +1780,15 @@ class ScrollView extends React.Component {
- // Note: we should split props.style on the inner and outer props
- // however, the ScrollView still needs the baseStyle to be scrollable
- const {outer, inner} = splitLayoutProps(flattenStyle(props.style));
-+ let inverted;
-+ if (inner.scaleY) {
-+ inverted = {scaleY: -1};
-+ delete inner['scaleY']
-+ }
-+
- return React.cloneElement(
- refreshControl,
-- {style: StyleSheet.compose(baseStyle, outer)},
-+ {style: [baseStyle, outer, inverted]},
- {
-@@ -1986,12 +1987,16 @@ class CellRenderer extends React.Component<
- props: CellRendererProps,
- prevState: CellRendererState,
- ): ?CellRendererState {
-- return {
-- separatorProps: {
-- ...prevState.separatorProps,
-- leadingItem: props.item,
-- },
-- };
-+ if (prevState.separatorProps.leadingItem !== props.item) {
-+ return {
-+ separatorProps: {
-+ ...prevState.separatorProps,
-+ leadingItem: props.item,
-+ },
-+ };
-+ } else {
-+ return prevState;
-+ }
- }
-
- // TODO: consider factoring separator stuff out of VirtualizedList into FlatList since it's not
-@@ -2171,7 +2176,10 @@ function describeNestedLists(childList: {
-
- const styles = StyleSheet.create({
- verticallyInverted: {
-- transform: [{scaleY: -1}],
-+ ...Platform.select({
-+ android: {scaleY: -1},
-+ ios: {transform: [{scaleY: -1}]},
-+ }),
- },
- horizontallyInverted: {
- transform: [{scaleX: -1}],
-diff --git a/node_modules/react-native/react.gradle b/node_modules/react-native/react.gradle
-index 912a407..01fa3ba 100644
---- a/node_modules/react-native/react.gradle
-+++ b/node_modules/react-native/react.gradle
-@@ -141,7 +141,7 @@ def enableHermesForVariant = config.enableHermesForVariant ?: {
- def hermesFlagsForVariant = config.hermesFlagsForVariant ?: {
- def variant ->
- def hermesFlags;
-- if (variant.name.toLowerCase().contains("release")) {
-+ if (variant.name.toLowerCase().contains("release") || variant.name.toLowerCase().contains("unsigned")) {
- // Can't use ?: since that will also substitute valid empty lists
- hermesFlags = config.hermesFlagsRelease
- if (hermesFlags == null) hermesFlags = ["-O", "-output-source-map"]
-@@ -157,7 +157,7 @@ def hermesFlagsForVariant = config.hermesFlagsForVariant ?: {
- def disableDevForVariant = config.disableDevForVariant ?: {
- def variant ->
- config."devDisabledIn${variant.name.capitalize()}" ||
-- variant.name.toLowerCase().contains("release")
-+ variant.name.toLowerCase().contains("release") || variant.name.toLowerCase().contains("unsigned")
- }
-
- // Set bundleForVariant to a function to configure per variant,
-@@ -166,13 +166,13 @@ def bundleForVariant = config.bundleForVariant ?: {
- def variant ->
- config."bundleIn${variant.name.capitalize()}" ||
- config."bundleIn${variant.buildType.name.capitalize()}" ||
-- variant.name.toLowerCase().contains("release")
-+ variant.name.toLowerCase().contains("release") || variant.name.toLowerCase().contains("unsigned")
- }
-
- // Set deleteDebugFilesForVariant to a function to configure per variant,
- // defaults to True for Release variants and False for debug variants
- def deleteDebugFilesForVariant = config.deleteDebugFilesForVariant ?: {
-- def variant -> variant.name.toLowerCase().contains("release")
-+ def variant -> variant.name.toLowerCase().contains("release") || variant.name.toLowerCase().contains("unsigned")
- }
-
- android {
-diff --git a/node_modules/react-native/sdks/hermes/hermes-engine.podspec b/node_modules/react-native/sdks/hermes/hermes-engine.podspec
-new file mode 100644
-index 0000000..8d331e0
---- /dev/null
-+++ b/node_modules/react-native/sdks/hermes/hermes-engine.podspec
-@@ -0,0 +1,84 @@
-+# 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.
-+
-+require "json"
-+require "open3"
-+
-+# sdks/hermesc/osx-bin/ImportHermesc.cmake
-+import_hermesc_file=File.join(__dir__, "..", "hermesc", "osx-bin", "ImportHermesc.cmake")
-+
-+# package.json
-+package_file = File.join(__dir__, "..", "..", "package.json")
-+package = JSON.parse(File.read(package_file))
-+version = package['version']
-+
-+# We need to check the current git branch/remote to verify if
-+# we're on a React Native release branch to actually build Hermes.
-+currentbranch, err = Open3.capture3("git rev-parse --abbrev-ref HEAD")
-+currentremote, err = Open3.capture3("git config --get remote.origin.url")
-+
-+source = {}
-+git = "https://github.com/facebook/hermes.git"
-+
-+if ENV.has_key?('HERMES_ENGINE_TARBALL_PATH')
-+ Pod::UI.puts '[Hermes] Using pre-built Hermes binaries from local path.' if Object.const_defined?("Pod::UI")
-+ source[:http] = "file://#{ENV['HERMES_ENGINE_TARBALL_PATH']}"
-+elsif version == '1000.0.0'
-+ Pod::UI.puts '[Hermes] Hermes needs to be compiled, installing hermes-engine may take a while...'.yellow if Object.const_defined?("Pod::UI")
-+ source[:git] = git
-+ source[:commit] = `git ls-remote https://github.com/facebook/hermes main | cut -f 1`.strip
-+elsif currentremote.strip.end_with?("facebook/react-native.git") and currentbranch.strip.end_with?("-stable")
-+ Pod::UI.puts '[Hermes] Detected that you are on a React Native release branch, building Hermes from source...'.yellow if Object.const_defined?("Pod::UI")
-+ hermestag_file = File.join(__dir__, "..", ".hermesversion")
-+ hermestag = File.read(hermestag_file).strip
-+ source[:git] = git
-+ source[:tag] = hermestag
-+else
-+ source[:http] = "https://github.com/facebook/react-native/releases/download/v#{version}/hermes-runtime-darwin-v#{version}.tar.gz"
-+end
-+
-+module HermesHelper
-+ # BUILD_TYPE = :debug
-+ BUILD_TYPE = :release
-+end
-+
-+Pod::Spec.new do |spec|
-+ spec.name = "hermes-engine"
-+ spec.version = version
-+ spec.summary = "Hermes is a small and lightweight JavaScript engine optimized for running React Native."
-+ spec.description = "Hermes is a JavaScript engine optimized for fast start-up of React Native apps. It features ahead-of-time static optimization and compact bytecode."
-+ spec.homepage = "https://hermesengine.dev"
-+ spec.license = package["license"]
-+ spec.author = "Facebook"
-+ spec.source = source
-+ spec.platforms = { :osx => "10.13", :ios => "12.4" }
-+
-+ spec.preserve_paths = ["destroot/bin/*"].concat(HermesHelper::BUILD_TYPE == :debug ? ["**/*.{h,c,cpp}"] : [])
-+ spec.source_files = "destroot/include/**/*.h"
-+ spec.header_mappings_dir = "destroot/include"
-+
-+ spec.ios.vendored_frameworks = "destroot/Library/Frameworks/universal/hermes.xcframework"
-+ spec.osx.vendored_frameworks = "destroot/Library/Frameworks/macosx/hermes.framework"
-+
-+ spec.xcconfig = { "CLANG_CXX_LANGUAGE_STANDARD" => "c++17", "CLANG_CXX_LIBRARY" => "compiler-default", "GCC_PREPROCESSOR_DEFINITIONS" => "HERMES_ENABLE_DEBUGGER=1" }
-+
-+ if source[:git] then
-+ spec.prepare_command = <<-EOS
-+ # When true, debug build will be used.
-+ # See `build-apple-framework.sh` for details
-+ DEBUG=#{HermesHelper::BUILD_TYPE == :debug}
-+
-+ # Set HERMES_OVERRIDE_HERMESC_PATH if pre-built HermesC is available
-+ #{File.exist?(import_hermesc_file) ? "export HERMES_OVERRIDE_HERMESC_PATH=#{import_hermesc_file}" : ""}
-+ #{File.exist?(import_hermesc_file) ? "echo \"Overriding HermesC path...\"" : ""}
-+
-+ # Build iOS framework
-+ ./utils/build-ios-framework.sh
-+
-+ # Build Mac framework
-+ ./utils/build-mac-framework.sh
-+ EOS
-+ end
-+end
diff --git a/patches/react-native+0.71.1.patch b/patches/react-native+0.71.1.patch
new file mode 100644
index 0000000000..39656c3560
--- /dev/null
+++ b/patches/react-native+0.71.1.patch
@@ -0,0 +1,106 @@
+diff --git a/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js b/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js
+index 0c2ecf2..a04414f 100644
+--- a/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js
++++ b/node_modules/react-native/Libraries/Components/ScrollView/ScrollView.js
+@@ -1819,9 +1819,14 @@ class ScrollView extends React.Component {
+ // Note: we should split props.style on the inner and outer props
+ // however, the ScrollView still needs the baseStyle to be scrollable
+ const {outer, inner} = splitLayoutProps(flattenStyle(props.style));
++ let inverted;
++ if (inner.scaleY) {
++ inverted = {scaleY: -1};
++ delete inner['scaleY']
++ }
+ return React.cloneElement(
+ refreshControl,
+- {style: StyleSheet.compose(baseStyle, outer)},
++ {style: StyleSheet.compose(baseStyle, outer, inverted)},
+
+ def hermesFlags;
+- if (variant.name.toLowerCase().contains("release")) {
++ if (variant.name.toLowerCase().contains("release") || variant.name.toLowerCase().contains("unsigned")) {
+ // Can't use ?: since that will also substitute valid empty lists
+ hermesFlags = config.hermesFlagsRelease
+ if (hermesFlags == null) hermesFlags = ["-O", "-output-source-map"]
+@@ -175,7 +175,7 @@ def hermesFlagsForVariant = config.hermesFlagsForVariant ?: {
+ def disableDevForVariant = config.disableDevForVariant ?: {
+ def variant ->
+ config."devDisabledIn${variant.name.capitalize()}" ||
+- variant.name.toLowerCase().contains("release")
++ variant.name.toLowerCase().contains("release") || variant.name.toLowerCase().contains("unsigned")
+ }
+
+ // Set bundleForVariant to a function to configure per variant,
+@@ -184,13 +184,13 @@ def bundleForVariant = config.bundleForVariant ?: {
+ def variant ->
+ config."bundleIn${variant.name.capitalize()}" ||
+ config."bundleIn${variant.buildType.name.capitalize()}" ||
+- variant.name.toLowerCase().contains("release")
++ variant.name.toLowerCase().contains("release") || variant.name.toLowerCase().contains("unsigned")
+ }
+
+ // Set deleteDebugFilesForVariant to a function to configure per variant,
+ // defaults to True for Release variants and False for debug variants
+ def deleteDebugFilesForVariant = config.deleteDebugFilesForVariant ?: {
+- def variant -> variant.name.toLowerCase().contains("release")
++ def variant -> variant.name.toLowerCase().contains("release") || variant.name.toLowerCase().contains("unsigned")
+ }
+
+ android {
diff --git a/patches/react-native-create-thumbnail+1.6.4.patch b/patches/react-native-create-thumbnail+1.6.4.patch
index 7d1aa97d62..f5135e7e5e 100644
--- a/patches/react-native-create-thumbnail+1.6.4.patch
+++ b/patches/react-native-create-thumbnail+1.6.4.patch
@@ -1,3 +1,63 @@
+diff --git a/node_modules/react-native-create-thumbnail/android/src/main/java/com/createthumbnail/CreateThumbnailModule.java b/node_modules/react-native-create-thumbnail/android/src/main/java/com/createthumbnail/CreateThumbnailModule.java
+index 9bd67d8..bf4175a 100644
+--- a/node_modules/react-native-create-thumbnail/android/src/main/java/com/createthumbnail/CreateThumbnailModule.java
++++ b/node_modules/react-native-create-thumbnail/android/src/main/java/com/createthumbnail/CreateThumbnailModule.java
+@@ -169,31 +169,35 @@ public class CreateThumbnailModule extends ReactContextBaseJavaModule {
+ }
+
+ private static Bitmap getBitmapAtTime(Context context, String filePath, int time, Map headers) {
+- MediaMetadataRetriever retriever = new MediaMetadataRetriever();
+- if (URLUtil.isFileUrl(filePath)) {
+- String decodedPath;
+- try {
+- decodedPath = URLDecoder.decode(filePath, "UTF-8");
+- } catch (UnsupportedEncodingException e) {
+- decodedPath = filePath;
+- }
++ try {
++ MediaMetadataRetriever retriever = new MediaMetadataRetriever();
++ if (URLUtil.isFileUrl(filePath)) {
++ String decodedPath;
++ try {
++ decodedPath = URLDecoder.decode(filePath, "UTF-8");
++ } catch (UnsupportedEncodingException e) {
++ decodedPath = filePath;
++ }
+
+- retriever.setDataSource(decodedPath.replace("file://", ""));
+- } else if (filePath.contains("content://")) {
+- retriever.setDataSource(context, Uri.parse(filePath));
+- } else {
+- if (VERSION.SDK_INT < 14) {
+- throw new IllegalStateException("Remote videos aren't supported on sdk_version < 14");
++ retriever.setDataSource(decodedPath.replace("file://", ""));
++ } else if (filePath.contains("content://")) {
++ retriever.setDataSource(context, Uri.parse(filePath));
++ } else {
++ if (VERSION.SDK_INT < 14) {
++ throw new IllegalStateException("Remote videos aren't supported on sdk_version < 14");
++ }
++ retriever.setDataSource(filePath, headers);
+ }
+- retriever.setDataSource(filePath, headers);
+- }
+
+- Bitmap image = retriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
+- retriever.release();
+- if (image == null) {
++ Bitmap image = retriever.getFrameAtTime(time * 1000, MediaMetadataRetriever.OPTION_CLOSEST_SYNC);
++ retriever.release();
++ if (image == null) {
++ throw new IllegalStateException("File doesn't exist or not supported");
++ }
++ return image;
++ } catch (Exception e) {
+ throw new IllegalStateException("File doesn't exist or not supported");
+ }
+- return image;
+ }
+
+ private static long getDirSize(File dir) {
diff --git a/node_modules/react-native-create-thumbnail/ios/CreateThumbnail.h b/node_modules/react-native-create-thumbnail/ios/CreateThumbnail.h
index 28b1d9b..cb63c52 100644
--- a/node_modules/react-native-create-thumbnail/ios/CreateThumbnail.h
@@ -10,7 +70,7 @@ index 28b1d9b..cb63c52 100644
++(void)create:(NSDictionary *)config findEventsWithResolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject;
@end
diff --git a/node_modules/react-native-create-thumbnail/ios/CreateThumbnail.m b/node_modules/react-native-create-thumbnail/ios/CreateThumbnail.m
-index 92cc49f..23cc83c 100644
+index 92cc49f..a2bab15 100644
--- a/node_modules/react-native-create-thumbnail/ios/CreateThumbnail.m
+++ b/node_modules/react-native-create-thumbnail/ios/CreateThumbnail.m
@@ -6,6 +6,10 @@ RCT_EXPORT_MODULE()
diff --git a/patches/react-native-navigation+7.30.6.patch b/patches/react-native-navigation+7.31.1.patch
similarity index 62%
rename from patches/react-native-navigation+7.30.6.patch
rename to patches/react-native-navigation+7.31.1.patch
index eeb56c9abb..616628d8f5 100644
--- a/patches/react-native-navigation+7.30.6.patch
+++ b/patches/react-native-navigation+7.31.1.patch
@@ -1,8 +1,39 @@
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java
-index 226d3bf..6213a88 100644
+index 8ddc3d5..c4acd2d 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/NavigationActivity.java
-@@ -48,7 +48,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
+@@ -1,18 +1,15 @@
+ package com.reactnativenavigation;
+
+-import android.annotation.TargetApi;
+ import android.content.Intent;
+ import android.content.res.Configuration;
+-import android.graphics.Color;
+-import android.os.Build;
+ import android.os.Bundle;
+ import android.view.KeyEvent;
+ import android.view.View;
+
++import com.facebook.react.ReactActivity;
+ import com.facebook.react.modules.core.DefaultHardwareBackBtnHandler;
+ import com.facebook.react.modules.core.PermissionAwareActivity;
+ import com.facebook.react.modules.core.PermissionListener;
+-import com.reactnativenavigation.options.Options;
+ import com.reactnativenavigation.viewcontrollers.overlay.OverlayManager;
+ import com.reactnativenavigation.viewcontrollers.viewcontroller.RootPresenter;
+ import com.reactnativenavigation.react.JsDevReloadHandler;
+@@ -25,9 +22,8 @@ import com.reactnativenavigation.viewcontrollers.navigator.Navigator;
+ import androidx.activity.OnBackPressedCallback;
+ import androidx.annotation.NonNull;
+ import androidx.annotation.Nullable;
+-import androidx.appcompat.app.AppCompatActivity;
+
+-public class NavigationActivity extends AppCompatActivity implements DefaultHardwareBackBtnHandler, PermissionAwareActivity, JsDevReloadHandler.ReloadListener {
++public class NavigationActivity extends ReactActivity implements DefaultHardwareBackBtnHandler, PermissionAwareActivity, JsDevReloadHandler.ReloadListener {
+ @Nullable
+ private PermissionListener mPermissionListener;
+
+@@ -50,7 +46,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
);
navigator.bindViews();
getReactGateway().onActivityCreated(this);
@@ -11,18 +42,40 @@ index 226d3bf..6213a88 100644
}
@Override
-@@ -141,6 +141,11 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
- navigator.destroyViews();
+@@ -96,15 +92,11 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
+
+ @Override
+ public void invokeDefaultOnBackPressed() {
+- if (!navigator.handleBack(new CommandListenerAdapter())) {
+- callback.setEnabled(false);
+- NavigationActivity.super.onBackPressed();
+- callback.setEnabled(true);
+- }
++ super.invokeDefaultOnBackPressed();
}
-+ @Override
-+ public void onBackPressed() {
-+ getReactGateway().onBackPressed();
-+ }
-+
- protected void addDefaultSplashLayout() {
- View view = new View(this);
- setContentView(view);
+ @Override
+- protected void onActivityResult(int requestCode, int resultCode, Intent data) {
++ public void onActivityResult(int requestCode, int resultCode, Intent data) {
+ super.onActivityResult(requestCode, resultCode, data);
+ getReactGateway().onActivityResult(this, requestCode, resultCode, data);
+ }
+@@ -126,7 +118,6 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
+ return navigator;
+ }
+
+- @TargetApi(Build.VERSION_CODES.M)
+ public void requestPermissions(String[] permissions, int requestCode, PermissionListener listener) {
+ mPermissionListener = listener;
+ requestPermissions(permissions, requestCode);
+@@ -134,6 +125,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
+
+ @Override
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
++ super.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ NavigationApplication.instance.onRequestPermissionsResult(requestCode, permissions, grantResults);
+ if (mPermissionListener != null && mPermissionListener.onRequestPermissionsResult(requestCode, permissions, grantResults)) {
+ mPermissionListener = null;
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java
index a34598c..b035a76 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java
@@ -109,23 +162,21 @@ index a34598c..b035a76 100644
if (navigationActivity != null) {
navigationActivity.onCatalystInstanceDestroy();
}
-diff --git a/node_modules/react-native-navigation/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReactGateway.java b/node_modules/react-native-navigation/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReactGateway.java
-index 035ec31..38109c1 100644
---- a/node_modules/react-native-navigation/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReactGateway.java
-+++ b/node_modules/react-native-navigation/lib/android/app/src/reactNative68/java/com/reactnativenavigation/react/ReactGateway.java
-@@ -48,6 +48,12 @@ public class ReactGateway {
- }
+diff --git a/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/ReactGateway.java b/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/ReactGateway.java
+index 035ec31..630b8d4 100644
+--- a/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/ReactGateway.java
++++ b/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/ReactGateway.java
+@@ -69,4 +69,10 @@ public class ReactGateway {
+ public void onActivityResult(Activity activity, int requestCode, int resultCode, Intent data) {
+ host.getReactInstanceManager().onActivityResult(activity, requestCode, resultCode, data);
}
-
++
+ public void onWindowFocusChanged(boolean hasFocus) {
+ if (host.hasInstance()) {
+ host.getReactInstanceManager().onWindowFocusChange(hasFocus);
+ }
+ }
-+
- public void onActivityPaused(NavigationActivity activity) {
- initializer.onActivityPaused(activity);
- jsDevReloadHandler.onActivityPaused(activity);
+ }
diff --git a/node_modules/react-native-navigation/lib/ios/RNNComponentViewController.m b/node_modules/react-native-navigation/lib/ios/RNNComponentViewController.m
index 3ce9674..ae34704 100644
--- a/node_modules/react-native-navigation/lib/ios/RNNComponentViewController.m
@@ -186,3 +237,14 @@ index f814815..bb39a10 100644
@interface RNNReactView
: RCTFabricSurfaceHostingProxyRootView
#else
+diff --git a/node_modules/react-native-navigation/lib/src/interfaces/Options.ts b/node_modules/react-native-navigation/lib/src/interfaces/Options.ts
+index 4851b40..e891183 100644
+--- a/node_modules/react-native-navigation/lib/src/interfaces/Options.ts
++++ b/node_modules/react-native-navigation/lib/src/interfaces/Options.ts
+@@ -1,5 +1,5 @@
+ // tslint:disable jsdoc-format
+-import { ImageRequireSource, ImageSourcePropType, Insets, OpaqueColorValue } from 'react-native';
++import type { ImageRequireSource, ImageSourcePropType, Insets, OpaqueColorValue } from 'react-native';
+
+ // TODO: Import ColorValue instead when upgrading @types/react-native to 0.63+
+ // Only assign PlatformColor or DynamicColorIOS as a Color symbol!
diff --git a/patches/react-native-reanimated+2.13.0.patch b/patches/react-native-reanimated+2.14.4.patch
similarity index 100%
rename from patches/react-native-reanimated+2.13.0.patch
rename to patches/react-native-reanimated+2.14.4.patch
diff --git a/patches/react-native-svg+13.6.0.patch b/patches/react-native-svg+13.7.0.patch
similarity index 100%
rename from patches/react-native-svg+13.6.0.patch
rename to patches/react-native-svg+13.7.0.patch
diff --git a/patches/react-native-walkthrough-tooltip+1.4.0.patch b/patches/react-native-walkthrough-tooltip+1.5.0.patch
similarity index 68%
rename from patches/react-native-walkthrough-tooltip+1.4.0.patch
rename to patches/react-native-walkthrough-tooltip+1.5.0.patch
index 38e9501d4f..2a6f6e4def 100644
--- a/patches/react-native-walkthrough-tooltip+1.4.0.patch
+++ b/patches/react-native-walkthrough-tooltip+1.5.0.patch
@@ -1,16 +1,3 @@
-diff --git a/node_modules/react-native-walkthrough-tooltip/src/tooltip.d.ts b/node_modules/react-native-walkthrough-tooltip/src/tooltip.d.ts
-index 5a7ef59..305d794 100644
---- a/node_modules/react-native-walkthrough-tooltip/src/tooltip.d.ts
-+++ b/node_modules/react-native-walkthrough-tooltip/src/tooltip.d.ts
-@@ -129,6 +129,8 @@ declare module 'react-native-walkthrough-tooltip' {
-
- /** Will use given component instead of default react-native Modal component **/
- modalComponent?: object;
-+
-+ children: React.ReactNode;
- }
-
- /**
diff --git a/node_modules/react-native-walkthrough-tooltip/src/tooltip.js b/node_modules/react-native-walkthrough-tooltip/src/tooltip.js
index db612fd..0262d6d 100644
--- a/node_modules/react-native-walkthrough-tooltip/src/tooltip.js
diff --git a/test/setup.ts b/test/setup.ts
index eea80218bc..a2c629ad1d 100644
--- a/test/setup.ts
+++ b/test/setup.ts
@@ -137,6 +137,9 @@ jest.doMock('react-native', () => {
const Linking = {
...RNLinking,
openURL: jest.fn(),
+ addEventListener: jest.fn(() => {
+ return {remove: jest.fn()};
+ }),
};
return Object.setPrototypeOf({
@@ -278,7 +281,7 @@ jest.mock('react-native-navigation', () => {
return {remove: jest.fn()};
}),
registerNavigationButtonPressedListener: jest.fn(() => {
- return {buttonId: 'buttonId'};
+ return {remove: jest.fn()};
}),
}),
setRoot: jest.fn(),
diff --git a/tsconfig.json b/tsconfig.json
index 0dec6dd843..261c51508c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -8,13 +8,18 @@
"allowJs": false,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
+ "allowUnreachableCode": false,
+ "allowUnusedLabels": false,
"esModuleInterop": true,
"isolatedModules": true,
- "jsx": "react",
+ "jsx": "react-native",
+ "types": ["react-native", "node", "jest"],
"moduleResolution": "node",
"noEmit": false,
"strict": true,
"importHelpers": true,
+ "importsNotUsedAsValues": "error",
+ "forceConsistentCasingInFileNames": true,
"declaration": true,
"sourceMap": false,
"rootDir": "./",
@@ -29,6 +34,7 @@
"downlevelIteration": true,
"noUnusedParameters": false,
"noImplicitReturns": true,
+ "noImplicitUseStrict": false,
"noFallthroughCasesInSwitch": true,
"resolveJsonModule": true,
"baseUrl": ".",
diff --git a/types/api/teams.d.ts b/types/api/teams.d.ts
index e3c0784b3e..5fe283f0a6 100644
--- a/types/api/teams.d.ts
+++ b/types/api/teams.d.ts
@@ -19,6 +19,11 @@ type TeamMemberWithError = {
error: ApiError;
}
+type TeamInviteWithError = {
+ email: string;
+ error: ApiError;
+}
+
type TeamType = 'O' | 'I';
type Team = {
diff --git a/types/components/syntax_highlight.ts b/types/components/syntax_highlight.ts
index d8f959e5f8..9cea988bde 100644
--- a/types/components/syntax_highlight.ts
+++ b/types/components/syntax_highlight.ts
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {TextStyle} from 'react-native';
+import type {TextStyle} from 'react-native';
export type SyntaxHiglightProps = {
code: string;
diff --git a/types/database/database.ts b/types/database/database.ts
index 3041c2b068..2b90992f4d 100644
--- a/types/database/database.ts
+++ b/types/database/database.ts
@@ -9,7 +9,6 @@ import type ServerDataOperator from '@database/operator/server_data_operator';
import type {Database} from '@nozbe/watermelondb';
import type Model from '@nozbe/watermelondb/Model';
import type {Clause} from '@nozbe/watermelondb/QueryDescription';
-import type {Class} from '@nozbe/watermelondb/utils/common';
import type System from '@typings/database/models/servers/system';
export type WithDatabaseArgs = { database: Database }
@@ -51,6 +50,10 @@ export type TransformerArgs = {
value: RecordPair;
};
+export type PrepareBaseRecordArgs = TransformerArgs & {
+ fieldsMapper: (model: Model) => void;
+}
+
export type OperationArgs = {
tableName: string;
createRaws?: RecordPair[];
@@ -59,7 +62,7 @@ export type OperationArgs = {
transformer: (args: TransformerArgs) => Promise;
};
-export type Models = Array>;
+export type Models = Model[];
// The elements needed to create a new database
export type CreateServerDatabaseArgs = {
diff --git a/types/global/data_retention.d.ts b/types/global/data_retention.d.ts
new file mode 100644
index 0000000000..99e907e967
--- /dev/null
+++ b/types/global/data_retention.d.ts
@@ -0,0 +1,19 @@
+// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
+// See LICENSE.txt for license information.
+
+type GlobalDataRetentionPolicy = {
+ file_deletion_enabled: boolean;
+ file_retention_cutoff: number;
+ message_deletion_enabled: boolean;
+ message_retention_cutoff: number;
+}
+
+type TeamDataRetentionPolicy = {
+ post_duration: number;
+ team_id: string;
+}
+
+type ChannelDataRetentionPolicy = {
+ post_duration: number;
+ channel_id: string;
+}
diff --git a/types/global/markdown.ts b/types/global/markdown.ts
index a478b1128f..df1ab69461 100644
--- a/types/global/markdown.ts
+++ b/types/global/markdown.ts
@@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {TextStyle, ViewStyle} from 'react-native';
+import type {TextStyle, ViewStyle} from 'react-native';
export type SearchPattern = {
pattern: RegExp;
diff --git a/types/global/styles.ts b/types/global/styles.ts
index f3c43b0843..40d0532141 100644
--- a/types/global/styles.ts
+++ b/types/global/styles.ts
@@ -1,5 +1,5 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
-import {ImageStyle, TextStyle, ViewStyle} from 'react-native';
+import type {ImageStyle, TextStyle, ViewStyle} from 'react-native';
export type NamedStyles = { [P in keyof T]: ViewStyle | TextStyle | ImageStyle };
diff --git a/types/screens/edit_profile.ts b/types/screens/edit_profile.ts
index 1a8d23231f..08c61f72a1 100644
--- a/types/screens/edit_profile.ts
+++ b/types/screens/edit_profile.ts
@@ -1,6 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
+import type {AvailableScreens} from './navigation';
import type {FloatingTextInputRef} from '@components/floating_text_input_label';
import type {FieldProps} from '@screens/edit_profile/components/field';
import type UserModel from '@typings/database/models/servers/user';
@@ -16,7 +17,7 @@ export interface UserInfo extends Record