Update dependencies (#8721)

* update fastlane

* update dev dependencies

* update to eslint 9+

* update testing-library

* update react-intl

* update bottom-sheet

* update expo

* update reanimated

* upgrade msgpack

* upgrade datepicker

* upgrade react-navigation

* update sentry

* update FlasList

* update fuse.js moment-timezone node-html-parser and semver

* update gesture-handler

* update image-picker

* update react-native-keychain

* update react-native-localize

* update react-native-navigation

* update watermelonDB

* update react-native-permissions

* update react-native-safe-area-context and react-native-screens

* update react-native-share and react-native-svg

* update react-native-video and react-native-webrtc

* update @mattermost/rnutils

* update @mattermost/rnshare

* update @mattermost/hardware-keyboard

* fix isMainActivity

* update android dependencies

* fix upload file progress indicator

* fix entry update config & license

* revert to stable version of @sentry/react-native

* update react-intl again

* update moment-timezone

* upgrade @react-native-camera-roll/camera-roll

* update @react-native-clipboard/clipboard

* update @react-navigation again

* update @shopify/flash-list

* update eslint

* update expo again

* update html-entities

* update mime-db

* update react-native-permissions

* Revert "update react-intl again"

This reverts commit e8e6d5a60dfa56b82b810cbbd7cdffec7697ffc7.

* Revert "update react-intl"

This reverts commit c77f329bb38910aeeba03869b72d77a8b0e00ba1.

* update react-native-keychain

* update and patch react-intl

* mend

* feedback during review 1
This commit is contained in:
Elias Nahum 2025-04-07 09:30:06 +08:00 committed by GitHub
parent fefa164a06
commit 374f812b98
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
72 changed files with 3128 additions and 2855 deletions

View file

@ -1,115 +0,0 @@
{
"extends": [
"./eslint/eslint-mattermost",
"./eslint/eslint-react",
"plugin:@typescript-eslint/eslint-recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react-hooks/recommended"
],
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint",
"import"
],
"settings": {
"react": {
"pragma": "React",
"version": "17.0"
}
},
"env": {
"jest": true
},
"globals": {
"__DEV__": true
},
"rules": {
"eol-last": ["error", "always"],
"global-require": 0,
"no-undefined": 0,
"no-shadow": "off",
"react/display-name": [2, { "ignoreTranspilerName": false }],
"react/jsx-filename-extension": 0,
"react-hooks/exhaustive-deps": "warn",
"camelcase": [
0,
{
"properties": "never"
}
],
"@typescript-eslint/ban-types": 0,
"@typescript-eslint/no-non-null-assertion": 0,
"@typescript-eslint/no-unused-vars": [
2,
{
"vars": "all",
"args": "after-used"
}
],
"@typescript-eslint/no-shadow": ["error"],
"@typescript-eslint/no-explicit-any": "warn",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": 0,
"@typescript-eslint/no-var-requires": 0,
"@typescript-eslint/explicit-function-return-type": 0,
"@typescript-eslint/explicit-module-boundary-types": "off",
"no-underscore-dangle": "off",
"indent": [2, 4, {"SwitchCase": 1}],
"key-spacing": [2, {
"singleLine": {
"beforeColon": false,
"afterColon": true
}}],
"@typescript-eslint/member-delimiter-style": 2,
"@typescript-eslint/no-unsafe-declaration-merging": "off",
"import/order": [
2,
{
"groups": ["builtin", "external", "parent", "sibling", "index", "type"],
"newlines-between": "always",
"pathGroups": [
{
"pattern": "{@(@actions|@app|@assets|@calls|@client|@components|@constants|@context|@database|@helpers|@hooks|@init|@managers|@queries|@screens|@selectors|@share|@store|@telemetry|@typings|@test|@utils)/**,@(@constants|@i18n|@store|@websocket)}",
"group": "external",
"position": "after"
},
{
"pattern": "app/**",
"group": "parent",
"position": "before"
}
],
"alphabetize": {
"order": "asc",
"caseInsensitive": true
},
"pathGroupsExcludedImportTypes": ["type"]
}
]
},
"overrides": [
{
"files": ["*.test.js", "*.test.jsx"],
"env": {
"jest": true
}
},
{
"files": ["detox/e2e/**"],
"globals": {
"by": true,
"detox": true,
"device": true,
"element": true,
"waitFor": true
},
"rules": {
"func-names": 0,
"import/no-unresolved": 0,
"max-nested-callbacks": 0,
"no-process-env": 0,
"no-unused-expressions": 0
}
}
]
}

View file

@ -202,14 +202,14 @@ dependencies {
implementation jscFlavor
}
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3'
implementation 'androidx.appcompat:appcompat:1.7.0'
implementation 'com.google.android.material:material:1.12.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
implementation "com.google.firebase:firebase-messaging:$firebaseVersion"
androidTestImplementation('com.wix:detox:+')
androidTestImplementation 'androidx.test:core:1.6.0'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:core:1.6.1'
androidTestImplementation 'androidx.test:runner:1.6.2'
androidTestImplementation 'com.wix:detox:20.26.2'
// For animated GIF support
@ -231,16 +231,16 @@ dependencies {
configurations.all {
resolutionStrategy {
force 'androidx.test:core:1.6.0'
force 'androidx.test:core:1.6.1'
eachDependency { DependencyResolveDetails details ->
if (details.requested.name == 'play-services-base') {
details.useTarget group: details.requested.group, name: details.requested.name, version: '18.2.0'
details.useTarget group: details.requested.group, name: details.requested.name, version: '18.5.0'
}
if (details.requested.name == 'play-services-tasks') {
details.useTarget group: details.requested.group, name: details.requested.name, version: '18.0.2'
details.useTarget group: details.requested.group, name: details.requested.name, version: '18.2.0'
}
if (details.requested.name == 'play-services-basement') {
details.useTarget group: details.requested.group, name: details.requested.name, version: '18.2.0'
details.useTarget group: details.requested.group, name: details.requested.name, version: '18.5.0'
}
if (details.requested.name == 'okhttp') {
details.useTarget group: details.requested.group, name: details.requested.name, version: '4.12.0'

View file

@ -105,7 +105,7 @@ class CustomPushNotification(
CustomPushNotificationHelper.PUSH_TYPE_MESSAGE, CustomPushNotificationHelper.PUSH_TYPE_SESSION -> {
val currentActivityName = mAppLifecycleFacade.runningReactContext?.currentActivity?.componentName?.className ?: ""
TurboLog.i("ReactNative", currentActivityName)
if (!mAppLifecycleFacade.isAppVisible() || currentActivityName != "MainActivity") {
if (!mAppLifecycleFacade.isAppVisible() || !currentActivityName.contains("MainActivity")) {
var createSummary = type == CustomPushNotificationHelper.PUSH_TYPE_MESSAGE
if (type == CustomPushNotificationHelper.PUSH_TYPE_MESSAGE) {
channelId?.let {

View file

@ -19,7 +19,7 @@ buildscript {
dependencies {
classpath("com.android.tools.build:gradle")
classpath("com.facebook.react:react-native-gradle-plugin")
classpath('com.google.gms:google-services:4.4.0')
classpath('com.google.gms:google-services:4.4.2')
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin")
// NOTE: Do not place your application dependencies here; they belong

View file

@ -1,68 +1,68 @@
# This is a Gradle generated file for dependency locking.
# Manual edits can break the build and are not advised.
# This file is expected to be part of source control.
androidx.databinding:databinding-common:8.2.1=classpath
androidx.databinding:databinding-compiler-common:8.2.1=classpath
com.android.databinding:baseLibrary:8.2.1=classpath
com.android.tools.analytics-library:crash:31.2.1=classpath
com.android.tools.analytics-library:protos:31.2.1=classpath
com.android.tools.analytics-library:shared:31.2.1=classpath
com.android.tools.analytics-library:tracker:31.2.1=classpath
androidx.databinding:databinding-common:8.6.0=classpath
androidx.databinding:databinding-compiler-common:8.6.0=classpath
com.android.databinding:baseLibrary:8.6.0=classpath
com.android.tools.analytics-library:crash:31.6.0=classpath
com.android.tools.analytics-library:protos:31.6.0=classpath
com.android.tools.analytics-library:shared:31.6.0=classpath
com.android.tools.analytics-library:tracker:31.6.0=classpath
com.android.tools.build.jetifier:jetifier-core:1.0.0-beta10=classpath
com.android.tools.build.jetifier:jetifier-processor:1.0.0-beta10=classpath
com.android.tools.build:aapt2-proto:8.2.1-10154469=classpath
com.android.tools.build:aaptcompiler:8.2.1=classpath
com.android.tools.build:apksig:8.2.1=classpath
com.android.tools.build:apkzlib:8.2.1=classpath
com.android.tools.build:builder-model:8.2.1=classpath
com.android.tools.build:builder-test-api:8.2.1=classpath
com.android.tools.build:builder:8.2.1=classpath
com.android.tools.build:bundletool:1.15.2=classpath
com.android.tools.build:gradle-api:8.2.1=classpath
com.android.tools.build:gradle-settings-api:8.2.1=classpath
com.android.tools.build:gradle:8.2.1=classpath
com.android.tools.build:manifest-merger:31.2.1=classpath
com.android.tools.build:aapt2-proto:8.6.0-11315950=classpath
com.android.tools.build:aaptcompiler:8.6.0=classpath
com.android.tools.build:apksig:8.6.0=classpath
com.android.tools.build:apkzlib:8.6.0=classpath
com.android.tools.build:builder-model:8.6.0=classpath
com.android.tools.build:builder-test-api:8.6.0=classpath
com.android.tools.build:builder:8.6.0=classpath
com.android.tools.build:bundletool:1.16.0=classpath
com.android.tools.build:gradle-api:8.6.0=classpath
com.android.tools.build:gradle-settings-api:8.6.0=classpath
com.android.tools.build:gradle:8.6.0=classpath
com.android.tools.build:manifest-merger:31.6.0=classpath
com.android.tools.build:transform-api:2.0.0-deprecated-use-gradle-api=classpath
com.android.tools.ddms:ddmlib:31.2.1=classpath
com.android.tools.layoutlib:layoutlib-api:31.2.1=classpath
com.android.tools.lint:lint-model:31.2.1=classpath
com.android.tools.lint:lint-typedef-remover:31.2.1=classpath
com.android.tools.utp:android-device-provider-ddmlib-proto:31.2.1=classpath
com.android.tools.utp:android-device-provider-gradle-proto:31.2.1=classpath
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.2.1=classpath
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.2.1=classpath
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.2.1=classpath
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.2.1=classpath
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.2.1=classpath
com.android.tools.utp:android-test-plugin-host-retention-proto:31.2.1=classpath
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.2.1=classpath
com.android.tools:annotations:31.2.1=classpath
com.android.tools:common:31.2.1=classpath
com.android.tools:dvlib:31.2.1=classpath
com.android.tools:repository:31.2.1=classpath
com.android.tools:sdk-common:31.2.1=classpath
com.android.tools:sdklib:31.2.1=classpath
com.android:signflinger:8.2.1=classpath
com.android:zipflinger:8.2.1=classpath
com.android.tools.ddms:ddmlib:31.6.0=classpath
com.android.tools.layoutlib:layoutlib-api:31.6.0=classpath
com.android.tools.lint:lint-model:31.6.0=classpath
com.android.tools.lint:lint-typedef-remover:31.6.0=classpath
com.android.tools.utp:android-device-provider-ddmlib-proto:31.6.0=classpath
com.android.tools.utp:android-device-provider-gradle-proto:31.6.0=classpath
com.android.tools.utp:android-test-plugin-host-additional-test-output-proto:31.6.0=classpath
com.android.tools.utp:android-test-plugin-host-apk-installer-proto:31.6.0=classpath
com.android.tools.utp:android-test-plugin-host-coverage-proto:31.6.0=classpath
com.android.tools.utp:android-test-plugin-host-emulator-control-proto:31.6.0=classpath
com.android.tools.utp:android-test-plugin-host-logcat-proto:31.6.0=classpath
com.android.tools.utp:android-test-plugin-host-retention-proto:31.6.0=classpath
com.android.tools.utp:android-test-plugin-result-listener-gradle-proto:31.6.0=classpath
com.android.tools:annotations:31.6.0=classpath
com.android.tools:common:31.6.0=classpath
com.android.tools:dvlib:31.6.0=classpath
com.android.tools:repository:31.6.0=classpath
com.android.tools:sdk-common:31.6.0=classpath
com.android.tools:sdklib:31.6.0=classpath
com.android:signflinger:8.6.0=classpath
com.android:zipflinger:8.6.0=classpath
com.google.android.gms:strict-version-matcher-plugin:1.2.4=classpath
com.google.android:annotations:4.1.1.4=classpath
com.google.api.grpc:proto-google-common-protos:2.0.1=classpath
com.google.api.grpc:proto-google-common-protos:2.17.0=classpath
com.google.auto.value:auto-value-annotations:1.6.2=classpath
com.google.code.findbugs:jsr305:3.0.2=classpath
com.google.code.gson:gson:2.10=classpath
com.google.code.gson:gson:2.10.1=classpath
com.google.crypto.tink:tink:1.7.0=classpath
com.google.dagger:dagger:2.28.3=classpath
com.google.errorprone:error_prone_annotations:2.11.0=classpath
com.google.errorprone:error_prone_annotations:2.18.0=classpath
com.google.flatbuffers:flatbuffers-java:1.12.0=classpath
com.google.gms:google-services:4.4.0=classpath
com.google.gms:google-services:4.4.2=classpath
com.google.guava:failureaccess:1.0.1=classpath
com.google.guava:guava:31.1-jre=classpath
com.google.guava:guava:32.0.1-jre=classpath
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=classpath
com.google.j2objc:j2objc-annotations:1.3=classpath
com.google.j2objc:j2objc-annotations:2.8=classpath
com.google.jimfs:jimfs:1.1=classpath
com.google.protobuf:protobuf-java-util:3.19.3=classpath
com.google.protobuf:protobuf-java:3.19.3=classpath
com.google.testing.platform:core-proto:0.0.8-alpha08=classpath
com.google.protobuf:protobuf-java-util:3.22.3=classpath
com.google.protobuf:protobuf-java:3.22.3=classpath
com.google.testing.platform:core-proto:0.0.9-alpha02=classpath
com.googlecode.juniversalchardet:juniversalchardet:1.0.3=classpath
com.squareup:javapoet:1.13.0=classpath
com.squareup:javawriter:2.5.0=classpath
@ -70,27 +70,27 @@ com.sun.activation:javax.activation:1.2.0=classpath
com.sun.istack:istack-commons-runtime:3.0.8=classpath
com.sun.xml.fastinfoset:FastInfoset:1.2.16=classpath
commons-codec:commons-codec:1.11=classpath
commons-io:commons-io:2.4=classpath
commons-io:commons-io:2.13.0=classpath
commons-logging:commons-logging:1.2=classpath
io.grpc:grpc-api:1.45.1=classpath
io.grpc:grpc-context:1.45.1=classpath
io.grpc:grpc-core:1.45.1=classpath
io.grpc:grpc-netty:1.45.1=classpath
io.grpc:grpc-protobuf-lite:1.45.1=classpath
io.grpc:grpc-protobuf:1.45.1=classpath
io.grpc:grpc-stub:1.45.1=classpath
io.netty:netty-buffer:4.1.72.Final=classpath
io.netty:netty-codec-http2:4.1.72.Final=classpath
io.netty:netty-codec-http:4.1.72.Final=classpath
io.netty:netty-codec-socks:4.1.72.Final=classpath
io.netty:netty-codec:4.1.72.Final=classpath
io.netty:netty-common:4.1.72.Final=classpath
io.netty:netty-handler-proxy:4.1.72.Final=classpath
io.netty:netty-handler:4.1.72.Final=classpath
io.netty:netty-resolver:4.1.72.Final=classpath
io.netty:netty-tcnative-classes:2.0.46.Final=classpath
io.netty:netty-transport:4.1.72.Final=classpath
io.perfmark:perfmark-api:0.23.0=classpath
io.grpc:grpc-api:1.57.0=classpath
io.grpc:grpc-context:1.57.0=classpath
io.grpc:grpc-core:1.57.0=classpath
io.grpc:grpc-netty:1.57.0=classpath
io.grpc:grpc-protobuf-lite:1.57.0=classpath
io.grpc:grpc-protobuf:1.57.0=classpath
io.grpc:grpc-stub:1.57.0=classpath
io.netty:netty-buffer:4.1.93.Final=classpath
io.netty:netty-codec-http2:4.1.93.Final=classpath
io.netty:netty-codec-http:4.1.93.Final=classpath
io.netty:netty-codec-socks:4.1.93.Final=classpath
io.netty:netty-codec:4.1.93.Final=classpath
io.netty:netty-common:4.1.93.Final=classpath
io.netty:netty-handler-proxy:4.1.93.Final=classpath
io.netty:netty-handler:4.1.93.Final=classpath
io.netty:netty-resolver:4.1.93.Final=classpath
io.netty:netty-transport-native-unix-common:4.1.93.Final=classpath
io.netty:netty-transport:4.1.93.Final=classpath
io.perfmark:perfmark-api:0.26.0=classpath
jakarta.activation:jakarta.activation-api:1.2.1=classpath
jakarta.xml.bind:jakarta.xml.bind-api:2.3.2=classpath
javax.annotation:javax.annotation-api:1.3.2=classpath
@ -103,52 +103,51 @@ org.apache.commons:commons-compress:1.21=classpath
org.apache.httpcomponents:httpclient:4.5.14=classpath
org.apache.httpcomponents:httpcore:4.4.16=classpath
org.apache.httpcomponents:httpmime:4.5.6=classpath
org.bitbucket.b_c:jose4j:0.7.0=classpath
org.bouncycastle:bcpkix-jdk15on:1.67=classpath
org.bouncycastle:bcprov-jdk15on:1.67=classpath
org.checkerframework:checker-qual:3.12.0=classpath
org.codehaus.mojo:animal-sniffer-annotations:1.19=classpath
org.bitbucket.b_c:jose4j:0.9.5=classpath
org.bouncycastle:bcpkix-jdk18on:1.77=classpath
org.bouncycastle:bcprov-jdk18on:1.77=classpath
org.bouncycastle:bcutil-jdk18on:1.77=classpath
org.checkerframework:checker-qual:3.33.0=classpath
org.codehaus.mojo:animal-sniffer-annotations:1.23=classpath
org.glassfish.jaxb:jaxb-runtime:2.3.2=classpath
org.glassfish.jaxb:txw2:2.3.2=classpath
org.jdom:jdom2:2.0.6=classpath
org.jetbrains.intellij.deps:trove4j:1.0.20200330=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.22=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.22=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.22=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.22=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.22=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.22=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.22=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.22=classpath
org.jetbrains.kotlin:kotlin-reflect:1.9.0=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.22=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.22=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.22=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.22=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.22=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.22=classpath
org.jetbrains.kotlin:kotlin-android-extensions:1.9.24=classpath
org.jetbrains.kotlin:kotlin-build-tools-api:1.9.24=classpath
org.jetbrains.kotlin:kotlin-compiler-embeddable:1.9.24=classpath
org.jetbrains.kotlin:kotlin-compiler-runner:1.9.24=classpath
org.jetbrains.kotlin:kotlin-daemon-client:1.9.24=classpath
org.jetbrains.kotlin:kotlin-daemon-embeddable:1.9.24=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-annotations:1.9.24=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-api:1.9.24=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea-proto:1.9.24=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-idea:1.9.24=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin-model:1.9.24=classpath
org.jetbrains.kotlin:kotlin-gradle-plugin:1.9.24=classpath
org.jetbrains.kotlin:kotlin-gradle-plugins-bom:1.9.24=classpath
org.jetbrains.kotlin:kotlin-klib-commonizer-api:1.9.24=classpath
org.jetbrains.kotlin:kotlin-native-utils:1.9.24=classpath
org.jetbrains.kotlin:kotlin-project-model:1.9.24=classpath
org.jetbrains.kotlin:kotlin-reflect:1.9.20=classpath
org.jetbrains.kotlin:kotlin-scripting-common:1.9.24=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-embeddable:1.9.24=classpath
org.jetbrains.kotlin:kotlin-scripting-compiler-impl-embeddable:1.9.24=classpath
org.jetbrains.kotlin:kotlin-scripting-jvm:1.9.24=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.20=classpath
org.jetbrains.kotlin:kotlin-stdlib:1.9.24=classpath
org.jetbrains.kotlin:kotlin-tooling-core:1.9.24=classpath
org.jetbrains.kotlin:kotlin-util-io:1.9.24=classpath
org.jetbrains.kotlin:kotlin-util-klib:1.9.24=classpath
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.5.0=classpath
org.jetbrains:annotations:13.0=classpath
org.jetbrains:annotations:23.0.0=classpath
org.jvnet.staxex:stax-ex:1.8.1=classpath
org.ow2.asm:asm-analysis:9.2=classpath
org.ow2.asm:asm-commons:9.2=classpath
org.ow2.asm:asm-tree:9.2=classpath
org.ow2.asm:asm-util:9.2=classpath
org.ow2.asm:asm:9.2=classpath
org.ow2.asm:asm-analysis:9.6=classpath
org.ow2.asm:asm-commons:9.6=classpath
org.ow2.asm:asm-tree:9.6=classpath
org.ow2.asm:asm-util:9.6=classpath
org.ow2.asm:asm:9.6=classpath
org.slf4j:slf4j-api:1.7.30=classpath
org.tensorflow:tensorflow-lite-metadata:0.1.0-rc2=classpath
xerces:xercesImpl:2.12.0=classpath
xml-apis:xml-apis:1.4.01=classpath
empty=

View file

@ -105,7 +105,7 @@ const entryRest = async (serverUrl: string, teamId?: string, channelId?: string,
let lastDisconnectedAt = since || await getLastFullSync(database);
const [confResp, prefData] = await Promise.all([
fetchConfigAndLicense(serverUrl, true, groupLabel),
fetchConfigAndLicense(serverUrl, false, groupLabel),
fetchMyPreferences(serverUrl, true, groupLabel),
]);

View file

@ -1,6 +1,6 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {render, fireEvent} from '@testing-library/react-native';
import {render, fireEvent, act} from '@testing-library/react-native';
import React, {useMemo, type ComponentProps} from 'react';
import {DeviceEventEmitter, Text, TouchableOpacity, View} from 'react-native';
@ -408,10 +408,16 @@ describe('Files', () => {
expect(getByTestId('1-inViewPort')).toHaveTextContent('false');
expect(getByTestId('2-inViewPort')).toHaveTextContent('false');
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'unrelated-event': true});
act(() => {
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'unrelated-event': true});
});
expect(getByTestId('1-inViewPort')).toHaveTextContent('false');
expect(getByTestId('2-inViewPort')).toHaveTextContent('false');
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'test-location-test-post-id': true});
act(() => {
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'test-location-test-post-id': true});
});
expect(getByTestId('1-inViewPort')).toHaveTextContent('true');
expect(getByTestId('2-inViewPort')).toHaveTextContent('true');
});
@ -444,7 +450,9 @@ describe('Files', () => {
expect(getByTestId('1-inViewPort')).toHaveTextContent('false');
expect(getByTestId('2-inViewPort')).toHaveTextContent('false');
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'location1-post1': true});
act(() => {
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'location1-post1': true});
});
expect(getByTestId('1-inViewPort')).toHaveTextContent('false');
expect(getByTestId('2-inViewPort')).toHaveTextContent('false');
@ -453,11 +461,15 @@ describe('Files', () => {
expect(getByTestId('1-inViewPort')).toHaveTextContent('false');
expect(getByTestId('2-inViewPort')).toHaveTextContent('false');
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'location2-post1': true});
act(() => {
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'location2-post1': true});
});
expect(getByTestId('1-inViewPort')).toHaveTextContent('false');
expect(getByTestId('2-inViewPort')).toHaveTextContent('false');
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'location2-post2': true});
act(() => {
DeviceEventEmitter.emit(Events.ITEM_IN_VIEWPORT, {'location2-post2': true});
});
expect(getByTestId('1-inViewPort')).toHaveTextContent('true');
expect(getByTestId('2-inViewPort')).toHaveTextContent('true');
});

View file

@ -3,14 +3,14 @@
import React, {type ReactElement} from 'react';
type MarkdownList = {
type MarkdownListProps = {
children: ReactElement[];
ordered: boolean;
start: number;
tight: boolean;
};
const MarkdownList = ({start = 1, tight, ordered, children}: MarkdownList) => {
const MarkdownList = ({start = 1, tight, ordered, children}: MarkdownListProps) => {
let bulletWidth = 15;
if (ordered) {
const lastNumber = (start + children.length) - 1;

View file

@ -21,13 +21,13 @@ const TouchableOptionTypes = {
SELECT: 'select',
};
const OptionType = {
const OptionTypeConst = {
NONE: 'none',
TOGGLE: 'toggle',
...TouchableOptionTypes,
} as const;
export type OptionType = typeof OptionType[keyof typeof OptionType];
export type OptionType = typeof OptionTypeConst[keyof typeof OptionTypeConst];
export const ITEM_HEIGHT = 48;
const DESCRIPTION_MARGIN_TOP = 2;
@ -182,7 +182,7 @@ const OptionItem = ({
let actionComponent;
let radioComponent;
if (type === OptionType.SELECT && selected) {
if (type === OptionTypeConst.SELECT && selected) {
actionComponent = (
<CompassIcon
color={theme.linkColor}
@ -191,7 +191,7 @@ const OptionItem = ({
testID={`${testID}.selected`}
/>
);
} else if (type === OptionType.RADIO) {
} else if (type === OptionTypeConst.RADIO) {
const radioComponentTestId = selected ? `${testID}.selected` : `${testID}.not_selected`;
radioComponent = (
<RadioItem
@ -200,7 +200,7 @@ const OptionItem = ({
testID={radioComponentTestId}
/>
);
} else if (type === OptionType.TOGGLE) {
} else if (type === OptionTypeConst.TOGGLE) {
const trackColor = Platform.select({
ios: {true: theme.buttonBg, false: changeOpacity(theme.centerChannelColor, 0.16)},
default: {true: changeOpacity(theme.buttonBg, 0.32), false: changeOpacity(theme.centerChannelColor, 0.24)},
@ -217,7 +217,7 @@ const OptionItem = ({
testID={`${testID}.toggled.${selected}.button`}
/>
);
} else if (type === OptionType.ARROW) {
} else if (type === OptionTypeConst.ARROW) {
actionComponent = (
<CompassIcon
color={changeOpacity(theme.centerChannelColor, 0.32)}
@ -226,7 +226,7 @@ const OptionItem = ({
style={arrowStyle}
/>
);
} else if (type === OptionType.REMOVE) {
} else if (type === OptionTypeConst.REMOVE) {
actionComponent = (
<TouchableWithFeedback
hitSlop={hitSlop}
@ -265,7 +265,7 @@ const OptionItem = ({
/>
</View>
)}
{type === OptionType.RADIO && radioComponent}
{type === OptionTypeConst.RADIO && radioComponent}
<View style={labelStyle}>
<Text
style={[labelTextStyle, optionLabelTextStyle]}

View file

@ -48,7 +48,7 @@ export default function FileQuickAction({
onUploadFiles);
picker.attachFileFromFiles(undefined, true);
}, [onUploadFiles]);
}, [intl, maxFileCount, maxFilesReached, onUploadFiles]);
const actionTestID = disabled ? `${testID}.disabled` : testID;
const color = disabled ? changeOpacity(theme.centerChannelColor, 0.16) : changeOpacity(theme.centerChannelColor, 0.64);

View file

@ -40,7 +40,6 @@ const style = StyleSheet.create({
borderRadius: 4,
},
progress: {
alignItems: 'center',
backgroundColor: 'rgba(0, 0, 0, 0.1)',
height: 53,
width: 53,
@ -49,6 +48,11 @@ const style = StyleSheet.create({
borderRadius: 4,
paddingLeft: 3,
},
progressContainer: {
paddingVertical: undefined,
position: undefined,
justifyContent: undefined,
},
filePreview: {
width: 56,
height: 56,
@ -122,7 +126,7 @@ export default function UploadItem({
file={file}
/>
);
}, [file]);
}, [file, ref, theme.centerChannelColor]);
return (
<View
@ -145,6 +149,7 @@ export default function UploadItem({
<ProgressBar
progress={progress || 0}
color={theme.buttonBg}
containerStyle={style.progressContainer}
/>
</View>
}

View file

@ -6,7 +6,7 @@ import React, {type ComponentProps} from 'react';
import NetworkManager from '@managers/network_manager';
import PerformanceMetricsManager from '@managers/performance_metrics_manager';
import {getPostById} from '@queries/servers/post';
import {renderWithEverything} from '@test/intl-test-helper';
import {renderWithEverything, waitFor} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import Post from './post';
@ -52,24 +52,30 @@ describe('performance metrics', () => {
NetworkManager.invalidateClient(serverUrl);
});
it('do not call the performance metrics if it is not the last post', () => {
it('do not call the performance metrics if it is not the last post', async () => {
const props = getBaseProps();
props.isLastPost = false;
renderWithEverything(<Post {...props}/>, {database, serverUrl});
expect(PerformanceMetricsManager.finishLoad).not.toHaveBeenCalled();
expect(PerformanceMetricsManager.endMetric).not.toHaveBeenCalled();
await waitFor(() => {
expect(PerformanceMetricsManager.finishLoad).not.toHaveBeenCalled();
expect(PerformanceMetricsManager.endMetric).not.toHaveBeenCalled();
});
});
it('on channel', () => {
it('on channel', async () => {
const props = getBaseProps();
renderWithEverything(<Post {...props}/>, {database, serverUrl});
expect(PerformanceMetricsManager.finishLoad).toHaveBeenCalledWith('CHANNEL', serverUrl);
expect(PerformanceMetricsManager.endMetric).toHaveBeenCalledWith('mobile_channel_switch', serverUrl);
await waitFor(() => {
expect(PerformanceMetricsManager.finishLoad).toHaveBeenCalledWith('CHANNEL', serverUrl);
expect(PerformanceMetricsManager.endMetric).toHaveBeenCalledWith('mobile_channel_switch', serverUrl);
});
});
it('on thread', () => {
it('on thread', async () => {
const props = getBaseProps();
props.location = 'Thread';
renderWithEverything(<Post {...props}/>, {database, serverUrl});
expect(PerformanceMetricsManager.finishLoad).toHaveBeenCalledWith('THREAD', serverUrl);
expect(PerformanceMetricsManager.endMetric).toHaveBeenCalledWith('mobile_channel_switch', serverUrl);
await waitFor(() => {
expect(PerformanceMetricsManager.finishLoad).toHaveBeenCalledWith('THREAD', serverUrl);
expect(PerformanceMetricsManager.endMetric).toHaveBeenCalledWith('mobile_channel_switch', serverUrl);
});
});
});

View file

@ -2,7 +2,7 @@
// See LICENSE.txt for license information.
import {act} from '@testing-library/react-native';
import React from 'react';
import React, {type ComponentProps} from 'react';
import {DeviceEventEmitter, Platform} from 'react-native';
import * as localPostFunctions from '@actions/local/post';
@ -11,7 +11,7 @@ import {Events, Screens} from '@constants';
import {renderWithEverything} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import PostList, {exportedForTesting} from './post_list';
import PostList from './post_list';
jest.mock('@components/post_list/post', () => 'Post');
jest.mock('@components/post_list/thread_overview', () => 'ThreadOverview');
@ -31,8 +31,6 @@ jest.mock('@actions/local/post', () => ({
import type {PostModel} from '@database/models/server';
import type Database from '@nozbe/watermelondb/Database';
const {PostListProps} = exportedForTesting;
describe('components/post_list/PostList', () => {
let database: Database;
const serverUrl = 'https://server.com';
@ -68,7 +66,7 @@ describe('components/post_list/PostList', () => {
mockPostModel(),
];
const baseProps: typeof PostListProps = {
const baseProps: ComponentProps<typeof PostList> = {
appsEnabled: false,
channelId: 'channel-id',
currentTimezone: 'UTC',

View file

@ -402,8 +402,4 @@ const PostList = ({
);
};
export const exportedForTesting = {
PostListProps: {} as Props,
};
export default PostList;

View file

@ -56,11 +56,9 @@ exports[`ThreadOverview should match snapshot when post is saved and has replies
handlerTag={1}
handlerType="NativeViewGestureHandler"
innerRef={null}
onGestureEvent={[Function]}
onGestureHandlerEvent={[Function]}
onGestureHandlerStateChange={[Function]}
onHandlerStateChange={[Function]}
rippleColor={0}
rippleColor="transparent"
style={
[
undefined,
@ -97,11 +95,9 @@ exports[`ThreadOverview should match snapshot when post is saved and has replies
handlerTag={2}
handlerType="NativeViewGestureHandler"
innerRef={null}
onGestureEvent={[Function]}
onGestureHandlerEvent={[Function]}
onGestureHandlerStateChange={[Function]}
onHandlerStateChange={[Function]}
rippleColor={0}
rippleColor="transparent"
style={
[
undefined,

View file

@ -11,6 +11,7 @@ import {changeOpacity} from '@utils/theme';
type ProgressBarProps = {
color: string;
containerStyle?: StyleProp<ViewStyle>;
progress: number;
withCursor?: boolean;
style?: StyleProp<ViewStyle>;
@ -43,7 +44,7 @@ const styles = StyleSheet.create({
const START_CURSOR_VALUE = 0;
const END_CURSOR_VALUE = 1;
const ProgressBar = ({color, progress, withCursor, style, onSeek}: ProgressBarProps) => {
const ProgressBar = ({color, containerStyle, progress, withCursor, style, onSeek}: ProgressBarProps) => {
const theme = useTheme();
const widthValue = useSharedValue(0);
const progressValue = useSharedValue(progress);
@ -120,7 +121,7 @@ const ProgressBar = ({color, progress, withCursor, style, onSeek}: ProgressBarPr
<GestureDetector gesture={composedGestures}>
<View
onTouchStart={(e) => e.stopPropagation()}
style={styles.container}
style={[styles.container, containerStyle]}
>
<View
onLayout={onLayout}

View file

@ -3,12 +3,12 @@
import React from 'react';
import {renderWithIntlAndTheme} from '@test/intl-test-helper';
import {renderWithIntlAndTheme, waitFor} from '@test/intl-test-helper';
import Icon from './index';
describe('Server Icon', () => {
test('Server Icon Component should match snapshot', () => {
test('Server Icon Component should match snapshot', async () => {
const {toJSON} = renderWithIntlAndTheme(
<Icon
hasUnreads={false}
@ -16,10 +16,12 @@ describe('Server Icon', () => {
/>,
);
expect(toJSON()).toMatchSnapshot();
await waitFor(() => {
expect(toJSON()).toMatchSnapshot();
});
});
test('Server Icon Component should match snapshot with unreads', () => {
test('Server Icon Component should match snapshot with unreads', async () => {
const {toJSON} = renderWithIntlAndTheme(
<Icon
hasUnreads={true}
@ -28,10 +30,12 @@ describe('Server Icon', () => {
/>,
);
expect(toJSON()).toMatchSnapshot();
await waitFor(() => {
expect(toJSON()).toMatchSnapshot();
});
});
test('Server Icon Component should match snapshot with mentions', () => {
test('Server Icon Component should match snapshot with mentions', async () => {
const {toJSON} = renderWithIntlAndTheme(
<Icon
hasUnreads={false}
@ -40,6 +44,8 @@ describe('Server Icon', () => {
/>,
);
expect(toJSON()).toMatchSnapshot();
await waitFor(() => {
expect(toJSON()).toMatchSnapshot();
});
});
});

View file

@ -3,23 +3,23 @@
import React, {createContext} from 'react';
type Props = {
server: ServerContext;
children: React.ReactNode;
}
type WithServerUrlProps = {
serverUrl: string;
}
type GetProps<C> = C extends React.ComponentType<infer P & WithServerUrlProps> ? P : never
type ServerContext = {
type ServerContextType = {
displayName: string;
url: string;
}
const ServerContext = createContext<ServerContext>({displayName: '', url: ''});
type Props = {
server: ServerContextType;
children: React.ReactNode;
}
const ServerContext = createContext<ServerContextType>({displayName: '', url: ''});
const {Provider, Consumer} = ServerContext;
function ServerUrlProvider({server, children}: Props) {
@ -32,7 +32,7 @@ export function withServerUrl<C extends React.ComponentType<P>, P = GetProps<C>>
return function ServerUrlComponent(props: JSX.LibraryManagedAttributes<C, P>) {
return (
<Consumer>
{(server: ServerContext) => (
{(server: ServerContextType) => (
<Component
{...props}
serverUrl={server.url}

View file

@ -44,7 +44,7 @@ export const useHeaderHeight = () => {
defaultHeight,
largeHeight,
headerOffset,
}), [defaultHeight, largeHeight]);
}), [defaultHeight, headerOffset, largeHeight]);
};
export const useCollapsibleHeader = <T>(isLargeTitle: boolean, onSnap?: (offset: number) => void) => {

View file

@ -32,7 +32,9 @@ describe('useCollapsibleHeader', () => {
expect(result.current).toEqual({
defaultHeight: ViewConstants.DEFAULT_HEADER_HEIGHT,
scrollPaddingTop: LARGE_HEADER_TITLE_HEIGHT,
headerHeight: {value: LARGE_HEADER_TITLE_HEIGHT},
headerHeight: expect.objectContaining({
value: LARGE_HEADER_TITLE_HEIGHT,
}),
...commonHookResponse,
});
});
@ -43,7 +45,9 @@ describe('useCollapsibleHeader', () => {
expect(result.current).toEqual({
defaultHeight: ViewConstants.DEFAULT_HEADER_HEIGHT,
scrollPaddingTop: ViewConstants.DEFAULT_HEADER_HEIGHT,
headerHeight: {value: ViewConstants.DEFAULT_HEADER_HEIGHT},
headerHeight: expect.objectContaining({
value: ViewConstants.DEFAULT_HEADER_HEIGHT,
}),
...commonHookResponse,
});
});
@ -56,7 +60,9 @@ describe('useCollapsibleHeader', () => {
expect(result.current).toEqual({
defaultHeight: ViewConstants.TABLET_HEADER_HEIGHT,
scrollPaddingTop: LARGE_HEADER_TITLE_HEIGHT,
headerHeight: {value: LARGE_HEADER_TITLE_HEIGHT},
headerHeight: expect.objectContaining({
value: LARGE_HEADER_TITLE_HEIGHT,
}),
...commonHookResponse,
});
});

View file

@ -5,7 +5,7 @@
// eslint-disable-next-line
// @ts-nocheck
import {encode} from '@msgpack/msgpack/dist';
import {encode} from '@msgpack/msgpack';
import DatabaseManager from '@database/manager';

View file

@ -3,7 +3,7 @@
import {EventEmitter} from 'events';
import {encode} from '@msgpack/msgpack/dist';
import {encode} from '@msgpack/msgpack';
import Calls from '@constants/calls';
import DatabaseManager from '@database/manager';

View file

@ -726,7 +726,7 @@ describe('useCallsState', () => {
assert.deepEqual(result.current[1], null);
});
it('setChannelEnabled', () => {
it('setChannelEnabled', async () => {
const initialState = {
...DefaultCallsState,
enabled: {'channel-1': true, 'channel-2': false},
@ -734,33 +734,33 @@ describe('useCallsState', () => {
// setup
const {result} = renderHook(() => useCallsState('server1'));
act(() => setCallsState('server1', initialState));
await act(async () => setCallsState('server1', initialState));
assert.deepEqual(result.current, initialState);
// test setCalls affects enabled:
act(() => setCalls('server1', 'myUserId', {}, {'channel-1': true}));
await act(async () => setCalls('server1', 'myUserId', {}, {'channel-1': true}));
assert.deepEqual(result.current.enabled, {'channel-1': true});
// re-setup:
act(() => setCallsState('server1', initialState));
await act(async () => setCallsState('server1', initialState));
assert.deepEqual(result.current, initialState);
// test setChannelEnabled affects enabled:
act(() => setChannelEnabled('server1', 'channel-3', true));
await act(async () => setChannelEnabled('server1', 'channel-3', true));
assert.deepEqual(result.current.enabled, {'channel-1': true, 'channel-2': false, 'channel-3': true});
act(() => setChannelEnabled('server1', 'channel-3', false));
await act(async () => setChannelEnabled('server1', 'channel-3', false));
assert.deepEqual(result.current.enabled, {
'channel-1': true,
'channel-2': false,
'channel-3': false,
});
act(() => setChannelEnabled('server1', 'channel-1', true));
await act(async () => setChannelEnabled('server1', 'channel-1', true));
assert.deepEqual(result.current.enabled, {
'channel-1': true,
'channel-2': false,
'channel-3': false,
});
act(() => setChannelEnabled('server1', 'channel-1', false));
await act(async () => setChannelEnabled('server1', 'channel-1', false));
assert.deepEqual(result.current.enabled, {
'channel-1': false,
'channel-2': false,
@ -1510,14 +1510,14 @@ describe('useCallsState', () => {
// test: should not ring for same call again
await act(async () => {
await setIncomingCalls(initialIncomingCalls);
setIncomingCalls(initialIncomingCalls);
await playIncomingCallsRinging('server1', 'call1', 'online');
});
assert.deepEqual(result.current, initialIncomingCalls);
// test: should not ring when already ringing
await act(async () => {
await setIncomingCalls({
setIncomingCalls({
...initialIncomingCalls,
currentRingingCallId: 'call2',
});
@ -1534,33 +1534,38 @@ describe('useCallsState', () => {
// setup
const {result} = renderHook(() => useIncomingCalls());
await act(async () => {
await setIncomingCalls(initialIncomingCalls);
act(() => {
setIncomingCalls(initialIncomingCalls);
});
assert.deepEqual(result.current, initialIncomingCalls);
// test going to background
await act(async () => callsOnAppStateChange('background'));
await act(async () => {
await callsOnAppStateChange('background');
});
assert.deepEqual(result.current, {...initialIncomingCalls, currentRingingCallId: undefined});
// test going to inactive
await act(async () => {
await setIncomingCalls(initialIncomingCalls);
setIncomingCalls(initialIncomingCalls);
await callsOnAppStateChange('inactive');
await TestHelper.wait(100);
});
assert.deepEqual(result.current, {...initialIncomingCalls, currentRingingCallId: undefined});
// test going to active (should not change state)
await act(async () => {
await setIncomingCalls(initialIncomingCalls);
setIncomingCalls(initialIncomingCalls);
await callsOnAppStateChange('active');
await TestHelper.wait(100);
});
assert.deepEqual(result.current, initialIncomingCalls);
// test previous state
await act(async () => {
await setIncomingCalls(initialIncomingCalls);
setIncomingCalls(initialIncomingCalls);
await callsOnAppStateChange('active');
await TestHelper.wait(100);
});
assert.deepEqual(result.current, initialIncomingCalls);
});

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {act} from '@testing-library/react-native';
import {act, waitFor} from '@testing-library/react-native';
import React from 'react';
import {SYSTEM_IDENTIFIERS} from '@constants/database';
@ -30,7 +30,7 @@ describe('components/categories_list', () => {
});
});
it('should render', () => {
it('should render', async () => {
const wrapper = renderWithEverything(
<CategoriesList
moreThanOneTeam={false}
@ -39,10 +39,12 @@ describe('components/categories_list', () => {
/>,
{database},
);
expect(wrapper.toJSON()).toBeTruthy();
await waitFor(() => {
expect(wrapper.toJSON()).toBeTruthy();
});
});
it('should render channel list with thread menu', () => {
it('should render channel list with thread menu', async () => {
jest.useFakeTimers();
const wrapper = renderWithEverything(
<CategoriesList
@ -56,11 +58,13 @@ describe('components/categories_list', () => {
act(() => {
jest.runAllTimers();
});
expect(wrapper.toJSON()).toBeTruthy();
jest.useRealTimers();
await waitFor(() => {
expect(wrapper.toJSON()).toBeTruthy();
});
});
it('should render channel list with Draft menu', () => {
it('should render channel list with Draft menu', async () => {
const wrapper = renderWithEverything(
<CategoriesList
isCRTEnabled={true}
@ -70,7 +74,9 @@ describe('components/categories_list', () => {
/>,
{database},
);
expect(wrapper.getByText('Drafts')).toBeTruthy();
await waitFor(() => {
expect(wrapper.getByText('Drafts')).toBeTruthy();
});
});
it('should render team error', async () => {
@ -92,16 +98,19 @@ describe('components/categories_list', () => {
act(() => {
jest.runAllTimers();
});
expect(wrapper.toJSON()).toMatchSnapshot();
jest.useRealTimers();
await waitFor(() => {
expect(wrapper.toJSON()).toMatchSnapshot();
});
});
it('should render channels error', async () => {
await operator.handleSystem({
systems: [{id: SYSTEM_IDENTIFIERS.CURRENT_TEAM_ID, value: TestHelper.basicTeam!.id}],
prepareRecordsOnly: false,
});
});
it('should render channels error', () => {
jest.useFakeTimers();
const wrapper = renderWithEverything(
<CategoriesList
@ -114,6 +123,9 @@ describe('components/categories_list', () => {
act(() => {
jest.runAllTimers();
});
expect(wrapper.toJSON()).toMatchSnapshot();
jest.useRealTimers();
await waitFor(() => {
expect(wrapper.toJSON()).toMatchSnapshot();
});
});
});

View file

@ -4,7 +4,7 @@
import React, {type ComponentProps} from 'react';
import PerformanceMetricsManager from '@managers/performance_metrics_manager';
import {renderWithEverything} from '@test/intl-test-helper';
import {renderWithEverything, waitFor} from '@test/intl-test-helper';
import TestHelper from '@test/test_helper';
import ChannelListScreen from './channel_list';
@ -47,11 +47,11 @@ describe('performance metrics', () => {
database = server.database;
});
it('finish load on load', () => {
jest.useFakeTimers();
it('finish load on load', async () => {
const props = getBaseProps();
renderWithEverything(<ChannelListScreen {...props}/>, {database, serverUrl});
expect(PerformanceMetricsManager.finishLoad).toHaveBeenCalledWith('HOME', serverUrl);
jest.useRealTimers();
await waitFor(() => {
expect(PerformanceMetricsManager.finishLoad).toHaveBeenCalledWith('HOME', serverUrl);
});
});
});

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {fireEvent, waitFor} from '@testing-library/react-native';
import {act, fireEvent, waitFor} from '@testing-library/react-native';
import React from 'react';
import {addSearchToTeamSearchHistory} from '@actions/local/team';
@ -91,7 +91,9 @@ describe('SearchScreen', () => {
);
const searchInput = getByTestId('navigation.header.search_bar.search.input');
fireEvent.changeText(searchInput, 'test search');
act(() => {
fireEvent.changeText(searchInput, 'test search');
});
expect(searchInput.props.value).toBe('test search');
});
@ -102,8 +104,13 @@ describe('SearchScreen', () => {
);
const searchInput = getByTestId('navigation.header.search_bar.search.input');
fireEvent.changeText(searchInput, 'test search');
fireEvent(searchInput, 'submitEditing');
await act(async () => {
fireEvent.changeText(searchInput, 'test search');
});
await act(async () => {
fireEvent(searchInput, 'submitEditing');
});
await waitFor(() => {
expect(searchPosts).toHaveBeenCalledWith(
@ -126,7 +133,9 @@ describe('SearchScreen', () => {
);
const teamPicker = getByTestId('team_picker.button');
fireEvent.press(teamPicker);
act(() => {
fireEvent.press(teamPicker);
});
expect(teamPicker).toBeTruthy();
expect(bottomSheet).toHaveBeenCalled();
@ -139,10 +148,14 @@ describe('SearchScreen', () => {
);
const searchInput = getByTestId('navigation.header.search_bar.search.input');
fireEvent.changeText(searchInput, 'test search');
act(() => {
fireEvent.changeText(searchInput, 'test search');
});
const clearButton = getByTestId('navigation.header.search_bar.search.clear.button');
fireEvent.press(clearButton);
act(() => {
fireEvent.press(clearButton);
});
expect(searchInput.props.value).toBe('');
});
@ -154,8 +167,12 @@ describe('SearchScreen', () => {
);
const searchInput = getByTestId('navigation.header.search_bar.search.input');
fireEvent.changeText(searchInput, 'test search');
fireEvent(searchInput, 'submitEditing');
await act(async () => {
fireEvent.changeText(searchInput, 'test search');
});
await act(async () => {
fireEvent(searchInput, 'submitEditing');
});
await waitFor(() => {
expect(addSearchToTeamSearchHistory).toHaveBeenCalledWith(

View file

@ -157,7 +157,7 @@ export function hasTrailingSpaces(term: string) {
export function isMainActivity() {
if (Platform.OS === 'android') {
const MattermostShare = require('@mattermost/rnshare').default;
return MattermostShare?.getCurrentActivityName() === 'MainActivity';
return MattermostShare?.getCurrentActivityName().includes('MainActivity');
}
return true;

View file

@ -1,6 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import Config from '@assets/config.json';
import keyMirror from '@utils/key_mirror';
import {logError, logWarning, logInfo, logDebug} from './log';
@ -25,12 +26,17 @@ describe('Logging functions', () => {
const Sentry = require('@sentry/react-native');
const SentryLevels = keyMirror({debug: null, info: null, warning: null, error: null});
beforeAll(() => {
Config.SentryEnabled = true;
});
afterEach(() => {
jest.clearAllMocks();
});
afterAll(() => {
global.console = originalConsole;
Config.SentryEnabled = false;
});
test('logError logs error and adds breadcrumb', () => {

View file

@ -1,6 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import Config from '@assets/config.json';
import keyMirror from '@utils/key_mirror';
const SentryLevels = keyMirror({debug: null, info: null, warning: null, error: null});
@ -30,10 +31,12 @@ export function logDebug(...args: any[]) {
}
const addBreadcrumb = (logLevel: keyof typeof SentryLevels, ...args: any[]) => {
const Sentry = require('@sentry/react-native');
Sentry.addBreadcrumb({
level: logLevel,
message: args.join(','),
type: 'console-log',
});
if (Config.SentryEnabled) {
const Sentry = require('@sentry/react-native');
Sentry.addBreadcrumb({
level: logLevel,
message: args.join(','),
type: 'console-log',
});
}
};

143
eslint.config.mjs Normal file
View file

@ -0,0 +1,143 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {defineConfig, globalIgnores} from 'eslint/config';
import tseslint from "@typescript-eslint/eslint-plugin";
import * as tsparser from "@typescript-eslint/parser";
import importPlugin from "eslint-plugin-import";
import reactHooks from "eslint-plugin-react-hooks";
import stylisticTs from "@stylistic/eslint-plugin-ts";
// Load custom rulesets
import eslintMattermost, {jestConfig} from "./eslint/eslint-mattermost.mjs";
import eslintReact from "./eslint/eslint-react.mjs";
export default defineConfig([
globalIgnores([
"node_modules/",
"dist/",
"build/",
"coverage/",
"android/",
"ios/",
".github/",
"detox/artifacts/",
]),
eslintMattermost,
jestConfig,
eslintReact,
{
files: ["**/*.{js,jsx,ts,tsx}"],
languageOptions: {
parser: tsparser,
parserOptions: {
ecmaVersion: "latest",
ecmaFeatures: {
jsx: true
}
},
globals: {
__DEV__: true
},
sourceType: "module"
},
plugins: {
"@stylistic/ts": stylisticTs,
"@typescript-eslint": tseslint,
"import": importPlugin,
"react-hooks": reactHooks
},
settings: {
react: {
pragma: "React",
version: "detect"
}
},
rules: {
"eol-last": ["error", "always"],
"global-require": "off",
"no-undefined": "off",
"no-shadow": "off",
"react/display-name": [2, { "ignoreTranspilerName": false }],
"react/jsx-filename-extension": "off",
"react-hooks/exhaustive-deps": "warn",
"camelcase": ["off", { "properties": "never" }],
"@typescript-eslint/ban-types": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-unused-vars": [
2,
{
vars: "all",
args: "after-used",
caughtErrors: "none",
ignoreRestSiblings: true,
}
],
"@typescript-eslint/no-shadow": ["error"],
"@typescript-eslint/no-explicit-any": "warn",
"no-use-before-define": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/no-var-requires": "off",
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"no-underscore-dangle": "off",
"indent": [2, 4, { "SwitchCase": 1 }],
"key-spacing": [
2,
{
"singleLine": {
"beforeColon": false,
"afterColon": true
}
}
],
"@stylistic/ts/member-delimiter-style": 2,
"@typescript-eslint/no-unsafe-declaration-merging": "off",
"import/order": [
2,
{
"groups": ["builtin", "external", "parent", "sibling", "index", "type"],
"newlines-between": "always",
"pathGroups": [
{
"pattern": "{@(@actions|@app|@assets|@calls|@client|@components|@constants|@context|@database|@helpers|@hooks|@init|@managers|@queries|@screens|@selectors|@share|@store|@telemetry|@typings|@test|@utils)/**,@(@constants|@i18n|@store|@websocket)}",
"group": "external",
"position": "after"
},
{
"pattern": "app/**",
"group": "parent",
"position": "before"
}
],
"alphabetize": {
"order": "asc",
"caseInsensitive": true
},
"pathGroupsExcludedImportTypes": ["type"]
}
]
}
},
{
files: ["detox/e2e/**"],
languageOptions: {
globals: {
by: true,
detox: true,
device: true,
element: true,
waitFor: true
}
},
rules: {
"func-names": "off",
"import/no-unresolved": "off",
"max-nested-callbacks": "off",
"no-process-env": "off",
"no-unused-expressions": "off"
}
}
]);

View file

@ -1,505 +0,0 @@
{
"extends": [
"eslint:recommended"
],
"parserOptions": {
"ecmaVersion": 8,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true,
"impliedStrict": true,
"modules": true
}
},
"parser": "babel-eslint",
"plugins": [
"header"
],
"env": {
"browser": true,
"node": true,
"jquery": true,
"es6": true
},
"rules": {
"array-bracket-spacing": [
2,
"never"
],
"array-callback-return": 2,
"arrow-body-style": 0,
"arrow-parens": [
2,
"always"
],
"arrow-spacing": [
2,
{
"before": true,
"after": true
}
],
"block-scoped-var": 2,
"brace-style": [
2,
"1tbs",
{
"allowSingleLine": false
}
],
"camelcase": [
2,
{
"properties": "never"
}
],
"capitalized-comments": 0,
"class-methods-use-this": 0,
"comma-dangle": [
2,
"always-multiline"
],
"comma-spacing": [
2,
{
"before": false,
"after": true
}
],
"comma-style": [
2,
"last"
],
"complexity": [
0,
10
],
"computed-property-spacing": [
2,
"never"
],
"consistent-return": 2,
"consistent-this": [
2,
"self"
],
"constructor-super": 2,
"curly": [
2,
"all"
],
"dot-location": [
2,
"object"
],
"dot-notation": 2,
"eqeqeq": [
2,
"smart"
],
"func-call-spacing": [
2,
"never"
],
"func-name-matching": 0,
"func-names": 2,
"func-style": [
2,
"declaration",
{
"allowArrowFunctions": true
}
],
"generator-star-spacing": [
2,
{
"before": false,
"after": true
}
],
"global-require": 2,
"guard-for-in": 2,
"header/header": [
2,
"line",
" Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n See LICENSE.txt for license information."
],
"id-blacklist": 0,
"indent": [
2,
4,
{
"SwitchCase": 0
}
],
"jsx-quotes": [
2,
"prefer-single"
],
"key-spacing": [
2,
{
"beforeColon": false,
"afterColon": true,
"mode": "strict"
}
],
"keyword-spacing": [
2,
{
"before": true,
"after": true,
"overrides": {}
}
],
"line-comment-position": 0,
"linebreak-style": 2,
"lines-around-comment": [
2,
{
"beforeBlockComment": true,
"beforeLineComment": true,
"allowBlockStart": true,
"allowBlockEnd": true
}
],
"max-lines": [
1,
{
"max": 550,
"skipBlankLines": true,
"skipComments": true
}
],
"max-nested-callbacks": [
2,
{
"max": 2
}
],
"max-statements-per-line": [
2,
{
"max": 1
}
],
"multiline-ternary": [
1,
"never"
],
"new-cap": 2,
"new-parens": 2,
"newline-before-return": 0,
"newline-per-chained-call": 0,
"no-alert": 2,
"no-array-constructor": 2,
"no-await-in-loop": 2,
"no-caller": 2,
"no-case-declarations": 2,
"no-class-assign": 2,
"no-compare-neg-zero": 2,
"no-cond-assign": [
2,
"except-parens"
],
"no-confusing-arrow": 2,
"no-console": 2,
"no-const-assign": 2,
"no-constant-condition": 2,
"no-debugger": 2,
"no-div-regex": 2,
"no-dupe-args": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-duplicate-imports": [
2,
{
"includeExports": true
}
],
"no-else-return": 2,
"no-empty": 2,
"no-empty-function": 2,
"no-empty-pattern": 2,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-label": 2,
"no-extra-parens": 0,
"no-extra-semi": 2,
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-global-assign": 2,
"no-implicit-coercion": 2,
"no-implicit-globals": 0,
"no-implied-eval": 2,
"no-inner-declarations": 0,
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-lonely-if": 2,
"no-loop-func": 2,
"no-magic-numbers": 0,
"no-mixed-operators": [
2,
{
"allowSamePrecedence": false
}
],
"no-mixed-spaces-and-tabs": 2,
"no-multi-assign": 2,
"no-multi-spaces": [
2,
{
"exceptions": {
"Property": false
}
}
],
"no-multi-str": 0,
"no-multiple-empty-lines": [
2,
{
"max": 1
}
],
"no-native-reassign": 2,
"no-negated-condition": 2,
"no-nested-ternary": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-symbol": 2,
"no-new-wrappers": 2,
"no-octal-escape": 2,
"no-param-reassign": 2,
"no-process-env": 2,
"no-process-exit": 2,
"no-proto": 2,
"no-prototype-builtins": 1,
"no-redeclare": 2,
"no-return-assign": [
2,
"always"
],
"no-return-await": 2,
"no-script-url": 2,
"no-self-assign": [
2,
{
"props": true
}
],
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow": [
2,
{
"hoist": "functions"
}
],
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-tabs": 0,
"no-template-curly-in-string": 2,
"no-ternary": 0,
"no-this-before-super": 2,
"no-throw-literal": 2,
"no-trailing-spaces": [
2,
{
"skipBlankLines": false
}
],
"no-undef-init": 2,
"no-undefined": 2,
"no-underscore-dangle": 2,
"no-unexpected-multiline": 2,
"no-unmodified-loop-condition": 2,
"no-unneeded-ternary": [
2,
{
"defaultAssignment": false
}
],
"no-unreachable": 2,
"no-unsafe-finally": 2,
"no-unsafe-negation": 2,
"no-unused-expressions": 2,
"no-unused-vars": [
2,
{
"vars": "all",
"args": "after-used"
}
],
"no-use-before-define": [
2,
{
"classes": false,
"functions": false,
"variables": false
}
],
"no-useless-computed-key": 2,
"no-useless-concat": 2,
"no-useless-constructor": 2,
"no-useless-escape": 2,
"no-useless-rename": 2,
"no-useless-return": 2,
"no-var": 0,
"no-void": 2,
"no-warning-comments": 1,
"no-whitespace-before-property": 2,
"no-with": 2,
"object-curly-newline": 0,
"object-curly-spacing": [
2,
"never"
],
"object-property-newline": [
2,
{
"allowMultiplePropertiesPerLine": true
}
],
"object-shorthand": [
2,
"always"
],
"one-var": [
2,
"never"
],
"one-var-declaration-per-line": 0,
"operator-assignment": [
2,
"always"
],
"operator-linebreak": [
2,
"after"
],
"padded-blocks": [
2,
"never"
],
"prefer-arrow-callback": 2,
"prefer-const": 2,
"prefer-destructuring": 0,
"prefer-numeric-literals": 2,
"prefer-promise-reject-errors": 2,
"prefer-rest-params": 2,
"prefer-spread": 2,
"prefer-template": 0,
"quote-props": [
2,
"as-needed"
],
"quotes": [
2,
"single",
"avoid-escape"
],
"radix": 2,
"require-yield": 2,
"rest-spread-spacing": [
2,
"never"
],
"semi": [
2,
"always"
],
"semi-spacing": [
2,
{
"before": false,
"after": true
}
],
"sort-imports": 0,
"sort-keys": 0,
"space-before-blocks": [
2,
"always"
],
"space-before-function-paren": [
2,
{
"anonymous": "never",
"named": "never",
"asyncArrow": "always"
}
],
"space-in-parens": [
2,
"never"
],
"space-infix-ops": 2,
"space-unary-ops": [
2,
{
"words": true,
"nonwords": false
}
],
"symbol-description": 2,
"template-curly-spacing": [
2,
"never"
],
"valid-typeof": [
2,
{
"requireStringLiterals": false
}
],
"vars-on-top": 0,
"wrap-iife": [
2,
"outside"
],
"wrap-regex": 2,
"yoda": [
2,
"never",
{
"exceptRange": false,
"onlyEquality": false
}
],
"@typescript-eslint/array-type": [2, {"default": "array-simple"}],
"@typescript-eslint/member-delimiter-style": 2,
"@typescript-eslint/type-annotation-spacing": 2
},
"overrides": [
{
"files": ["*.test.js", "*.test.jsx", "*.test.ts", "*.test.tsx", "tests/**"],
"globals": {
"after": true,
"afterAll": true,
"afterEach": true,
"before": true,
"beforeAll": true,
"beforeEach": true,
"describe": true,
"expect": true,
"it": true,
"jest": true,
"test": true
},
"rules": {
"no-empty-function": 0,
"no-console": 0,
"max-nested-callbacks": 0,
"no-undefined": 0
}
}
]
}

View file

@ -0,0 +1,224 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import {defineConfig} from 'eslint/config';
import headerPlugin from "eslint-plugin-header";
import tseslint from "@typescript-eslint/eslint-plugin";
import stylisticTs from "@stylistic/eslint-plugin-ts";
headerPlugin.rules.header.meta.schema = false;
export default defineConfig([
{
files: ["**/*.{js,jsx,ts,tsx}"],
languageOptions: {
ecmaVersion: 8,
sourceType: "module",
globals: {
browser: true,
node: true,
jquery: true,
es6: true
},
},
plugins: {
header: headerPlugin,
"@typescript-eslint": tseslint,
"@stylistic/ts": stylisticTs,
},
rules: {
"array-bracket-spacing": [2, "never"],
"array-callback-return": 2,
"arrow-body-style": 0,
"arrow-parens": [2, "always"],
"arrow-spacing": [2, { before: true, after: true }],
"block-scoped-var": 2,
"brace-style": [2, "1tbs", { allowSingleLine: false }],
"camelcase": [2, { properties: "never" }],
"capitalized-comments": 0,
"class-methods-use-this": 0,
"comma-dangle": [2, "always-multiline"],
"comma-spacing": [2, { before: false, after: true }],
"comma-style": [2, "last"],
"complexity": [0, 10],
"computed-property-spacing": [2, "never"],
"consistent-return": 2,
"consistent-this": [2, "self"],
"constructor-super": 2,
"curly": [2, "all"],
"dot-location": [2, "object"],
"dot-notation": 2,
"eqeqeq": [2, "smart"],
"func-call-spacing": [2, "never"],
"func-name-matching": 0,
"func-names": 2,
"func-style": [2, "declaration", { allowArrowFunctions: true }],
"generator-star-spacing": [2, { before: false, after: true }],
"global-require": 2,
"guard-for-in": 2,
"header/header": [
2,
"line",
" Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.\n See LICENSE.txt for license information."
],
"id-blacklist": 0,
"indent": [2, 4, { SwitchCase: 0 }],
"jsx-quotes": [2, "prefer-single"],
"key-spacing": [2, { beforeColon: false, afterColon: true, mode: "strict" }],
"keyword-spacing": [2, { before: true, after: true, overrides: {} }],
"line-comment-position": 0,
"linebreak-style": 2,
"lines-around-comment": [2, { beforeBlockComment: true, beforeLineComment: true, allowBlockStart: true, allowBlockEnd: true }],
"max-lines": [1, { max: 550, skipBlankLines: true, skipComments: true }],
"max-nested-callbacks": [2, { max: 2 }],
"max-statements-per-line": [2, { max: 1 }],
"multiline-ternary": [1, "never"],
"new-cap": 2,
"new-parens": 2,
"newline-before-return": 0,
"newline-per-chained-call": 0,
"no-alert": 2,
"no-array-constructor": 2,
"no-await-in-loop": 2,
"no-caller": 2,
"no-case-declarations": 2,
"no-class-assign": 2,
"no-compare-neg-zero": 2,
"no-cond-assign": [2, "except-parens"],
"no-confusing-arrow": 2,
"no-console": 2,
"no-const-assign": 2,
"no-constant-condition": 2,
"no-debugger": 2,
"no-div-regex": 2,
"no-dupe-args": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-duplicate-imports": [2, { includeExports: true }],
"no-else-return": 2,
"no-empty": 2,
"no-empty-function": 2,
"no-empty-pattern": 2,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-label": 2,
"no-extra-parens": 0,
"no-extra-semi": 2,
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-global-assign": 2,
"no-implicit-coercion": 2,
"no-implicit-globals": 0,
"no-implied-eval": 2,
"no-inner-declarations": 0,
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-labels": 2,
"no-lone-blocks": 2,
"no-lonely-if": 2,
"no-loop-func": 2,
"no-magic-numbers": 0,
"no-mixed-operators": [2, { allowSamePrecedence: false }],
"no-mixed-spaces-and-tabs": 2,
"no-multi-assign": 2,
"no-multi-spaces": [2, { exceptions: { Property: false } }],
"no-multiple-empty-lines": [2, { max: 1 }],
"no-native-reassign": 2,
"no-negated-condition": 2,
"no-nested-ternary": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-symbol": 2,
"no-new-wrappers": 2,
"no-octal-escape": 2,
"no-param-reassign": 2,
"no-process-env": 2,
"no-prototype-builtins": 1,
"no-redeclare": 0,
"no-return-assign": [2, "always"],
"no-return-await": 2,
"no-script-url": 2,
"no-self-assign": [2, { props: true }],
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow": [2, { hoist: "functions" }],
"no-shadow-restricted-names": 2,
"no-spaced-func": 2,
"no-tabs": 0,
"no-ternary": 0,
"no-this-before-super": 2,
"no-throw-literal": 2,
"no-trailing-spaces": [2, { skipBlankLines: false }],
"no-undef-init": 2,
"no-undefined": 2,
"no-underscore-dangle": 2,
"no-unexpected-multiline": 2,
"no-unmodified-loop-condition": 2,
"no-unneeded-ternary": [2, { defaultAssignment: false }],
"no-unreachable": 2,
"no-unused-expressions": 2,
"no-use-before-define": [2, { classes: false, functions: false, variables: false }],
"no-useless-computed-key": 2,
"no-useless-concat": 2,
"no-useless-constructor": 2,
"no-useless-return": 2,
"no-var": 0,
"no-void": 2,
"no-warning-comments": 1,
"no-whitespace-before-property": 2,
"no-with": 2,
"object-curly-spacing": [2, "never"],
"object-property-newline": [2, { allowMultiplePropertiesPerLine: true }],
"object-shorthand": [2, "always"],
"one-var": [2, "never"],
"prefer-arrow-callback": 2,
"prefer-const": 2,
"prefer-numeric-literals": 2,
"prefer-promise-reject-errors": 2,
"quotes": [2, "single", "avoid-escape"],
"semi": [2, "always"],
"semi-spacing": [2, { before: false, after: true }],
"space-before-blocks": [2, "always"],
"space-in-parens": [2, "never"],
"@typescript-eslint/array-type": [2, { default: "array-simple" }],
"@stylistic/ts/member-delimiter-style": 2,
"@stylistic/ts/type-annotation-spacing": 2,
"@typescript-eslint/no-redeclare": [
2,
{ ignoreDeclarationMerge: true }
]
},
},
// Jest Config
]);
export const jestConfig = defineConfig({
files: ["**/*.test.{js,jsx,ts,tsx}", "**/tests/**"],
languageOptions: {
globals: {
after: true,
afterAll: true,
afterEach: true,
before: true,
beforeAll: true,
beforeEach: true,
describe: true,
expect: true,
it: true,
jest: true,
test: true
}
},
rules: {
"no-empty-function": "off",
"no-console": "off",
"max-nested-callbacks": "off",
"no-undefined": 'off'
}
});

View file

@ -1,123 +0,0 @@
{
"extends": [
"plugin:react/recommended"
],
"plugins": [
"react"
],
"rules": {
"react/display-name": [
0,
{
"ignoreTranspilerName": false
}
],
"react/forbid-component-props": 0,
"react/forbid-elements": [
2,
{
"forbid": [
"embed"
]
}
],
"react/jsx-boolean-value": [
2,
"always"
],
"react/jsx-closing-bracket-location": [
2,
{
"location": "tag-aligned"
}
],
"react/jsx-curly-spacing": [
2,
"never"
],
"react/jsx-equals-spacing": [
2,
"never"
],
"react/jsx-filename-extension": 2,
"react/jsx-first-prop-new-line": [
2,
"multiline"
],
"react/jsx-handler-names": 0,
"react/jsx-indent": [
2,
4
],
"react/jsx-indent-props": [
2,
4
],
"react/jsx-key": 2,
"react/jsx-max-props-per-line": [
2,
{
"maximum": 1
}
],
"react/jsx-no-bind": 0,
"react/jsx-no-comment-textnodes": 2,
"react/jsx-no-duplicate-props": [
2,
{
"ignoreCase": false
}
],
"react/jsx-no-literals": 2,
"react/jsx-no-target-blank": 2,
"react/jsx-no-undef": 2,
"react/jsx-pascal-case": 2,
"react/jsx-tag-spacing": [
2,
{
"closingSlash": "never",
"beforeSelfClosing": "never",
"afterOpening": "never"
}
],
"react/jsx-uses-react": 2,
"react/jsx-uses-vars": 2,
"react/jsx-wrap-multilines": 2,
"react/no-array-index-key": 1,
"react/no-children-prop": 2,
"react/no-danger": 0,
"react/no-danger-with-children": 2,
"react/no-deprecated": 1,
"react/no-did-mount-set-state": 2,
"react/no-did-update-set-state": 2,
"react/no-direct-mutation-state": 2,
"react/no-find-dom-node": 1,
"react/no-is-mounted": 2,
"react/no-multi-comp": [
2,
{
"ignoreStateless": true
}
],
"react/no-render-return-value": 2,
"react/no-set-state": 0,
"react/no-string-refs": 0,
"react/no-unescaped-entities": 2,
"react/no-unknown-property": 2,
"react/no-unused-prop-types": [
1,
{
"skipShapeProps": true
}
],
"react/prefer-es6-class": 2,
"react/prefer-stateless-function": 0,
"react/prop-types": 2,
"react/require-default-props": 0,
"react/require-optimization": 1,
"react/require-render-return": 2,
"react/self-closing-comp": 2,
"react/sort-comp": 0,
"react/style-prop-object": 2
}
}

58
eslint/eslint-react.mjs Normal file
View file

@ -0,0 +1,58 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import reactPlugin from "eslint-plugin-react";
export default {
plugins: {
react: reactPlugin
},
settings: {
react: {
pragma: "React",
version: "detect"
}
},
rules: {
"react/display-name": [0, { ignoreTranspilerName: false }],
"react/forbid-elements": [2, { forbid: ["embed"] }],
"react/jsx-boolean-value": [2, "always"],
"react/jsx-closing-bracket-location": [2, { location: "tag-aligned" }],
"react/jsx-curly-spacing": [2, "never"],
"react/jsx-equals-spacing": [2, "never"],
"react/jsx-filename-extension": 2,
"react/jsx-first-prop-new-line": [2, "multiline"],
"react/jsx-indent": [2, 4],
"react/jsx-indent-props": [2, 4],
"react/jsx-key": 2,
"react/jsx-max-props-per-line": [2, { maximum: 1 }],
"react/jsx-no-comment-textnodes": 2,
"react/jsx-no-duplicate-props": [2, { ignoreCase: false }],
"react/jsx-no-literals": 2,
"react/jsx-no-target-blank": 2,
"react/jsx-no-undef": 2,
"react/jsx-pascal-case": 2,
"react/jsx-tag-spacing": [2, { closingSlash: "never", beforeSelfClosing: "never", afterOpening: "never" }],
"react/jsx-uses-react": 2,
"react/jsx-uses-vars": 2,
"react/jsx-wrap-multilines": 2,
"react/no-array-index-key": 1,
"react/no-children-prop": 2,
"react/no-danger": 0,
"react/no-deprecated": 1,
"react/no-did-mount-set-state": 2,
"react/no-did-update-set-state": 2,
"react/no-direct-mutation-state": 2,
"react/no-find-dom-node": 1,
"react/no-multi-comp": [2, { ignoreStateless: true }],
"react/no-render-return-value": 2,
"react/no-string-refs": 0,
"react/no-unescaped-entities": 2,
"react/no-unknown-property": 2,
"react/no-unused-prop-types": [1, { skipShapeProps: true }],
"react/prefer-es6-class": 2,
"react/require-default-props": 0,
"react/require-render-return": 2,
"react/self-closing-comp": 2
}
};

View file

@ -15,21 +15,22 @@ GEM
public_suffix (>= 2.0.2, < 7.0)
artifactory (3.0.17)
atomos (0.1.3)
aws-eventstream (1.3.0)
aws-partitions (1.1005.0)
aws-sdk-core (3.212.0)
aws-eventstream (1.3.2)
aws-partitions (1.1067.0)
aws-sdk-core (3.220.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sigv4 (~> 1.9)
base64
jmespath (~> 1, >= 1.6.1)
aws-sdk-kms (1.95.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-kms (1.99.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sigv4 (~> 1.5)
aws-sdk-s3 (1.170.1)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-s3 (1.182.0)
aws-sdk-core (~> 3, >= 3.216.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
aws-sigv4 (1.10.1)
aws-sigv4 (1.11.0)
aws-eventstream (~> 1, >= 1.0.2)
babosa (1.0.4)
base64 (0.2.0)
@ -39,7 +40,7 @@ GEM
commander (4.6.0)
highline (~> 2.0.0)
declarative (0.0.20)
digest-crc (0.6.5)
digest-crc (0.7.0)
rake (>= 12.0.0, < 14.0.0)
domain_name (0.6.20240107)
dotenv (2.8.1)
@ -64,8 +65,8 @@ GEM
faraday-em_synchrony (1.0.0)
faraday-excon (1.1.0)
faraday-httpclient (1.0.1)
faraday-multipart (1.0.4)
multipart-post (~> 2)
faraday-multipart (1.1.0)
multipart-post (~> 2.0)
faraday-net_http (1.0.2)
faraday-net_http_persistent (1.2.0)
faraday-patron (1.0.0)
@ -73,8 +74,8 @@ GEM
faraday-retry (1.0.3)
faraday_middleware (1.2.1)
faraday (~> 1.0)
fastimage (2.3.1)
fastlane (2.225.0)
fastimage (2.4.0)
fastlane (2.227.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.8, < 3.0.0)
artifactory (~> 3.0)
@ -114,7 +115,7 @@ GEM
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty (~> 0.4.0)
xcpretty-travis-formatter (>= 0.0.3, < 2.0.0)
fastlane-plugin-android_change_package_identifier (0.1.0)
fastlane-plugin-android_change_string_app_name (0.1.1)
@ -139,12 +140,12 @@ GEM
google-apis-core (>= 0.11.0, < 2.a)
google-apis-storage_v1 (0.31.0)
google-apis-core (>= 0.11.0, < 2.a)
google-cloud-core (1.7.1)
google-cloud-core (1.8.0)
google-cloud-env (>= 1.0, < 3.a)
google-cloud-errors (~> 1.0)
google-cloud-env (1.6.0)
faraday (>= 0.17.3, < 3.0)
google-cloud-errors (1.4.0)
google-cloud-errors (1.5.0)
google-cloud-storage (1.47.0)
addressable (~> 2.8)
digest-crc (~> 0.4)
@ -160,17 +161,19 @@ GEM
os (>= 0.9, < 2.0)
signet (>= 0.16, < 2.a)
highline (2.0.3)
http-cookie (1.0.7)
http-cookie (1.0.8)
domain_name (~> 0.5)
httpclient (2.8.3)
httpclient (2.9.0)
mutex_m
jmespath (1.6.2)
json (2.8.1)
jwt (2.9.3)
json (2.10.2)
jwt (2.10.1)
base64
mini_magick (4.13.2)
mini_mime (1.1.5)
multi_json (1.15.0)
multipart-post (2.4.1)
mutex_m (0.3.0)
nanaimo (0.4.0)
naturally (2.2.1)
nkf (0.2.0)
@ -182,7 +185,7 @@ GEM
racc (~> 1.4)
optparse (0.6.0)
os (1.1.4)
plist (3.7.1)
plist (3.7.2)
public_suffix (6.0.1)
racc (1.8.1)
rake (13.2.1)
@ -191,10 +194,10 @@ GEM
trailblazer-option (>= 0.1.1, < 0.2.0)
uber (< 0.2.0)
retriable (3.1.2)
rexml (3.3.9)
rouge (2.0.7)
rexml (3.4.1)
rouge (3.28.0)
ruby2_keywords (0.0.5)
rubyzip (2.3.2)
rubyzip (2.4.1)
security (0.1.5)
signet (0.19.0)
addressable (~> 2.8)
@ -223,8 +226,8 @@ GEM
colored2 (~> 3.1)
nanaimo (~> 0.4.0)
rexml (>= 3.3.6, < 4.0)
xcpretty (0.3.0)
rouge (~> 2.0.7)
xcpretty (0.4.0)
rouge (~> 3.28.0)
xcpretty-travis-formatter (1.0.1)
xcpretty (~> 0.2, >= 0.0.7)

View file

@ -5,25 +5,25 @@ PODS:
- CocoaLumberjack/Core (= 3.8.5)
- CocoaLumberjack/Core (3.8.5)
- DoubleConversion (1.1.6)
- EXApplication (6.0.1):
- EXApplication (6.0.2):
- ExpoModulesCore
- EXConstants (17.0.3):
- EXConstants (17.0.8):
- ExpoModulesCore
- Expo (52.0.19):
- Expo (52.0.40):
- ExpoModulesCore
- ExpoCrypto (14.0.1):
- ExpoCrypto (14.0.2):
- ExpoModulesCore
- ExpoDevice (7.0.1):
- ExpoDevice (7.0.2):
- ExpoModulesCore
- ExpoFileSystem (18.0.6):
- ExpoFileSystem (18.0.12):
- ExpoModulesCore
- ExpoImage (2.0.4):
- ExpoImage (2.0.6):
- ExpoModulesCore
- SDWebImage (~> 5.19.1)
- SDWebImageSVGCoder (~> 1.7.0)
- ExpoLinearGradient (14.0.1):
- ExpoLinearGradient (14.0.2):
- ExpoModulesCore
- ExpoModulesCore (2.1.2):
- ExpoModulesCore (2.2.3):
- DoubleConversion
- glog
- hermes-engine
@ -46,11 +46,11 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- ExpoStoreReview (8.0.0):
- ExpoStoreReview (8.0.1):
- ExpoModulesCore
- ExpoVideoThumbnails (9.0.2):
- ExpoVideoThumbnails (9.0.3):
- ExpoModulesCore
- ExpoWebBrowser (14.0.1):
- ExpoWebBrowser (14.0.2):
- ExpoModulesCore
- FBLazyVector (0.76.5)
- fmt (9.1.0)
@ -1366,7 +1366,7 @@ PODS:
- Yoga
- react-native-background-timer (2.4.1):
- React-Core
- react-native-cameraroll (7.9.0):
- react-native-cameraroll (7.10.0):
- DoubleConversion
- glog
- hermes-engine
@ -1431,7 +1431,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-image-picker (7.2.3):
- react-native-image-picker (8.2.0):
- DoubleConversion
- glog
- hermes-engine
@ -1503,9 +1503,9 @@ PODS:
- Yoga
- react-native-performance (5.1.2):
- React-Core
- react-native-safe-area-context (5.0.0):
- react-native-safe-area-context (5.3.0):
- React-Core
- react-native-video (6.8.2):
- react-native-video (6.11.0):
- DoubleConversion
- glog
- hermes-engine
@ -1518,7 +1518,7 @@ PODS:
- React-featureflags
- React-graphics
- React-ImageManager
- react-native-video/Video (= 6.8.2)
- react-native-video/Video (= 6.11.0)
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
@ -1527,7 +1527,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-video/Video (6.8.2):
- react-native-video/Video (6.11.0):
- DoubleConversion
- glog
- hermes-engine
@ -1548,7 +1548,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- react-native-webrtc (124.0.4):
- react-native-webrtc (124.0.5):
- JitsiWebRTC (~> 124.0.0)
- React-Core
- React-nativeconfig (0.76.5)
@ -1822,26 +1822,26 @@ PODS:
- React-Core
- ReactNativeIncallManager (4.2.0):
- React-Core
- ReactNativeNavigation (7.40.3):
- ReactNativeNavigation (7.44.0):
- HMSegmentedControl
- React-Core
- React-CoreModules
- React-RCTImage
- React-RCTText
- ReactNativeNavigation/Core (= 7.40.3)
- ReactNativeNavigation/Core (7.40.3):
- ReactNativeNavigation/Core (= 7.44.0)
- ReactNativeNavigation/Core (7.44.0):
- HMSegmentedControl
- React-Core
- React-CoreModules
- React-RCTImage
- React-RCTText
- RNCClipboard (1.15.0):
- RNCClipboard (1.16.2):
- React-Core
- RNDateTimePicker (8.2.0):
- RNDateTimePicker (8.3.0):
- React-Core
- RNFileViewer (2.1.5):
- React-Core
- RNFlashList (1.7.3):
- RNFlashList (1.7.6):
- DoubleConversion
- glog
- hermes-engine
@ -1862,7 +1862,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNGestureHandler (2.21.2):
- RNGestureHandler (2.24.0):
- DoubleConversion
- glog
- hermes-engine
@ -1883,7 +1883,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNKeychain (9.2.2):
- RNKeychain (10.0.0):
- DoubleConversion
- glog
- hermes-engine
@ -1904,9 +1904,9 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNLocalize (3.3.0):
- RNLocalize (3.4.1):
- React-Core
- RNPermissions (5.2.1):
- RNPermissions (5.3.0):
- React-Core
- RNReactNativeHapticFeedback (2.3.3):
- DoubleConversion
@ -1929,7 +1929,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNReanimated (3.16.5):
- RNReanimated (3.17.1):
- DoubleConversion
- glog
- hermes-engine
@ -1941,7 +1941,9 @@ PODS:
- React-Fabric
- React-featureflags
- React-graphics
- React-hermes
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
@ -1949,10 +1951,10 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/reanimated (= 3.16.5)
- RNReanimated/worklets (= 3.16.5)
- RNReanimated/reanimated (= 3.17.1)
- RNReanimated/worklets (= 3.17.1)
- Yoga
- RNReanimated/reanimated (3.16.5):
- RNReanimated/reanimated (3.17.1):
- DoubleConversion
- glog
- hermes-engine
@ -1964,7 +1966,9 @@ PODS:
- React-Fabric
- React-featureflags
- React-graphics
- React-hermes
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
@ -1972,9 +1976,9 @@ PODS:
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/reanimated/apple (= 3.16.5)
- RNReanimated/reanimated/apple (= 3.17.1)
- Yoga
- RNReanimated/reanimated/apple (3.16.5):
- RNReanimated/reanimated/apple (3.17.1):
- DoubleConversion
- glog
- hermes-engine
@ -1986,7 +1990,9 @@ PODS:
- React-Fabric
- React-featureflags
- React-graphics
- React-hermes
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
@ -1995,7 +2001,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNReanimated/worklets (3.16.5):
- RNReanimated/worklets (3.17.1):
- DoubleConversion
- glog
- hermes-engine
@ -2007,7 +2013,33 @@ PODS:
- React-Fabric
- React-featureflags
- React-graphics
- React-hermes
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
- React-utils
- ReactCodegen
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- RNReanimated/worklets/apple (= 3.17.1)
- Yoga
- RNReanimated/worklets/apple (3.17.1):
- DoubleConversion
- glog
- hermes-engine
- RCT-Folly (= 2024.01.01.00)
- RCTRequired
- RCTTypeSafety
- React-Core
- React-debug
- React-Fabric
- React-featureflags
- React-graphics
- React-hermes
- React-ImageManager
- React-jsi
- React-NativeModulesApple
- React-RCTFabric
- React-rendererdebug
@ -2016,7 +2048,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNScreens (4.3.0):
- RNScreens (4.9.2):
- DoubleConversion
- glog
- hermes-engine
@ -2061,7 +2093,7 @@ PODS:
- ReactCommon/turbomodule/core
- Sentry/HybridSDK (= 8.41.0)
- Yoga
- RNShare (12.0.3):
- RNShare (12.0.9):
- DoubleConversion
- glog
- hermes-engine
@ -2082,7 +2114,7 @@ PODS:
- ReactCommon/turbomodule/bridging
- ReactCommon/turbomodule/core
- Yoga
- RNSVG (15.10.1):
- RNSVG (15.11.2):
- React-Core
- RNVectorIcons (10.2.0):
- DoubleConversion
@ -2117,7 +2149,7 @@ PODS:
- SwiftyJSON (5.0.2)
- TurboLogIOSNative (0.1.0):
- CocoaLumberjack (~> 3.8.5)
- WatermelonDB (0.28.0-1):
- WatermelonDB (0.28.0-2):
- React
- simdjson
- Yoga (0.0.0)
@ -2495,18 +2527,18 @@ SPEC CHECKSUMS:
boost: 1dca942403ed9342f98334bf4c3621f011aa7946
CocoaLumberjack: 6a459bc897d6d80bd1b8c78482ec7ad05dffc3f0
DoubleConversion: f16ae600a246532c4020132d54af21d0ddb2a385
EXApplication: 88ebf1a95f85faa5d2df160016d61f2d060e9438
EXConstants: 277129d9a42ba2cf1fad375e7eaa9939005c60be
Expo: 848501c300b37b3fa7330c58a5353e07e03d5c3d
ExpoCrypto: 483fc758365923f89ddaab4327c21cae9534841d
ExpoDevice: 449822f2c45660c1ce83283dd51c67fe5404996c
ExpoFileSystem: a38e1bb58d77f41717293a7b73ebd4014d8cb8dd
ExpoImage: 18ec1a3e5cd96ee6162d988be3085e18113e143f
ExpoLinearGradient: 18148bd38f98fa0229c1f9df23393b32ab6d2d32
ExpoModulesCore: c9cb309323aee3c048099bb40ad0226e3fcf0c56
ExpoStoreReview: f38ed71ee04dfc02dde63a05f925f001cebba5d8
ExpoVideoThumbnails: 5572e98fac313bfdc86f7d7915354f13a364ed38
ExpoWebBrowser: b658ba8a9161f1b54afb279591cfce2cb73330fa
EXApplication: 4c72f6017a14a65e338c5e74fca418f35141e819
EXConstants: fcfc75800824ac2d5c592b5bc74130bad17b146b
Expo: 4f645fc381f88e6acacfb0dcb63b45fb9eff25b9
ExpoCrypto: e97e864c8d7b9ce4a000bca45dddb93544a1b2b4
ExpoDevice: 1662ecdf42a8b5b2cf60ef7cecaf5a297639dd63
ExpoFileSystem: 42d363d3b96f9afab980dcef60d5657a4443c655
ExpoImage: eefe750743772ec0ca1a8055f56c8653e7de21fc
ExpoLinearGradient: 35ebd83b16f80b3add053a2fd68cc328ed927f60
ExpoModulesCore: 15f60d00e33ca0cea27147543877ca6e70c42ef5
ExpoStoreReview: 92ad323dd14485e7aa67d5b47248fb22876ffaee
ExpoVideoThumbnails: 7e9cd967393af9af0f7b0c62a4a00549f1860cab
ExpoWebBrowser: a212e6b480d8857d3e441fba51e0c968333803b3
FBLazyVector: 1bf99bb46c6af9a2712592e707347315f23947aa
fmt: 10c6e61f4be25dc963c36bd73fc7b1705fe975be
glog: 08b301085f15bcbb6ff8632a8ebaf239aae04e6a
@ -2547,19 +2579,19 @@ SPEC CHECKSUMS:
React-Mapbuffer: 7eb5d69e1154e7743487ef0c8d7261e5b59afb32
React-microtasksnativemodule: 16e31e4f503a5f46adafd035096130418c3bce70
react-native-background-timer: 4638ae3bee00320753647900b21260b10587b6f7
react-native-cameraroll: 5f180ef5e9b52b6c3c3a2645fa33a921d1e37a6c
react-native-cameraroll: 12a9c1cd6d10d32d438f45cc1a55348728062055
react-native-cookies: d648ab7025833b977c0b19e142503034f5f29411
react-native-document-picker: 530879d9e89b490f0954bcc4ab697c5b5e35d659
react-native-emm: afc895b726861262e1b7fecaccb1339492c0bbdc
react-native-image-picker: 130fad649d07e4eec8faaed361d3bba570e1e5ff
react-native-image-picker: 86f8954a0b8c0f85d56fa1d85ae87936ae74e615
react-native-netinfo: cec9c4e86083cb5b6aba0e0711f563e2fbbff187
react-native-network-client: fdbd7f5f4c2818d6b90b4dcf9613d0a54ab41303
react-native-notifications: 3bafa1237ae8a47569a84801f17d80242fe9f6a5
react-native-paste-input: d33daa183942fa57f34dff2088805a60895f14d2
react-native-performance: 125a96c145e29918b55b45ce25cbba54f1e24dcd
react-native-safe-area-context: 314537f8fca6fe2c06bd53fc8905efa9e6aaaf59
react-native-video: cab619600c0d1283080c80298a2abe3a6a9157f3
react-native-webrtc: 2261a482150195092246fe70b3aff976f2e11ec5
react-native-safe-area-context: fdb0a66feac038cb6eb1edafcf2ccee2b5cf0284
react-native-video: 11ad1501910486a22bd4f9acd623660df4a9c1a9
react-native-webrtc: 62659d18a13f6b50ad95c99a9a48cf9872a15815
React-nativeconfig: f7ab6c152e780b99a8c17448f2d99cf5f69a2311
React-NativeModulesApple: 9aeb901b9bfcc9235e912445fb3cf4780a99baf4
React-perflogger: 16e049953d21b37e9871ddf0b02f414e12ff14ba
@ -2589,21 +2621,21 @@ SPEC CHECKSUMS:
ReactCommon: 5809a8ee421b7219221a475b78180f8f34b5c5ec
ReactNativeExceptionHandler: a23922ca00122b050ae9412f960061791c232c47
ReactNativeIncallManager: ef7b845e166f04cf8ddf433d8a23227b01cef87a
ReactNativeNavigation: 7579af7ae4f79c58691c19a06630bd50172c8817
RNCClipboard: dbcf25b8f666b4685c02eeb65be981d30198e505
RNDateTimePicker: 818460dc31b0dc5ec58289003e27dd8d022fb79c
ReactNativeNavigation: 1be1769ba07b05f5f7065294d6001e84e6c3a2a0
RNCClipboard: e1d17c9d093d8129ef50b39b63a17a0e8ccd0ade
RNDateTimePicker: 29264364ea7b8cc0fb355b3843cf276a4ff78966
RNFileViewer: 4b5d83358214347e4ab2d4ca8d5c1c90d869e251
RNFlashList: 3f19b05498275481fa67506db51057eee62fa54a
RNGestureHandler: 5b24d10761754ad271b714e536c457fd89b17c54
RNKeychain: bd09fc5dcf4e0c4166a5d4012beaf2e093fcd9f5
RNLocalize: d024afa9204c13885e61dc88b8190651bcaabac9
RNPermissions: 318634eacdb21addd8c709467035b2304d2963d3
RNFlashList: fad82b8b2d3ee447fcc4723d747f43b38710c4fc
RNGestureHandler: fc491c834d09b0538618a3f328ab75fe8f90f5b4
RNKeychain: 57c0b42f79950ba6bdca5277ab52a6b24dccd595
RNLocalize: 15463c4d79c7da45230064b4adcf5e9bb984667e
RNPermissions: 84ae3e68efdd6d4a5142c8969df11869bfb06fa8
RNReactNativeHapticFeedback: 00ba111b82aa266bb3ee1aa576831c2ea9a9dfad
RNReanimated: 5d4ff4e212df81d3890e581446d8ab714a8dc2ba
RNScreens: e21c8d32fe97737ecc30f1f21e7b6f69f341a1f5
RNReanimated: 17a1990801a6a324816dcc52a9a44dfb99d556b3
RNScreens: 0e8829648c78f4168f3e96cdc2e219213cb1907c
RNSentry: c5075bc124ebc8afa84e037c7fe257053a0b2cda
RNShare: d40e9e8d071f845fff5072173ffb7a3bf3918c6d
RNSVG: 3421710ac15f4f2dc47e5c122f2c2e4282116830
RNShare: 381ed02f6c0dc42b8c24bb5a1e5df0ee5fd91354
RNSVG: a07e14363aa208062c6483bad24a438d5986d490
RNVectorIcons: 182892e7d1a2f27b52d3c627eca5d2665a22ee28
SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3
SDWebImageSVGCoder: 15a300a97ec1c8ac958f009c02220ac0402e936c
@ -2613,7 +2645,7 @@ SPEC CHECKSUMS:
Starscream: 19b5533ddb925208db698f0ac508a100b884a1b9
SwiftyJSON: f5b1bf1cd8dd53cd25887ac0eabcfd92301c6a5a
TurboLogIOSNative: 45f6d20ba17ee39f8106e718e93baf43b2d76b7b
WatermelonDB: 438a8dd16910dfe622095c44b5d1dbe11cbba6ba
WatermelonDB: e9fe3df0dfccbb9d196d3e244b52b8761a267434
Yoga: fcc198acd4a55599b3468cfb6ebc526baff5f06e
PODFILE CHECKSUM: 0e437947a8e6696940c2efdfd7205ab54d67b7b8

View file

@ -6,7 +6,7 @@ buildscript {
google()
gradlePluginPortal()
}
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : "1.9.22"
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : "1.9.24"
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")

View file

@ -20,10 +20,10 @@ class MattermostHardwareKeyboardPackage : TurboReactPackage() {
MattermostHardwareKeyboardImpl.NAME to ReactModuleInfo(
MattermostHardwareKeyboardImpl.NAME,
MattermostHardwareKeyboardImpl.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
false, // isCxxModule
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED // isTurboModule
_canOverrideExistingModule = false,
_needsEagerInit = false,
isCxxModule = false,
isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
)
)
}

View file

@ -6,7 +6,7 @@ buildscript {
google()
gradlePluginPortal()
}
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : "1.9.22"
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : "1.9.24"
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
@ -55,5 +55,5 @@ repositories {
dependencies {
implementation 'com.facebook.react:react-native'
implementation 'androidx.work:work-runtime:2.8.1'
implementation 'androidx.work:work-runtime:2.10.0'
}

View file

@ -22,10 +22,10 @@ class MattermostSharePackage : TurboReactPackage() {
moduleInfos[MattermostShareImpl.NAME] = ReactModuleInfo(
MattermostShareImpl.NAME,
MattermostShareImpl.NAME,
false, // canOverrideExistingModule
false, // needsEagerInit
false, // isCxxModule
isTurboModule // isTurboModule
_canOverrideExistingModule = false,
_needsEagerInit = false,
isCxxModule = false,
isTurboModule = isTurboModule
)
moduleInfos
}

View file

@ -7,6 +7,7 @@ import android.graphics.BitmapFactory
import android.media.MediaMetadataRetriever
import android.net.Uri
import android.webkit.URLUtil
import androidx.core.net.toUri
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.ReadableMap
import com.facebook.react.bridge.WritableMap
@ -95,7 +96,7 @@ object ShareUtils {
retriever.setDataSource(decodedPath.replace("file://", ""))
} else if (filePath.contains("content://")) {
retriever.setDataSource(context, Uri.parse(filePath))
retriever.setDataSource(context, filePath.toUri())
}
val image = retriever.getFrameAtTime((time * 1000).toLong(), MediaMetadataRetriever.OPTION_CLOSEST_SYNC)

View file

@ -1,7 +1,8 @@
package com.mattermost.rnshare
import android.content.pm.ServiceInfo
import android.content.Context
import android.content.pm.ServiceInfo
import android.os.Build
import android.util.Base64
import android.util.Log
import androidx.core.app.NotificationCompat
@ -199,7 +200,11 @@ class ShareWorker(private val context: Context, workerParameters: WorkerParamete
.setSmallIcon(applicationContext.resources.getIdentifier("ic_notification", "mipmap", applicationContext.packageName))
.setOngoing(true)
.build()
return ForegroundInfo(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
ForegroundInfo(1, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
} else {
ForegroundInfo(1, notification)
}
}
}

View file

@ -6,7 +6,7 @@ buildscript {
google()
gradlePluginPortal()
}
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : "1.9.22"
def kotlin_version = rootProject.ext.has('kotlinVersion') ? rootProject.ext.get('kotlinVersion') : "1.9.24"
dependencies {
classpath("com.android.tools.build:gradle:7.3.1")
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version")
@ -55,9 +55,9 @@ repositories {
dependencies {
implementation 'com.facebook.react:react-native'
implementation 'androidx.window:window:1.2.0'
implementation 'androidx.window:window-core:1.2.0'
implementation 'androidx.window:window-rxjava3:1.2.0'
implementation 'androidx.window:window:1.3.0'
implementation 'androidx.window:window-core:1.3.0'
implementation 'androidx.window:window-rxjava3:1.3.0'
implementation 'io.reactivex.rxjava3:rxjava:3.1.6'
implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'

View file

@ -1,10 +1,9 @@
package com.mattermost.rnutils
import android.app.Activity
import android.net.Uri
import android.os.Build
import android.view.WindowManager
import androidx.core.view.OnApplyWindowInsetsListener
import androidx.core.net.toUri
import com.facebook.react.bridge.Arguments
import com.facebook.react.bridge.Promise
import com.facebook.react.bridge.ReactApplicationContext
@ -16,7 +15,6 @@ import com.mattermost.rnutils.helpers.SaveDataTask
import com.mattermost.rnutils.helpers.SplitView
class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) {
private var customInsetsListener: OnApplyWindowInsetsListener? = null
companion object {
const val NAME = "RNUtils"
@ -56,7 +54,7 @@ class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) {
var result = ""
if (currentActivity != null) {
val uri = Uri.parse(filePath)
val uri = filePath?.toUri()
val path: String? = RealPathUtil.getRealPathFromURI(reactContext, uri)
if (path != null) {
result = "file://$path"
@ -93,7 +91,7 @@ class RNUtilsModuleImpl(private val reactContext: ReactApplicationContext) {
fun lockPortrait() {}
fun deleteDatabaseDirectory(databaseName: String?, shouldRemoveDirectory: Boolean): WritableMap {
fun deleteDatabaseDirectory(): WritableMap {
val map = Arguments.createMap()
map.putNull("error")
map.putBoolean("success", true)

View file

@ -20,10 +20,10 @@ class RNUtilsPackage : TurboReactPackage() {
RNUtilsModuleImpl.NAME to ReactModuleInfo(
RNUtilsModuleImpl.NAME,
RNUtilsModuleImpl.NAME,
false,
false,
false,
BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
_canOverrideExistingModule = false,
_needsEagerInit = false,
isCxxModule = false,
isTurboModule = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED
)
)
}

View file

@ -55,7 +55,7 @@ class FoldableObserver(activity: Activity) {
disposable = observable.observeOn(AndroidSchedulers.mainThread())
.subscribe { layoutInfo ->
setIsDeviceFolded(layoutInfo)
handleWindowLayoutInfo(layoutInfo)
handleWindowLayoutInfo()
SplitView.setDeviceFolded()
}
}
@ -82,7 +82,7 @@ class FoldableObserver(activity: Activity) {
}
}
private fun handleWindowLayoutInfo(windowLayoutInfo: WindowLayoutInfo) {
private fun handleWindowLayoutInfo() {
val bounds = getWindowSize()
if (bounds?.width() != windowBounds?.width()) {
@ -111,7 +111,7 @@ class FoldableObserver(activity: Activity) {
}
fun getWindowDimensions(): Rect? {
return this.windowBounds;
return this.windowBounds
}
fun isCompactView(): Boolean {

View file

@ -8,6 +8,7 @@ import android.text.TextUtils
import androidx.core.app.NotificationManagerCompat
import org.json.JSONException
import org.json.JSONObject
import androidx.core.content.edit
object NotificationHelper {
private const val PUSH_NOTIFICATIONS: String = "PUSH_NOTIFICATIONS"
@ -33,10 +34,8 @@ object NotificationHelper {
}
if (version != storedVersion) {
if (pSharedPref != null) {
val editor = pSharedPref.edit()
editor.putString(PREF_VERSION, version)
editor.apply()
pSharedPref?.edit {
putString(PREF_VERSION, version)
}
val inputMap: Map<String?, JSONObject?> = HashMap()
@ -98,7 +97,7 @@ object NotificationHelper {
// Add the summary notification id as well
notificationsInGroup.put((notificationId + 1).toString(), true)
}
notificationsInServer.put(groupId, notificationsInGroup)
groupId?.let { notificationsInServer.put(it, notificationsInGroup) }
notificationsPerServer[serverUrl] = notificationsInServer
saveMap(context, notificationsPerServer)
@ -148,7 +147,7 @@ object NotificationHelper {
notificationsInServer.remove(groupId)
} else {
try {
notificationsInServer.put(groupId, notificationsInGroup)
groupId?.let { notificationsInServer.put(it, notificationsInGroup) }
} catch (e: JSONException) {
e.printStackTrace()
}
@ -295,10 +294,10 @@ object NotificationHelper {
try {
if (pSharedPref != null) {
val jsonString = pSharedPref.getString(NOTIFICATIONS_IN_GROUP, JSONObject().toString())
val json = JSONObject(jsonString)
val servers = json.keys()
val json = jsonString?.let { JSONObject(it) }
val servers = json?.keys()
while (servers.hasNext()) {
while (servers?.hasNext() == true) {
val serverUrl = servers.next()
val notificationGroup = json.getJSONObject(serverUrl)
outputMap[serverUrl] = notificationGroup

View file

@ -67,7 +67,7 @@ object RealPathUtil {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI
}
}
val selectionArgs = arrayOf<String>(split[1])
val selectionArgs = arrayOf(split[1])
return contentUri?.let { getDataColumn(context, it, selectionArgs) }
}
}
@ -94,7 +94,8 @@ object RealPathUtil {
val returnCursor = context.contentResolver.query(uri, null, null, null, null)
val nameIndex = returnCursor?.getColumnIndex(OpenableColumns.DISPLAY_NAME)
returnCursor?.moveToFirst()
fileName = sanitizeFilename(nameIndex?.let { returnCursor?.getString(it) })
fileName = sanitizeFilename(nameIndex?.let { returnCursor.getString(it) })
returnCursor?.close()
} catch (e:Exception) {
// just continue to get the filename with the last segment of the path
}
@ -126,18 +127,18 @@ object RealPathUtil {
private fun sanitizeFilename(filename: String?): String? {
if (filename == null) {
return null;
return null
}
val f = File(filename);
return f.name;
val f = File(filename)
return f.name
}
private fun getDataColumn(context:Context, uri:Uri, selectionArgs:Array<String>): String? {
var cursor: Cursor? = null
val column = "_data"
val selection = "_id=?"
val projection = arrayOf<String>(column)
val projection = arrayOf(column)
try
{
cursor = context.contentResolver.query(uri, projection, selection, selectionArgs, null)
@ -185,7 +186,7 @@ object RealPathUtil {
}
}
fun getMimeType(file: File): String? {
private fun getMimeType(file: File): String? {
val extension = getExtension(file.name)
if (extension?.length!! > 0) {
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1))

View file

@ -5,6 +5,7 @@ import android.content.Intent
import android.net.Uri
import android.webkit.MimeTypeMap
import androidx.core.content.FileProvider
import androidx.core.net.toUri
import com.facebook.react.bridge.ActivityEventListener
import com.facebook.react.bridge.BaseActivityEventListener
import com.facebook.react.bridge.Promise
@ -25,12 +26,14 @@ open class SaveDataTask(val reactContext: ReactApplicationContext) {
private val weakContext = WeakReference(reactContext.applicationContext)
private val myExecutor = Executors.newSingleThreadExecutor()
private lateinit var mActivityEventListener: ActivityEventListener
companion object {
const val SAVE_REQUEST: Int = 38641
}
init {
var mActivityEventListener: ActivityEventListener = object : BaseActivityEventListener() {
mActivityEventListener = object : BaseActivityEventListener() {
override fun onActivityResult(activity: Activity, requestCode: Int, resultCode: Int, intent: Intent?) {
if (requestCode == SAVE_REQUEST) {
if (resultCode == Activity.RESULT_CANCELED) {
@ -50,11 +53,13 @@ open class SaveDataTask(val reactContext: ReactApplicationContext) {
}
mPickerPromise = null
reactContext.removeActivityEventListener(mActivityEventListener)
}
}
}
}
reactContext.addActivityEventListener(mActivityEventListener)
}
private fun save(fromFile: String, toFile: Uri) {
myExecutor.execute {
@ -84,7 +89,7 @@ open class SaveDataTask(val reactContext: ReactApplicationContext) {
var filename = ""
if (filePath?.startsWith("content://") == true) {
contentUri = Uri.parse(filePath)
contentUri = filePath.toUri()
} else {
val newFile = filePath?.let { File(it) }
filename = newFile?.name ?: ""

View file

@ -41,7 +41,7 @@ class SplitView {
private fun getSplitViewResults(folded: Boolean): WritableMap? {
if (context?.currentActivity != null) {
val map = Arguments.createMap()
var isSplitView = folded;
var isSplitView = folded
if (context?.currentActivity?.isInMultiWindowMode == true) {
isSplitView = FoldableObserver.getInstance()?.isCompactView() == true
}

View file

@ -41,7 +41,7 @@ class RNUtilsModule(val reactContext: ReactApplicationContext) : NativeRNUtilsSp
}
override fun deleteDatabaseDirectory(databaseName: String?, shouldRemoveDirectory: Boolean): WritableMap {
return implementation.deleteDatabaseDirectory(databaseName, shouldRemoveDirectory)
return implementation.deleteDatabaseDirectory()
}
override fun renameDatabase(databaseName: String?, newDatabaseName: String?): WritableMap {

View file

@ -66,7 +66,7 @@ class RNUtilsModule(context: ReactApplicationContext) :
@ReactMethod(isBlockingSynchronousMethod = true)
fun deleteDatabaseDirectory(databaseName: String?, shouldRemoveDirectory: Boolean): WritableMap {
return implementation.deleteDatabaseDirectory(databaseName, shouldRemoveDirectory)
return implementation.deleteDatabaseDirectory()
}
@ReactMethod(isBlockingSynchronousMethod = true)

3418
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -11,13 +11,13 @@
"npm": "^9 || ^10"
},
"dependencies": {
"@formatjs/intl-datetimeformat": "6.17.1",
"@formatjs/intl-getcanonicallocales": "2.5.4",
"@formatjs/intl-listformat": "7.7.8",
"@formatjs/intl-locale": "4.2.8",
"@formatjs/intl-numberformat": "8.15.1",
"@formatjs/intl-pluralrules": "5.4.1",
"@gorhom/bottom-sheet": "5.0.6",
"@formatjs/intl-datetimeformat": "6.17.4",
"@formatjs/intl-getcanonicallocales": "2.5.5",
"@formatjs/intl-listformat": "7.7.11",
"@formatjs/intl-locale": "4.2.11",
"@formatjs/intl-numberformat": "8.15.4",
"@formatjs/intl-pluralrules": "5.4.4",
"@gorhom/bottom-sheet": "5.1.2",
"@mattermost/calls": "github:mattermost/calls-common#030ff7c0a37ee9b0ccc5fae0b2ea9c0e1c08473f",
"@mattermost/compass-icons": "0.1.48",
"@mattermost/hardware-keyboard": "file:./libraries/@mattermost/hardware-keyboard",
@ -27,22 +27,22 @@
"@mattermost/react-native-turbo-log": "0.6.0",
"@mattermost/rnshare": "file:./libraries/@mattermost/rnshare",
"@mattermost/rnutils": "file:./libraries/@mattermost/rnutils",
"@msgpack/msgpack": "2.8.0",
"@nozbe/watermelondb": "0.28.0-1",
"@react-native-camera-roll/camera-roll": "7.9.0",
"@react-native-clipboard/clipboard": "1.15.0",
"@msgpack/msgpack": "3.1.1",
"@nozbe/watermelondb": "0.28.0-2",
"@react-native-camera-roll/camera-roll": "7.10.0",
"@react-native-clipboard/clipboard": "1.16.2",
"@react-native-community/cli": "15.1.3",
"@react-native-community/cli-platform-android": "15.1.3",
"@react-native-community/cli-platform-ios": "15.1.3",
"@react-native-community/datetimepicker": "8.2.0",
"@react-native-community/datetimepicker": "8.3.0",
"@react-native-community/netinfo": "11.4.1",
"@react-native-cookies/cookies": "6.2.1",
"@react-navigation/bottom-tabs": "7.2.0",
"@react-navigation/native": "7.0.14",
"@react-navigation/stack": "7.1.0",
"@react-navigation/bottom-tabs": "7.3.2",
"@react-navigation/native": "7.0.18",
"@react-navigation/stack": "7.2.2",
"@rneui/base": "4.0.0-rc.8",
"@sentry/react-native": "6.4.0",
"@shopify/flash-list": "1.7.3",
"@shopify/flash-list": "1.7.6",
"@stream-io/flat-list-mvcp": "0.10.3",
"@voximplant/react-native-foreground-service": "3.0.2",
"APNG4Android": "github:mattermost/APNG4Android#15a7e93d59542d18c1e562d49b3f4896dd1643a6",
@ -52,69 +52,69 @@
"deep-equal": "2.2.3",
"deepmerge": "4.3.1",
"emoji-regex": "10.4.0",
"expo": "52.0.19",
"expo-application": "6.0.1",
"expo-crypto": "14.0.1",
"expo-device": "7.0.1",
"expo-image": "2.0.4",
"expo-linear-gradient": "14.0.1",
"expo-store-review": "8.0.0",
"expo-video-thumbnails": "9.0.2",
"expo-web-browser": "14.0.1",
"expo": "52.0.40",
"expo-application": "6.0.2",
"expo-crypto": "14.0.2",
"expo-device": "7.0.2",
"expo-image": "2.0.6",
"expo-linear-gradient": "14.0.2",
"expo-store-review": "8.0.1",
"expo-video-thumbnails": "9.0.3",
"expo-web-browser": "14.0.2",
"fflate": "0.8.2",
"fuse.js": "7.0.0",
"html-entities": "2.5.2",
"mime-db": "1.53.0",
"moment-timezone": "0.5.46",
"node-html-parser": "6.1.13",
"fuse.js": "7.1.0",
"html-entities": "2.5.3",
"mime-db": "1.54.0",
"moment-timezone": "0.5.48",
"node-html-parser": "7.0.1",
"path-to-regexp": "8.2.0",
"react": "18.3.1",
"react-freeze": "1.0.4",
"react-intl": "7.0.4",
"react-intl": "7.1.8",
"react-native": "0.76.5",
"react-native-background-timer": "2.4.1",
"react-native-document-picker": "9.3.1",
"react-native-dotenv": "3.4.11",
"react-native-exception-handler": "2.10.10",
"react-native-file-viewer": "2.1.5",
"react-native-gesture-handler": "2.21.2",
"react-native-gesture-handler": "2.24.0",
"react-native-haptic-feedback": "2.3.3",
"react-native-image-picker": "7.2.3",
"react-native-image-picker": "8.2.0",
"react-native-incall-manager": "4.2.0",
"react-native-keyboard-aware-scroll-view": "0.9.5",
"react-native-keychain": "9.2.2",
"react-native-localize": "3.3.0",
"react-native-keychain": "10.0.0",
"react-native-localize": "3.4.1",
"react-native-math-view": "3.9.5",
"react-native-navigation": "7.40.3",
"react-native-navigation": "7.44.0",
"react-native-notifications": "5.1.0",
"react-native-performance": "5.1.2",
"react-native-permissions": "5.2.1",
"react-native-reanimated": "3.16.5",
"react-native-safe-area-context": "5.0.0",
"react-native-screens": "4.3.0",
"react-native-permissions": "5.3.0",
"react-native-reanimated": "3.17.1",
"react-native-safe-area-context": "5.3.0",
"react-native-screens": "4.9.2",
"react-native-section-list-get-item-layout": "2.2.3",
"react-native-shadow-2": "7.1.1",
"react-native-share": "12.0.3",
"react-native-svg": "15.10.1",
"react-native-share": "12.0.9",
"react-native-svg": "15.11.2",
"react-native-url-polyfill": "2.0.0",
"react-native-vector-icons": "10.2.0",
"react-native-video": "6.8.2",
"react-native-video": "6.11.0",
"react-native-walkthrough-tooltip": "1.6.0",
"react-native-webrtc": "124.0.4",
"react-native-webrtc": "124.0.5",
"react-syntax-highlighter": "15.6.1",
"semver": "7.6.3",
"semver": "7.7.1",
"tinycolor2": "1.6.0",
"url-parse": "1.5.10"
},
"devDependencies": {
"@babel/cli": "7.26.4",
"@babel/core": "7.26.0",
"@babel/eslint-parser": "7.25.9",
"@babel/core": "7.26.10",
"@babel/eslint-parser": "7.26.10",
"@babel/plugin-proposal-class-properties": "7.18.6",
"@babel/plugin-proposal-decorators": "7.25.9",
"@babel/plugin-transform-flow-strip-types": "7.25.9",
"@babel/plugin-transform-runtime": "7.25.9",
"@babel/preset-env": "7.26.0",
"@babel/plugin-transform-flow-strip-types": "7.26.5",
"@babel/plugin-transform-runtime": "7.26.10",
"@babel/preset-env": "7.26.9",
"@babel/preset-typescript": "7.26.0",
"@babel/register": "7.25.9",
"@babel/runtime": "7.26.10",
@ -122,53 +122,54 @@
"@react-native/eslint-config": "0.76.5",
"@react-native/metro-config": "0.76.5",
"@react-native/typescript-config": "0.76.5",
"@stylistic/eslint-plugin-ts": "4.2.0",
"@testing-library/react-hooks": "8.0.1",
"@testing-library/react-native": "12.9.0",
"@testing-library/react-native": "13.2.0",
"@types/base-64": "1.0.2",
"@types/commonmark": "0.27.9",
"@types/commonmark-react-renderer": "4.3.4",
"@types/deep-equal": "1.0.4",
"@types/jest": "29.5.14",
"@types/lodash": "4.17.13",
"@types/lodash": "4.17.16",
"@types/mime-db": "1.43.5",
"@types/pako": "2.0.3",
"@types/querystringify": "2.0.2",
"@types/react": "18.3.12",
"@types/react-native-background-timer": "2.0.2",
"@types/react-native-dotenv": "0.2.2",
"@types/react-native-share": "6.0.0",
"@types/react-syntax-highlighter": "15.5.13",
"@types/semver": "7.5.8",
"@types/tinycolor2": "1.4.6",
"@types/tough-cookie": "4.0.5",
"@types/url-parse": "1.4.11",
"@types/uuid": "10.0.0",
"@typescript-eslint/eslint-plugin": "7.14.1",
"@typescript-eslint/parser": "7.14.1",
"@typescript-eslint/eslint-plugin": "8.27.0",
"@typescript-eslint/parser": "8.27.0",
"babel-jest": "29.7.0",
"babel-loader": "9.2.1",
"babel-loader": "10.0.0",
"babel-plugin-module-resolver": "5.0.2",
"eslint": "8.57.1",
"eslint": "9.23.0",
"eslint-plugin-header": "3.1.1",
"eslint-plugin-import": "2.31.0",
"eslint-plugin-jest": "28.9.0",
"eslint-plugin-react": "7.37.2",
"eslint-plugin-react-hooks": "5.1.0",
"eslint-plugin-jest": "28.11.0",
"eslint-plugin-react": "7.37.4",
"eslint-plugin-react-hooks": "5.2.0",
"husky": "9.1.7",
"isomorphic-fetch": "3.0.0",
"jest": "29.7.0",
"jest-cli": "29.7.0",
"jest-expo": "52.0.2",
"jest-expo": "52.0.6",
"jetifier": "2.0.0",
"mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
"nock": "13.5.6",
"nock": "14.0.1",
"patch-package": "8.0.0",
"react-devtools-core": "6.0.1",
"react-devtools-core": "6.1.1",
"react-test-renderer": "18.3.1",
"timezones.json": "1.7.1",
"tough-cookie": "5.0.0",
"ts-jest": "29.2.5",
"typescript": "5.7.2",
"uuid": "11.0.3"
"tough-cookie": "5.1.2",
"ts-jest": "29.2.6",
"typescript": "5.8.2",
"uuid": "11.1.0"
},
"scripts": {
"android": "react-native run-android",
@ -188,7 +189,7 @@
"ios": "react-native run-ios",
"ios-gems": "bundle install",
"ios-gems-m1": "arch -arm64 bundle install",
"lint": "eslint --ignore-path .gitignore --ignore-pattern node_modules --quiet .",
"lint": "eslint --ignore-pattern .gitignore --ignore-pattern node_modules --quiet .",
"mmjstool": "mmjstool",
"pod-install": "cd ios && RCT_NEW_ARCH_ENABLED=0 pod install",
"pod-install-m1": "cd ios && RCT_NEW_ARCH_ENABLED=0 arch -x86_64 pod install",
@ -203,22 +204,26 @@
"updatesnapshot": "jest --updateSnapshot"
},
"overrides": {
"promise": "^8.3.0",
"react-test-renderer": "18.3.1",
"@babel/runtime": "7.26.10",
"@babel/runtime-corejs3": "7.26.10",
"@testing-library/react-native": {
"react": "^18.3.1"
},
"@testing-library/react-hooks": {
"@types/react": "^18.2.37",
"react": "^18.3.1",
"react-test-renderer": "^18.2.0"
"react-test-renderer": "^18.3.1"
},
"@react-native-community/datetimepicker": {
"react-native": "^0.76.5"
},
"@react-native-clipboard/clipboard": {
"react-native": "^0.76.5"
},
"react-native-windows": {
"react-native": "^0.76.5"
},
"@react-native/eslint-config@0.76.5": {
"@typescript-eslint/eslint-plugin": "^8.26.1"
}
},
"expo": {

View file

@ -0,0 +1,13 @@
diff --git a/node_modules/react-intl/src/components/createIntl.js b/node_modules/react-intl/src/components/createIntl.js
index 6887909..d1819bc 100644
--- a/node_modules/react-intl/src/components/createIntl.js
+++ b/node_modules/react-intl/src/components/createIntl.js
@@ -32,7 +32,7 @@ var formatMessage = function (config, formatters, descriptor, rawValues) {
formatters,
descriptor,
values], rest, false));
- return (0, utils_1.toKeyedReactNodeArray)(chunks);
+ return typeof chunks === 'string' ? chunks : (0, utils_1.toKeyedReactNodeArray)(chunks);
};
/**
* Create intl object

View file

@ -1,5 +1,5 @@
diff --git a/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.h b/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.h
index 4a1234f..f3e2308 100644
index 4a1234f..1eb9519 100644
--- a/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.h
+++ b/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.h
@@ -10,5 +10,6 @@
@ -11,10 +11,10 @@ index 4a1234f..f3e2308 100644
+-(NSArray<NSString*>*)getAllServersForInternetPasswords;
@end
diff --git a/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.m b/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.m
index 18e42ab..ff130ab 100644
index 6888ff0..c5e1dc5 100644
--- a/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.m
+++ b/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.m
@@ -209,6 +209,36 @@ SecAccessControlCreateFlags accessControlValue(NSDictionary *options)
@@ -209,6 +209,35 @@ SecAccessControlCreateFlags accessControlValue(NSDictionary *options)
return 0;
}
@ -24,6 +24,7 @@ index 18e42ab..ff130ab 100644
+ (__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes,
+ (__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit,
+ nil];
+
+ NSMutableArray<NSString*> *servers = [NSMutableArray<NSString*> new];
+
+ [query setObject:(__bridge id)kSecClassInternetPassword forKey:(__bridge id)kSecClass];
@ -38,74 +39,74 @@ index 18e42ab..ff130ab 100644
+ if (result != NULL) {
+ for (id entry in result) {
+ NSString *serverData = [entry objectForKey:(__bridge NSString *)kSecAttrServer];
+ if (serverData != NULL) {
+ [servers addObject:serverData];
+ }
+ [servers addObject:serverData];
+ }
+ }
+ }
+
+
+ return servers;
+}
+
- (void)insertKeychainEntry:(NSDictionary *)attributes
withOptions:(NSDictionary * __nullable)options
resolver:(RCTPromiseResolveBlock)resolve
@@ -663,4 +693,14 @@ RCT_EXPORT_METHOD(getAllGenericPasswordServices:(RCTPromiseResolveBlock)resolve
}
@@ -627,6 +656,16 @@ RCT_EXPORT_METHOD(getInternetCredentialsForServer:(NSString *)server
}
+RCT_EXPORT_METHOD(getAllInternetPasswordServers:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
+{
+ @try {
+ NSArray *servers = [self getAllServersForInternetPasswords];
+ NSArray<NSString*> *servers = [self getAllServersForInternetPasswords];
+ return resolve(servers);
+ } @catch (NSError *nsError) {
+ return rejectWithError(reject, nsError);
+ }
+}
+
@end
RCT_EXPORT_METHOD(resetInternetCredentialsForOptions:(NSDictionary *)options
resolver:(RCTPromiseResolveBlock)resolve
rejecter:(RCTPromiseRejectBlock)reject)
diff --git a/node_modules/react-native-keychain/lib/typescript/index.d.ts b/node_modules/react-native-keychain/lib/typescript/index.d.ts
index 43f2e2f..dcef782 100644
index b868899..1e2b619 100644
--- a/node_modules/react-native-keychain/lib/typescript/index.d.ts
+++ b/node_modules/react-native-keychain/lib/typescript/index.d.ts
@@ -73,6 +73,17 @@ export declare function resetGenericPassword(serviceOrOptions?: string | BaseOpt
@@ -122,6 +122,17 @@ export declare function setInternetCredentials(server: string, username: string,
* ```
*/
export declare function getAllGenericPasswordServices(): Promise<string[]>;
export declare function getInternetCredentials(server: string, options?: GetOptions): Promise<false | UserCredentials>;
+/**
+* Gets all `kSecAttrServer` values used in internet credentials for iOS.
+* @return {Promise<string[]>} Resolves to an array of strings
+*
+* @example
+* ```typescript
+* const servers = await Keychain.getAllInternetPasswordServers();
+* console.log('Servers:', servers);
+* ```
+*/
+ * Gets all `kSecAttrServer` values used in internet credentials for iOS.
+ * @return {Promise<string[]>} Resolves to an array of strings
+ *
+ * @example
+ * ```typescript
+ * const servers = await Keychain.getAllInternetPasswordServers();
+ * console.log('Servers:', servers);
+ * ```
+ */
+export declare function getAllInternetPasswordServers(): Promise<string[]>;
/**
* Checks if internet credentials exist for the given server.
* Deletes all internet password keychain entries for the given server.
*
diff --git a/node_modules/react-native-keychain/src/index.ts b/node_modules/react-native-keychain/src/index.ts
index 7bfe371..3ac11b5 100644
index 1de35da..16eea24 100644
--- a/node_modules/react-native-keychain/src/index.ts
+++ b/node_modules/react-native-keychain/src/index.ts
@@ -132,6 +132,27 @@ export function getAllGenericPasswordServices(): Promise<string[]> {
return RNKeychainManager.getAllGenericPasswordServices();
@@ -200,6 +200,27 @@ export function getInternetCredentials(
);
}
+/**
+* Gets all `kSecAttrServer` values used in internet credentials for iOS.
+* @return {Promise<string>} Resolves to an array of strings
+*
+* @example
+* ```typescript
+* const servers = await Keychain.getAllInternetPasswordServers();
+* console.log('Servers:', servers);
+* ```
+*/
+ * Gets all `kSecAttrServer` values used in internet credentials for iOS.
+ * @return {Promise<string>} Resolves to an array of strings
+ *
+ * @example
+ * ```typescript
+ * const servers = await Keychain.getAllInternetPasswordServers();
+ * console.log('Servers:', servers);
+ * ```
+ */
+export async function getAllInternetPasswordServers(): Promise<string[]> {
+ if (Platform.OS !== 'ios') {
+ return Promise.reject(
@ -118,5 +119,5 @@ index 7bfe371..3ac11b5 100644
+}
+
/**
* Checks if internet credentials exist for the given server.
* Deletes all internet password keychain entries for the given server.
*

View file

@ -1,14 +1,13 @@
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 481aaf0..609e359 100644
index f3f0d5a..3af346d 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
@@ -1,18 +1,15 @@
@@ -1,13 +1,12 @@
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;
@ -18,11 +17,7 @@ index 481aaf0..609e359 100644
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;
@@ -24,9 +23,8 @@ import com.reactnativenavigation.viewcontrollers.navigator.Navigator;
import androidx.activity.OnBackPressedCallback;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@ -33,16 +28,16 @@ index 481aaf0..609e359 100644
@Nullable
private PermissionListener mPermissionListener;
@@ -50,7 +46,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
@@ -49,7 +47,7 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
);
navigator.bindViews();
getReactGateway().onActivityCreated(this);
- setBackPressedCallback();
+ // setBackPressedCallback();
StatusBarPresenter.Companion.init(this);
}
@Override
@@ -96,15 +92,16 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
@@ -96,15 +94,15 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
@Override
public void invokeDefaultOnBackPressed() {
@ -56,7 +51,6 @@ index 481aaf0..609e359 100644
+ // NavigationActivity.super.onBackPressed();
+ // callback.setEnabled(true);
+ // }
+ super.invokeDefaultOnBackPressed();
}
@Override
@ -65,7 +59,7 @@ index 481aaf0..609e359 100644
super.onActivityResult(requestCode, resultCode, data);
getReactGateway().onActivityResult(this, requestCode, resultCode, data);
}
@@ -126,7 +123,6 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
@@ -126,7 +124,6 @@ public class NavigationActivity extends AppCompatActivity implements DefaultHard
return navigator;
}
@ -73,31 +67,6 @@ index 481aaf0..609e359 100644
public void requestPermissions(String[] permissions, int requestCode, PermissionListener listener) {
mPermissionListener = listener;
requestPermissions(permissions, requestCode);
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java
index 0eced0f..251d72c 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/NavigationApplication.java
@@ -4,6 +4,7 @@ import android.app.Application;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactNativeHost;
+import com.facebook.react.soloader.OpenSourceMergedSoMapping;
import com.facebook.soloader.SoLoader;
import com.reactnativenavigation.react.ReactGateway;
import com.reactnativenavigation.viewcontrollers.externalcomponent.ExternalComponentCreator;
@@ -23,7 +24,11 @@ public abstract class NavigationApplication extends Application implements React
public void onCreate() {
super.onCreate();
instance = this;
- SoLoader.init(this, false);
+ try {
+ SoLoader.init(this, OpenSourceMergedSoMapping.INSTANCE);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
reactGateway = createReactGateway();
}
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 4cc09eb..857bbd4 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/react/NavigationModule.java
@ -302,50 +271,43 @@ index 4cc09eb..857bbd4 100644
+ super.invalidate();
}
}
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java
index 834d734..3fc00c3 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactTypefaceUtils.java
@@ -96,12 +96,12 @@ public class ReactTypefaceUtils {
int want = 0;
if ((weight == Typeface.BOLD)
- || ((oldStyle & Typeface.BOLD) != 0 && weight == ReactTextShadowNode.UNSET)) {
+ || ((oldStyle & Typeface.BOLD) != 0 && weight == -1)) {
want |= Typeface.BOLD;
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/react/ReactView.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/react/ReactView.java
index 0db6f39..0b265b7 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/react/ReactView.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/react/ReactView.java
@@ -10,7 +10,6 @@ import androidx.annotation.RestrictTo;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactRootView;
import com.facebook.react.bridge.ReactContext;
-import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.uimanager.JSTouchDispatcher;
import com.facebook.react.uimanager.UIManagerModule;
import com.facebook.react.uimanager.events.EventDispatcher;
@@ -35,7 +34,7 @@ public class ReactView extends ReactRootView implements IReactView, Renderable {
this.componentId = componentId;
this.componentName = componentName;
jsTouchDispatcher = new JSTouchDispatcher(this);
- setIsFabric(ReactFeatureFlags.enableFabricRenderer);
+ setIsFabric(false);
}
if ((style == Typeface.ITALIC)
- || ((oldStyle & Typeface.ITALIC) != 0 && style == ReactTextShadowNode.UNSET)) {
+ || ((oldStyle & Typeface.ITALIC) != 0 && style == -1)) {
want |= Typeface.ITALIC;
}
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactViewGroup.kt b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactViewGroup.kt
index f92580c..a58fa7b 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactViewGroup.kt
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/utils/ReactViewGroup.kt
@@ -4,4 +4,4 @@ import com.facebook.react.views.view.ReactViewBackgroundDrawable
import com.facebook.react.views.view.ReactViewGroup
val ReactViewGroup.borderRadius: Float
- get() = (background as? ReactViewBackgroundDrawable)?.fullBorderRadius ?: 0f
\ No newline at end of file
+ get() = 0f
\ No newline at end of file
@Override
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java
index 3acc41d..ebc8d18 100644
index f014bff..e4ccc55 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java
@@ -7,6 +7,7 @@ import android.util.Log;
import android.view.View;
@@ -6,8 +6,10 @@ import android.view.View;
import android.view.ViewGroup;
import android.view.WindowInsets;
import androidx.annotation.CallSuper;
+import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;
+import android.view.WindowManager;
import com.reactnativenavigation.options.Options;
import com.reactnativenavigation.utils.LogKt;
@@ -100,6 +101,18 @@ public abstract class ChildController<T extends ViewGroup> extends ViewControlle
import com.reactnativenavigation.viewcontrollers.navigator.Navigator;
@@ -93,6 +95,18 @@ public abstract class ChildController<T extends ViewGroup> extends ViewControlle
}
protected WindowInsetsCompat onApplyWindowInsets(View view, WindowInsetsCompat insets) {
@ -364,32 +326,6 @@ index 3acc41d..ebc8d18 100644
return insets;
}
diff --git a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/LayoutDirectionApplier.kt b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/LayoutDirectionApplier.kt
index 89216ae..345207a 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/LayoutDirectionApplier.kt
+++ b/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/viewcontroller/LayoutDirectionApplier.kt
@@ -1,15 +1,17 @@
package com.reactnativenavigation.viewcontrollers.viewcontroller
+import com.facebook.react.bridge.ReactContext
import com.facebook.react.ReactInstanceManager
import com.facebook.react.modules.i18nmanager.I18nUtil
import com.reactnativenavigation.options.Options
class LayoutDirectionApplier {
fun apply(root: ViewController<*>, options: Options, instanceManager: ReactInstanceManager) {
- if (options.layout.direction.hasValue() && instanceManager.currentReactContext != null) {
+ val reactContext = instanceManager.currentReactContext as? ReactContext
+ if (reactContext != null && options.layout.direction.hasValue()) {
root.activity.window.decorView.layoutDirection = options.layout.direction.get()
- I18nUtil.getInstance().allowRTL(instanceManager.currentReactContext, options.layout.direction.isRtl)
- I18nUtil.getInstance().forceRTL(instanceManager.currentReactContext, options.layout.direction.isRtl)
+ I18nUtil.getInstance().allowRTL(reactContext, options.layout.direction.isRtl)
+ I18nUtil.getInstance().forceRTL(reactContext, options.layout.direction.isRtl)
}
}
}
\ No newline at end of file
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
@ -406,75 +342,62 @@ index 035ec31..630b8d4 100644
+ }
}
diff --git a/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt b/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt
index ea8516f..f275c18 100644
index 551f72b..f275c18 100644
--- a/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt
+++ b/node_modules/react-native-navigation/lib/android/app/src/reactNative71/java/com/reactnativenavigation/react/modal/ModalContentLayout.kt
@@ -50,13 +50,19 @@ class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{
@@ -49,17 +49,23 @@ class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{
updateFirstChildView()
}
}
override fun onChildStartedNativeGesture(child: View, androidEvent: MotionEvent?) {
- override fun onChildStartedNativeGesture(child: View, androidEvent: MotionEvent) {
- mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher())
+ override fun onChildStartedNativeGesture(child: View, androidEvent: MotionEvent?) {
+ androidEvent?.let {
+ mJSTouchDispatcher.onChildStartedNativeGesture(it, this.getEventDispatcher()!!)
+ }
}
override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) {
- override fun onChildStartedNativeGesture(androidEvent: MotionEvent) {
- mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher())
+ override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) {
+ androidEvent?.let {
+ mJSTouchDispatcher.onChildStartedNativeGesture(it, this.getEventDispatcher()!!)
+ }
}
override fun onChildEndedNativeGesture(child: View, androidEvent: MotionEvent?) {
- override fun onChildEndedNativeGesture(child: View, androidEvent: MotionEvent) {
- mJSTouchDispatcher.onChildEndedNativeGesture(androidEvent, this.getEventDispatcher())
+ override fun onChildEndedNativeGesture(child: View, androidEvent: MotionEvent?) {
+ androidEvent?.let {
+ mJSTouchDispatcher.onChildEndedNativeGesture(it, this.getEventDispatcher()!!)
+ }
}
override fun requestDisallowInterceptTouchEvent(disallowIntercept: Boolean) {}
private fun getEventDispatcher(): EventDispatcher? {
@@ -74,12 +80,16 @@ class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{
- private fun getEventDispatcher(): EventDispatcher {
+ private fun getEventDispatcher(): EventDispatcher? {
val reactContext: ReactContext = this.getReactContext()
return reactContext.getNativeModule(UIManagerModule::class.java)!!.eventDispatcher
}
@@ -73,13 +79,17 @@ class ModalContentLayout(context: Context?) : ReactViewGroup(context), RootView{
return this.context as ReactContext
}
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
- override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
- mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher())
+ override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
+ event?.let {
+ mJSTouchDispatcher.handleTouchEvent(it, getEventDispatcher()!!)
+ }
return super.onInterceptTouchEvent(event)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
- override fun onTouchEvent(event: MotionEvent): Boolean {
- mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher())
+ override fun onTouchEvent(event: MotionEvent?): Boolean {
+ event?.let {
+ mJSTouchDispatcher.handleTouchEvent(it, getEventDispatcher()!!)
+ }
super.onTouchEvent(event)
return true
}
diff --git a/node_modules/react-native-navigation/lib/ios/BottomTabsBasePresenter.m b/node_modules/react-native-navigation/lib/ios/BottomTabsBasePresenter.m
index 75aa424..f0a7e08 100644
--- a/node_modules/react-native-navigation/lib/ios/BottomTabsBasePresenter.m
+++ b/node_modules/react-native-navigation/lib/ios/BottomTabsBasePresenter.m
@@ -29,8 +29,6 @@
[self applyBackgroundColor:[withDefault.bottomTabs.backgroundColor withDefault:nil]
translucent:[withDefault.bottomTabs.translucent withDefault:NO]];
[bottomTabs setTabBarHideShadow:[withDefault.bottomTabs.hideShadow withDefault:NO]];
- [bottomTabs setTabBarStyle:[RCTConvert UIBarStyle:[withDefault.bottomTabs.barStyle
- withDefault:@"default"]]];
[self applyTabBarBorder:withDefault.bottomTabs];
[self applyTabBarShadow:withDefault.bottomTabs.shadow];
}
@@ -59,10 +57,6 @@
[self setTabBarBackgroundColor:mergeOptions.bottomTabs.backgroundColor.get];
}
- if (mergeOptions.bottomTabs.barStyle.hasValue) {
- [bottomTabs setTabBarStyle:[RCTConvert UIBarStyle:mergeOptions.bottomTabs.barStyle.get]];
- }
-
if (mergeOptions.bottomTabs.translucent.hasValue) {
[bottomTabs setTabBarTranslucent:mergeOptions.bottomTabs.translucent.get];
}
diff --git a/node_modules/react-native-navigation/lib/ios/RNNComponentViewController.m b/node_modules/react-native-navigation/lib/ios/RNNComponentViewController.m
index fc482a6..9406bbf 100644
--- a/node_modules/react-native-navigation/lib/ios/RNNComponentViewController.m
@ -509,32 +432,8 @@ index b44f24f..bf4e1c3 100644
[hitTestResult isKindOfClass:[RCTModalHostView class]] ||
[hitTestResult isKindOfClass:NSClassFromString(@"RCTRootComponentView")]) {
return nil;
diff --git a/node_modules/react-native-navigation/lib/ios/RNNStackPresenter.m b/node_modules/react-native-navigation/lib/ios/RNNStackPresenter.m
index 5f4218e..8513863 100644
--- a/node_modules/react-native-navigation/lib/ios/RNNStackPresenter.m
+++ b/node_modules/react-native-navigation/lib/ios/RNNStackPresenter.m
@@ -67,8 +67,6 @@
[_interactivePopGestureDelegate setEnabled:[withDefault.popGesture withDefault:YES]];
stack.interactivePopGestureRecognizer.delegate = _interactivePopGestureDelegate;
- [stack
- setBarStyle:[RCTConvert UIBarStyle:[withDefault.topBar.barStyle withDefault:@"default"]]];
[stack setRootBackgroundImage:[withDefault.rootBackgroundImage withDefault:nil]];
[stack setNavigationBarTestId:[withDefault.topBar.testID withDefault:nil]];
[stack setNavigationBarVisible:[withDefault.topBar.visible withDefault:YES]
@@ -125,10 +123,6 @@
[stack hideBarsOnScroll:[mergeOptions.topBar.hideOnScroll get]];
}
- if (mergeOptions.topBar.barStyle.hasValue) {
- [stack setBarStyle:[RCTConvert UIBarStyle:mergeOptions.topBar.barStyle.get]];
- }
-
if (mergeOptions.topBar.background.clipToBounds.hasValue) {
[stack setNavigationBarClipsToBounds:[mergeOptions.topBar.background.clipToBounds get]];
}
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 1ab5b4e..ccd0b74 100644
index f0923ed..b0ea7fc 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 @@

View file

@ -9,7 +9,6 @@ import mockSafeAreaContext from 'react-native-safe-area-context/jest/mock';
import {v4 as uuidv4} from 'uuid';
import 'react-native-gesture-handler/jestSetup';
import '@testing-library/react-native/extend-expect';
import {mockApiClient} from './mock_api_client';
@ -18,6 +17,9 @@ import type {RequestOptions} from '@mattermost/react-native-network-client';
// @ts-expect-error Promise does not exists in global
global.Promise = jest.requireActual('promise');
// eslint-disable-next-line no-process-env
process.env.EXPO_OS = 'ios';
setGenerator(uuidv4);
require('isomorphic-fetch');
@ -69,6 +71,13 @@ jest.mock('expo-web-browser', () => ({
jest.mock('@nozbe/watermelondb/utils/common/randomId/randomId', () => ({}));
jest.mock('@nozbe/watermelondb/react/withObservables/garbageCollector', () => {
return {
__esModule: true,
default: jest.fn(),
};
});
/* eslint-disable no-console */
jest.mock('@database/manager');
jest.doMock('react-native', () => {
@ -166,6 +175,7 @@ jest.doMock('react-native', () => {
removeServerNotifications: jest.fn().mockImplementation(),
unlockOrientation: jest.fn(),
getWindowDimensions: jest.fn().mockReturnValue({width: 426, height: 952}),
},
APIClient: {
getConstants: () => ({
@ -231,6 +241,12 @@ jest.doMock('react-native', () => {
InteractionManager,
NativeModules,
Linking,
Animated: {
...ReactNative.Animated,
timing: jest.fn(() => ({
start: jest.fn((callback) => callback?.({finished: true})),
})),
},
}, ReactNative);
});
@ -388,12 +404,12 @@ jest.mock('@react-native-clipboard/clipboard', () => ({}));
jest.mock('react-native-document-picker', () => ({}));
jest.mock('@mattermost/react-native-network-client', () => ({
getOrCreateAPIClient: (serverUrl: string) => ({client: {
getOrCreateAPIClient: jest.fn((serverUrl: string) => Promise.resolve({client: {
baseUrl: serverUrl,
get: (url: string, options?: RequestOptions) => mockApiClient.get(`${serverUrl}${url}`, options),
post: (url: string, options?: RequestOptions) => mockApiClient.post(`${serverUrl}${url}`, options),
invalidate: jest.fn(),
}}),
}})),
RetryTypes: {
EXPONENTIAL_RETRY: 'exponential',
},
@ -424,3 +440,24 @@ global.requestAnimationFrame = (callback) => {
};
global.performance.now = () => Date.now();
const colors = {
reset: '\x1b[0m',
yellow: '\x1b[33m',
red: '\x1b[31m',
cyan: '\x1b[36m',
blue: '\x1b[1;34m',
};
const filterStackTrace = (color: string, prefix: string) => {
return (...args: unknown[]) => {
const message = args.join(' ');
process.stdout.write(`\n${color}${prefix} ${message}${colors.reset}\n`);
};
};
// Override console methods globally
console.warn = filterStackTrace(colors.yellow, '⚠️ Warning:');
console.error = filterStackTrace(colors.red, '🚨 Error:');
console.log = filterStackTrace(colors.cyan, '📢 Log:');
console.debug = filterStackTrace(colors.blue, '🐞 Debug:');

View file

@ -1,7 +1,7 @@
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
import type {DeepLink, Launch} from '@constants';
import type {DeepLink as DeepLinkConstant, Launch} from '@constants';
export interface DeepLink {
serverUrl: string;
@ -33,7 +33,7 @@ export interface DeepLinkPlugin extends DeepLink {
route?: string;
}
export type DeepLinkType = typeof DeepLink[keyof typeof DeepLink];
export type DeepLinkType = typeof DeepLinkConstant[keyof typeof DeepLinkConstant];
export interface DeepLinkWithData {
type: DeepLinkType;

View file

@ -5,17 +5,17 @@
// See LICENSE.txt for license information.
import type {Caption} from '@mattermost/calls/lib/types';
import type {GestureHandlerGestureEvent} from 'react-native-gesture-handler';
import type Animated from 'react-native-reanimated';
import type {SharedValue} from 'react-native-reanimated';
export type GalleryManagerSharedValues = {
width: Animated.SharedValue<number>;
height: Animated.SharedValue<number>;
x: Animated.SharedValue<number>;
y: Animated.SharedValue<number>;
opacity: Animated.SharedValue<number>;
activeIndex: Animated.SharedValue<number>;
targetWidth: Animated.SharedValue<number>;
targetHeight: Animated.SharedValue<number>;
width: SharedValue<number>;
height: SharedValue<number>;
x: SharedValue<number>;
y: SharedValue<number>;
opacity: SharedValue<number>;
activeIndex: SharedValue<number>;
targetWidth: SharedValue<number>;
targetHeight: SharedValue<number>;
}
export type Context = { [key: string]: any };