Update dependencies and upgrade to RN 0.76.5 (#8421)
* update dev deps * partial update dependencies * update watermelondb * update rn to 0.76.5, expo to 52.0.18 and others * upgrade android firebase * upgrade detox deps * fix package-lock.json * update emm and paste-input * update turbo-log * update network library * fix tests * review feedback * fix Keyboard blocking signIn button * Fall back to iphone 14 iOS 17.2 simulator as app crashes on iOS 17.4 * changes in deleteCredentialsForServer is causing a crash * withOptions x2 clearly is wrong * re-add cli-platform-apple fix * fix: RN 0.76.5 issue with bottom sheet disappearing (#8478) * experiment, using view vs BottomSheetView * revert previous & try disabling enableDynamicSizing * revert an unintended removal --------- Co-authored-by: yasserfaraazkhan <attitude3cena.yf@gmail.com> Co-authored-by: Mattermost Build <build@mattermost.com> Co-authored-by: Rahim Rahman <rahim.rahman@mattermost.com>
This commit is contained in:
parent
52e05fba13
commit
2f3dfbbbfa
101 changed files with 28335 additions and 33928 deletions
|
|
@ -39,7 +39,7 @@
|
|||
{
|
||||
"rule": "cli",
|
||||
"binary": "pod",
|
||||
"semver": "1.15.2",
|
||||
"semver": "1.16.1",
|
||||
"platform": "darwin"
|
||||
}
|
||||
],
|
||||
|
|
|
|||
2
Gemfile
2
Gemfile
|
|
@ -1,3 +1,3 @@
|
|||
source "https://rubygems.org"
|
||||
|
||||
gem "cocoapods", "1.15.2"
|
||||
gem "cocoapods", "1.16.1"
|
||||
|
|
|
|||
38
Gemfile.lock
38
Gemfile.lock
|
|
@ -5,16 +5,18 @@ GEM
|
|||
base64
|
||||
nkf
|
||||
rexml
|
||||
activesupport (7.1.3.4)
|
||||
activesupport (7.2.2.1)
|
||||
base64
|
||||
benchmark (>= 0.3)
|
||||
bigdecimal
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
concurrent-ruby (~> 1.0, >= 1.3.1)
|
||||
connection_pool (>= 2.2.5)
|
||||
drb
|
||||
i18n (>= 1.6, < 2)
|
||||
logger (>= 1.4.2)
|
||||
minitest (>= 5.1)
|
||||
mutex_m
|
||||
tzinfo (~> 2.0)
|
||||
securerandom (>= 0.3)
|
||||
tzinfo (~> 2.0, >= 2.0.5)
|
||||
addressable (2.8.7)
|
||||
public_suffix (>= 2.0.2, < 7.0)
|
||||
algoliasearch (1.27.5)
|
||||
|
|
@ -22,12 +24,13 @@ GEM
|
|||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
base64 (0.2.0)
|
||||
benchmark (0.4.0)
|
||||
bigdecimal (3.1.8)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.15.2)
|
||||
cocoapods (1.16.1)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.15.2)
|
||||
cocoapods-core (= 1.16.1)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 2.1, < 3.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
|
|
@ -41,8 +44,8 @@ GEM
|
|||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 2.3.0, < 3.0)
|
||||
xcodeproj (>= 1.23.0, < 2.0)
|
||||
cocoapods-core (1.15.2)
|
||||
xcodeproj (>= 1.26.0, < 2.0)
|
||||
cocoapods-core (1.16.1)
|
||||
activesupport (>= 5.0, < 8)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
|
|
@ -73,36 +76,37 @@ GEM
|
|||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.14.5)
|
||||
i18n (1.14.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.7.2)
|
||||
minitest (5.25.1)
|
||||
json (2.9.0)
|
||||
logger (1.6.3)
|
||||
minitest (5.25.4)
|
||||
molinillo (0.8.0)
|
||||
mutex_m (0.2.0)
|
||||
nanaimo (0.3.0)
|
||||
nanaimo (0.4.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
nkf (0.2.0)
|
||||
public_suffix (4.0.7)
|
||||
rexml (3.3.9)
|
||||
ruby-macho (2.5.1)
|
||||
securerandom (0.4.0)
|
||||
typhoeus (1.4.1)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.25.0)
|
||||
xcodeproj (1.27.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (>= 3.3.2, < 4.0)
|
||||
nanaimo (~> 0.4.0)
|
||||
rexml (>= 3.3.6, < 4.0)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
cocoapods (= 1.15.2)
|
||||
cocoapods (= 1.16.1)
|
||||
|
||||
BUNDLED WITH
|
||||
2.5.11
|
||||
|
|
|
|||
|
|
@ -9,14 +9,14 @@ apply plugin: "com.facebook.react"
|
|||
|
||||
react {
|
||||
/* Folders */
|
||||
// The root of your project, i.e. where "package.json" lives. Default is '..'
|
||||
// root = file("../")
|
||||
// The folder where the react-native NPM package is. Default is ../node_modules/react-native
|
||||
// reactNativeDir = file("../node_modules/react-native")
|
||||
// The folder where the react-native Codegen package is. Default is ../node_modules/@react-native/codegen
|
||||
// codegenDir = file("../node_modules/@react-native/codegen")
|
||||
// The cli.js file which is the React Native CLI entrypoint. Default is ../node_modules/react-native/cli.js
|
||||
// cliFile = file("../node_modules/react-native/cli.js")
|
||||
// The root of your project, i.e. where "package.json" lives. Default is '../..'
|
||||
// root = file("../../")
|
||||
// The folder where the react-native NPM package is. Default is ../../node_modules/react-native
|
||||
// reactNativeDir = file("../../node_modules/react-native")
|
||||
// The folder where the react-native Codegen package is. Default is ../../node_modules/@react-native/codegen
|
||||
// codegenDir = file("../../node_modules/@react-native/codegen")
|
||||
// The cli.js file which is the React Native CLI entrypoint. Default is ../../node_modules/react-native/cli.js
|
||||
// cliFile = file("../../node_modules/react-native/cli.js")
|
||||
/* Variants */
|
||||
// The list of variants to that are debuggable. For those we're going to
|
||||
// skip the bundling of the JS bundle and the assets. By default is just 'debug'.
|
||||
|
|
@ -47,6 +47,9 @@ apply plugin: "com.facebook.react"
|
|||
//
|
||||
// The list of flags to pass to the Hermes compiler. By default is "-O", "-output-source-map"
|
||||
// hermesFlags = ["-O", "-output-source-map"]
|
||||
|
||||
/* Autolinking */
|
||||
autolinkLibrariesWithApp()
|
||||
}
|
||||
|
||||
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
|
||||
|
|
@ -253,4 +256,3 @@ tasks.register('copyDownloadableDepsToLibs', Copy) {
|
|||
}
|
||||
|
||||
apply plugin: 'com.google.gms.google-services'
|
||||
apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ public class Network {
|
|||
private static final Promise emptyPromise = new ResolvePromise();
|
||||
|
||||
public static void init(Context context) {
|
||||
final ReactApplicationContext reactContext = (ApiClientModuleImpl.context == null) ? new ReactApplicationContext(context) : ApiClientModuleImpl.context;
|
||||
final ReactApplicationContext reactContext = (ApiClientModuleImpl.context == null) ? (ReactApplicationContext) context.getApplicationContext() : ApiClientModuleImpl.context;
|
||||
clientModule = new ApiClientModuleImpl(reactContext);
|
||||
createClientOptions();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.mattermost.helpers;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
|
|
@ -9,58 +10,59 @@ import com.facebook.react.bridge.WritableMap;
|
|||
* ResolvePromise: Helper class that abstracts boilerplate
|
||||
*/
|
||||
public class ResolvePromise implements Promise {
|
||||
|
||||
@Override
|
||||
public void resolve(@javax.annotation.Nullable Object value) {
|
||||
public void reject(@NonNull String s) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, String message) {
|
||||
public void resolve(@Nullable Object o) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, @NonNull WritableMap map) {
|
||||
public void reject(@NonNull String s, @Nullable String s1) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, Throwable e) {
|
||||
public void reject(@NonNull String s, @Nullable Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(Throwable e, WritableMap map) {
|
||||
public void reject(@NonNull String s, @Nullable String s1, @Nullable Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, Throwable e, WritableMap map) {
|
||||
public void reject(@NonNull Throwable throwable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, String message, Throwable e, WritableMap map) {
|
||||
public void reject(@NonNull Throwable throwable, @NonNull WritableMap writableMap) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, String message, Throwable e) {
|
||||
public void reject(@NonNull String s, @NonNull WritableMap writableMap) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String code, String message, @NonNull WritableMap map) {
|
||||
public void reject(@NonNull String s, @Nullable Throwable throwable, @NonNull WritableMap writableMap) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(String message) {
|
||||
public void reject(@NonNull String s, @Nullable String s1, @NonNull WritableMap writableMap) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reject(Throwable reason) {
|
||||
public void reject(@Nullable String s, @Nullable String s1, @Nullable Throwable throwable, @Nullable WritableMap writableMap) {
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,12 +22,12 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetch(serverUrl: Str
|
|||
}
|
||||
}
|
||||
|
||||
override fun reject(code: String, message: String) {
|
||||
override fun reject(code: String, message: String?) {
|
||||
cont.resumeWith(Result.failure(IOException("Unexpected code $code $message")))
|
||||
}
|
||||
|
||||
override fun reject(reason: Throwable?) {
|
||||
cont.resumeWith(Result.failure(IOException("Unexpected code $reason")))
|
||||
override fun reject(throwable: Throwable) {
|
||||
cont.resumeWith(Result.failure(IOException("Unexpected code $throwable")))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -41,12 +41,12 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetchWithPost(server
|
|||
cont.resumeWith(Result.success(response))
|
||||
}
|
||||
|
||||
override fun reject(code: String, message: String) {
|
||||
override fun reject(code: String, message: String?) {
|
||||
cont.resumeWith(Result.failure(IOException("Unexpected code $code $message")))
|
||||
}
|
||||
|
||||
override fun reject(reason: Throwable?) {
|
||||
cont.resumeWith(Result.failure(IOException("Unexpected code $reason")))
|
||||
override fun reject(throwable: Throwable) {
|
||||
cont.resumeWith(Result.failure(IOException("Unexpected code $throwable")))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,14 +7,13 @@ import android.content.res.Configuration
|
|||
import android.os.Bundle
|
||||
import com.facebook.react.PackageList
|
||||
import com.facebook.react.ReactHost
|
||||
import com.facebook.react.ReactInstanceManager
|
||||
import com.facebook.react.ReactNativeHost
|
||||
import com.facebook.react.ReactPackage
|
||||
import com.facebook.react.bridge.ReactContext
|
||||
import com.facebook.react.bridge.UiThreadUtil
|
||||
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.load
|
||||
import com.facebook.react.defaults.DefaultReactHost.getDefaultReactHost
|
||||
import com.facebook.react.defaults.DefaultReactNativeHost
|
||||
import com.facebook.react.soloader.OpenSourceMergedSoMapping
|
||||
import com.facebook.react.modules.network.OkHttpClientProvider
|
||||
import com.facebook.soloader.SoLoader
|
||||
import com.mattermost.networkclient.RCTOkHttpClientFactory
|
||||
|
|
@ -22,6 +21,7 @@ import com.mattermost.rnshare.helpers.RealPathUtil
|
|||
import com.mattermost.turbolog.TurboLog
|
||||
import com.mattermost.turbolog.ConfigureOptions
|
||||
import com.nozbe.watermelondb.jsi.JSIInstaller
|
||||
import com.nozbe.watermelondb.jsi.WatermelonDBJSIPackage
|
||||
import com.reactnativenavigation.NavigationApplication
|
||||
import com.wix.reactnativenotifications.RNNotificationsPackage
|
||||
import com.wix.reactnativenotifications.core.AppLaunchHelper
|
||||
|
|
@ -45,6 +45,7 @@ class MainApplication : NavigationApplication(), INotificationsApplication {
|
|||
// Packages that cannot be autolinked yet can be added manually here, for example:
|
||||
// add(MyReactNativePackage())
|
||||
add(RNNotificationsPackage(this@MainApplication))
|
||||
add(WatermelonDBJSIPackage())
|
||||
}
|
||||
|
||||
override fun getJSMainModuleName(): String = "index"
|
||||
|
|
@ -78,13 +79,12 @@ class MainApplication : NavigationApplication(), INotificationsApplication {
|
|||
OkHttpClientProvider.setOkHttpClientFactory(RCTOkHttpClientFactory())
|
||||
ExpoImageOkHttpClientGlideModule.okHttpClient = RCTOkHttpClientFactory().createNewNetworkModuleClient()
|
||||
|
||||
SoLoader.init(this, false)
|
||||
SoLoader.init(this, OpenSourceMergedSoMapping)
|
||||
if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
|
||||
// If you opted-in for the New Architecture, we load the native entry point for this app.
|
||||
load(bridgelessEnabled = false)
|
||||
}
|
||||
ApplicationLifecycleDispatcher.onApplicationCreate(this)
|
||||
registerJSIModules()
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
|
|
@ -117,27 +117,4 @@ class MainApplication : NavigationApplication(), INotificationsApplication {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
private fun registerJSIModules() {
|
||||
val reactInstanceManager = reactNativeHost.reactInstanceManager
|
||||
|
||||
if (!listenerAdded) {
|
||||
listenerAdded = true
|
||||
reactInstanceManager.addReactInstanceEventListener(object : ReactInstanceManager.ReactInstanceEventListener {
|
||||
override fun onReactContextInitialized(context: ReactContext) {
|
||||
runOnJSQueueThread {
|
||||
registerWatermelonJSI(context)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun registerWatermelonJSI(context: ReactContext) {
|
||||
val holder = context.javaScriptContextHolder?.get()
|
||||
if (holder != null) {
|
||||
JSIInstaller.install(context, holder)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,14 @@
|
|||
buildscript {
|
||||
ext {
|
||||
buildToolsVersion = "34.0.0"
|
||||
buildToolsVersion = "35.0.0"
|
||||
minSdkVersion = 24
|
||||
compileSdkVersion = 34
|
||||
compileSdkVersion = 35
|
||||
targetSdkVersion = 34
|
||||
supportLibVersion = "33.0.0"
|
||||
kotlinVersion = "1.9.22"
|
||||
supportLibVersion = "35.0.0"
|
||||
kotlinVersion = "1.9.24"
|
||||
kotlin_version = kotlinVersion
|
||||
RNNKotlinVersion = kotlinVersion
|
||||
firebaseVersion = "24.0.0"
|
||||
firebaseVersion = "24.1.0"
|
||||
ndkVersion = "26.1.10909125"
|
||||
}
|
||||
repositories {
|
||||
|
|
|
|||
|
|
@ -25,9 +25,6 @@ org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF
|
|||
# https://developer.android.com/topic/libraries/support-library/androidx-rn
|
||||
android.useAndroidX=true
|
||||
|
||||
# Automatically convert third-party libraries to use AndroidX
|
||||
android.enableJetifier=true
|
||||
|
||||
# Use this property to specify which architecture you want to build.
|
||||
# You can also override it from the CLI using
|
||||
# ./gradlew <task> -PreactNativeArchitectures=x86_64
|
||||
|
|
|
|||
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
BIN
android/gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
|
|
@ -1,6 +1,6 @@
|
|||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.6-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip
|
||||
networkTimeout=10000
|
||||
validateDistributionUrl=true
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
|
|
|
|||
7
android/gradlew
vendored
7
android/gradlew
vendored
|
|
@ -15,6 +15,8 @@
|
|||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
|
|
@ -55,7 +57,7 @@
|
|||
# Darwin, MinGW, and NonStop.
|
||||
#
|
||||
# (3) This script is generated from the Groovy template
|
||||
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
|
||||
# within the Gradle project.
|
||||
#
|
||||
# You can find Gradle at https://github.com/gradle/gradle/.
|
||||
|
|
@ -84,7 +86,8 @@ done
|
|||
# shellcheck disable=SC2034
|
||||
APP_BASE_NAME=${0##*/}
|
||||
# Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036)
|
||||
APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit
|
||||
APP_HOME=$( cd -P "${APP_HOME:-./}" > /dev/null && printf '%s
|
||||
' "$PWD" ) || exit
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD=maximum
|
||||
|
|
|
|||
2
android/gradlew.bat
vendored
2
android/gradlew.bat
vendored
|
|
@ -13,6 +13,8 @@
|
|||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
@rem SPDX-License-Identifier: Apache-2.0
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%"=="" @echo off
|
||||
@rem ##########################################################################
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
pluginManagement { includeBuild("../node_modules/@react-native/gradle-plugin") }
|
||||
plugins { id("com.facebook.react.settings") }
|
||||
extensions.configure(com.facebook.react.ReactSettingsExtension){ ex -> ex.autolinkLibrariesFromCommand() }
|
||||
|
||||
rootProject.name = 'Mattermost'
|
||||
include ':app'
|
||||
include ':reactnativenotifications'
|
||||
project(':reactnativenotifications').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-notifications/lib/android/app')
|
||||
apply from: file("../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesSettingsGradle(settings)
|
||||
include ':watermelondb-jsi'
|
||||
project(':watermelondb-jsi').projectDir = new File(rootProject.projectDir, '../node_modules/@nozbe/watermelondb/native/android-jsi')
|
||||
includeBuild('../node_modules/@react-native/gradle-plugin')
|
||||
|
|
|
|||
|
|
@ -141,7 +141,7 @@ describe('ClientTraking', () => {
|
|||
group.urls = {
|
||||
'https://example.com/api': {
|
||||
count: 2,
|
||||
metrics: {latency: 200, networkType: 'Wi-Fi', tlsCipherSuite: 'none', tlsVersion: 'none', isCached: false, httpVersion: 'h2', compressedSize: 10 * 1024, size: 6 * 1024 * 1024, connectionTime: 0},
|
||||
metrics: {latency: 200, networkType: 'Wi-Fi', tlsCipherSuite: 'none', tlsVersion: 'none', isCached: false, httpVersion: 'h2', compressedSize: 10 * 1024, size: 6 * 1024 * 1024, connectionTime: 0, startTime: 0, endTime: 100, speedInMbps: 1},
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ const AnnouncementBanner = ({
|
|||
snapPoints: [1, snapPoint],
|
||||
theme,
|
||||
});
|
||||
}, [theme.sidebarHeaderTextColor, intl.locale, renderContent, allowDismissal]);
|
||||
}, [intl, allowDismissal, renderContent, theme]);
|
||||
|
||||
const handleDismiss = useCallback(() => {
|
||||
dismissAnnouncement(serverUrl, bannerText);
|
||||
|
|
@ -129,7 +129,7 @@ const AnnouncementBanner = ({
|
|||
height.value = withTiming(visible ? ANNOUNCEMENT_BAR_HEIGHT : 0, {
|
||||
duration: 200,
|
||||
});
|
||||
}, [visible]);
|
||||
}, [height, visible]);
|
||||
|
||||
const bannerStyle = useAnimatedStyle(() => ({
|
||||
height: height.value,
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import {Image, type ImageStyle} from 'expo-image';
|
||||
import React, {useState, useCallback} from 'react';
|
||||
import {type StyleProp, type TextStyle, type ViewStyle} from 'react-native';
|
||||
import {type StyleProp, type TextStyle} from 'react-native';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import Emoji from '@components/emoji';
|
||||
|
|
@ -18,7 +18,7 @@ type Props = {
|
|||
iconSize: number;
|
||||
imageStyle?: StyleProp<ImageStyle>;
|
||||
imageUrl?: string;
|
||||
genericStyle: StyleProp<ViewStyle>;
|
||||
genericStyle: StyleProp<TextStyle>;
|
||||
}
|
||||
|
||||
const BookmarkIcon = ({emoji, emojiSize, emojiStyle, file, genericStyle, iconSize, imageStyle, imageUrl}: Props) => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {LinearGradient} from 'expo-linear-gradient';
|
||||
import {LinearGradient, type LinearGradientProps} from 'expo-linear-gradient';
|
||||
import React, {useCallback, useMemo, useState} from 'react';
|
||||
import {FlatList, View, type ListRenderItemInfo, type NativeSyntheticEvent, type NativeScrollEvent} from 'react-native';
|
||||
import Animated from 'react-native-reanimated';
|
||||
|
|
@ -31,7 +31,7 @@ type Props = {
|
|||
separator?: boolean;
|
||||
}
|
||||
|
||||
const GRADIENT_LOCATIONS = [0, 0.64, 1];
|
||||
const GRADIENT_LOCATIONS: LinearGradientProps['locations'] = [0, 0.64, 1];
|
||||
const SCROLL_OFFSET = 10;
|
||||
|
||||
const isCloseToBottom = ({layoutMeasurement, contentOffset, contentSize}: NativeScrollEvent) => {
|
||||
|
|
@ -112,7 +112,7 @@ const ChannelBookmarks = ({
|
|||
setAllowEndFade(isCloseToBottom(e.nativeEvent));
|
||||
}, []);
|
||||
|
||||
const gradientColors = useMemo(() => [
|
||||
const gradientColors: LinearGradientProps['colors'] = useMemo(() => [
|
||||
theme.centerChannelBg,
|
||||
changeOpacity(theme.centerChannelBg, 0.6458),
|
||||
changeOpacity(theme.centerChannelBg, 0),
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@ import {useTheme} from '@context/theme';
|
|||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import type UserModel from '@typings/database/models/servers/user';
|
||||
import type {StyleProp, ViewStyle} from 'react-native';
|
||||
import type {StyleProp, TextStyle, ViewStyle} from 'react-native';
|
||||
|
||||
type Props = {
|
||||
authorId: string;
|
||||
author?: UserModel;
|
||||
isOnCenterBg?: boolean;
|
||||
style: StyleProp<ViewStyle>;
|
||||
style: StyleProp<Intersection<TextStyle, ViewStyle>>;
|
||||
size: number;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {type StyleProp, Text, View, type ViewStyle} from 'react-native';
|
||||
import {type StyleProp, Text, type TextStyle, View, type ViewStyle} from 'react-native';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
import General from '@constants/general';
|
||||
|
|
@ -23,7 +23,7 @@ type ChannelIconProps = {
|
|||
name: string;
|
||||
shared: boolean;
|
||||
size?: number;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
style?: StyleProp<Intersection<TextStyle, ViewStyle>>;
|
||||
testID?: string;
|
||||
type: string;
|
||||
};
|
||||
|
|
@ -125,12 +125,12 @@ const ChannelIcon = ({
|
|||
mutedStyle = styles.muted;
|
||||
}
|
||||
|
||||
const commonStyles = [
|
||||
const commonStyles: StyleProp<Intersection<TextStyle, ViewStyle>> = [
|
||||
style,
|
||||
mutedStyle,
|
||||
];
|
||||
|
||||
const commonIconStyles = [
|
||||
const commonIconStyles: StyleProp<TextStyle> = [
|
||||
styles.icon,
|
||||
unreadIcon,
|
||||
activeIcon,
|
||||
|
|
|
|||
|
|
@ -6,13 +6,13 @@ import React from 'react';
|
|||
import CustomStatusEmoji from '@components/custom_status/custom_status_emoji';
|
||||
|
||||
import type {EmojiCommonStyle} from '@typings/components/emoji';
|
||||
import type {StyleProp} from 'react-native';
|
||||
import type {StyleProp, TextStyle} from 'react-native';
|
||||
|
||||
type Props = {
|
||||
customStatus?: UserCustomStatus;
|
||||
customStatusExpired: boolean;
|
||||
isCustomStatusEnabled: boolean;
|
||||
style: StyleProp<EmojiCommonStyle>;
|
||||
style: StyleProp<Intersection<EmojiCommonStyle, TextStyle>>;
|
||||
}
|
||||
|
||||
const CustomStatus = ({customStatus, customStatusExpired, isCustomStatusEnabled, style}: Props) => {
|
||||
|
|
|
|||
|
|
@ -150,7 +150,7 @@ const ConnectionBanner = ({
|
|||
height.value = withTiming(visible ? ANNOUNCEMENT_BAR_HEIGHT : 0, {
|
||||
duration: 200,
|
||||
});
|
||||
}, [visible]);
|
||||
}, [height, visible]);
|
||||
|
||||
const bannerStyle = useAnimatedStyle(() => ({
|
||||
height: height.value,
|
||||
|
|
|
|||
|
|
@ -6,12 +6,12 @@ import React from 'react';
|
|||
import Emoji from '@components/emoji';
|
||||
|
||||
import type {EmojiCommonStyle} from '@typings/components/emoji';
|
||||
import type {StyleProp} from 'react-native';
|
||||
import type {StyleProp, TextStyle} from 'react-native';
|
||||
|
||||
interface ComponentProps {
|
||||
customStatus: UserCustomStatus;
|
||||
emojiSize?: number;
|
||||
style?: StyleProp<EmojiCommonStyle>;
|
||||
style?: StyleProp<Intersection<EmojiCommonStyle, TextStyle>>;
|
||||
}
|
||||
|
||||
const CustomStatusEmoji = ({customStatus, emojiSize = 16, style}: ComponentProps) => {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import {makeStyleSheetFromTheme} from '@utils/theme';
|
|||
type ErrorProps = {
|
||||
error: unknown;
|
||||
testID?: string;
|
||||
textStyle?: StyleProp<ViewStyle> | StyleProp<TextStyle>;
|
||||
textStyle?: StyleProp<Intersection<TextStyle, ViewStyle>> | StyleProp<TextStyle>;
|
||||
}
|
||||
|
||||
const ErrorTextComponent = ({error, testID, textStyle}: ErrorProps) => {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import React, {useEffect, useMemo, useState} from 'react';
|
||||
import {DeviceEventEmitter, type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native';
|
||||
import Animated, {useDerivedValue} from 'react-native-reanimated';
|
||||
import Animated from 'react-native-reanimated';
|
||||
|
||||
import {Events} from '@constants';
|
||||
import {GalleryInit} from '@context/gallery';
|
||||
|
|
@ -56,21 +56,21 @@ const Files = ({canDownloadFiles, failed, filesInfo, isReplyPost, layoutWidth, l
|
|||
|
||||
const {images: imageAttachments, nonImages: nonImageAttachments} = useImageAttachments(filesInfo, publicLinkEnabled);
|
||||
|
||||
const filesForGallery = useDerivedValue(() => imageAttachments.concat(nonImageAttachments),
|
||||
const filesForGallery = useMemo(() => imageAttachments.concat(nonImageAttachments),
|
||||
[imageAttachments, nonImageAttachments]);
|
||||
|
||||
const attachmentIndex = (fileId: string) => {
|
||||
return filesForGallery.value.findIndex((file) => file.id === fileId) || 0;
|
||||
return filesForGallery.findIndex((file) => file.id === fileId) || 0;
|
||||
};
|
||||
|
||||
const handlePreviewPress = preventDoubleTap((idx: number) => {
|
||||
const items = filesForGallery.value.map((f) => fileToGalleryItem(f, f.user_id, postProps));
|
||||
const items = filesForGallery.map((f) => fileToGalleryItem(f, f.user_id, postProps));
|
||||
openGalleryAtIndex(galleryIdentifier, idx, items);
|
||||
});
|
||||
|
||||
const updateFileForGallery = (idx: number, file: FileInfo) => {
|
||||
'worklet';
|
||||
filesForGallery.value[idx] = file;
|
||||
filesForGallery[idx] = file;
|
||||
};
|
||||
|
||||
const isSingleImage = useMemo(() => filesInfo.filter((f) => isImage(f) || isVideo(f)).length === 1, [filesInfo]);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {LinearGradient} from 'expo-linear-gradient';
|
||||
import {LinearGradient, type LinearGradientProps} from 'expo-linear-gradient';
|
||||
import React, {useCallback, useMemo, useState} from 'react';
|
||||
import {StyleSheet, useWindowDimensions, View} from 'react-native';
|
||||
|
||||
|
|
@ -30,9 +30,9 @@ type ImageFileProps = {
|
|||
|
||||
const SMALL_IMAGE_MAX_HEIGHT = 48;
|
||||
const SMALL_IMAGE_MAX_WIDTH = 48;
|
||||
const GRADIENT_COLORS = ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, .32)'];
|
||||
const GRADIENT_COLORS: LinearGradientProps['colors'] = ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, .32)'];
|
||||
const GRADIENT_END = {x: 1, y: 1};
|
||||
const GRADIENT_LOCATIONS = [0.5, 1];
|
||||
const GRADIENT_LOCATIONS: LinearGradientProps['locations'] = [0.5, 1];
|
||||
const GRADIENT_START = {x: 0.5, y: 0.5};
|
||||
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
|
|
|
|||
|
|
@ -274,7 +274,7 @@ const FloatingTextChipsInput = forwardRef<Ref, Props>(({
|
|||
>
|
||||
{label}
|
||||
</Animated.Text>
|
||||
<View style={textInputContainerStyles}>
|
||||
<View style={textInputContainerStyles as StyleProp<ViewStyle>}>
|
||||
{chipsValues && chipsValues?.length > 0 && chipsValues.map((chipValue) => (
|
||||
<SelectedChip
|
||||
key={chipValue}
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ const FloatingTextInput = forwardRef<FloatingTextInputRef, FloatingTextInputProp
|
|||
>
|
||||
{label}
|
||||
</Animated.Text>
|
||||
<View style={combinedTextInputContainerStyle}>
|
||||
<View style={combinedTextInputContainerStyle as StyleProp<ViewStyle>}>
|
||||
<TextInput
|
||||
{...props}
|
||||
editable={isKeyboardInput && editable}
|
||||
|
|
|
|||
|
|
@ -114,7 +114,7 @@ const FormattedMarkdownText = ({baseTextStyle, channelId, defaultMessage, id, lo
|
|||
};
|
||||
|
||||
const renderParagraph = ({children, first}: {children: ReactElement; first: boolean}) => {
|
||||
const blockStyle: StyleProp<ViewStyle> = [styles.block];
|
||||
const blockStyle: StyleProp<Intersection<TextStyle, ViewStyle>> = [styles.block];
|
||||
if (!first) {
|
||||
const blockS = getMarkdownBlockStyles(theme);
|
||||
blockStyle.push(blockS.adjacentParagraph);
|
||||
|
|
|
|||
|
|
@ -332,7 +332,7 @@ const Markdown = ({
|
|||
|
||||
return (
|
||||
<View
|
||||
style={containerStyle}
|
||||
style={containerStyle as StyleProp<ViewStyle>}
|
||||
testID='markdown_heading'
|
||||
>
|
||||
<Text style={textStyle}>
|
||||
|
|
|
|||
|
|
@ -2,13 +2,13 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {type ReactNode} from 'react';
|
||||
import {StyleSheet, type TextStyle, View, type ViewStyle} from 'react-native';
|
||||
import {type StyleProp, StyleSheet, type TextStyle, View, type ViewStyle} from 'react-native';
|
||||
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
|
||||
type MarkdownBlockQuoteProps = {
|
||||
continueBlock?: boolean;
|
||||
iconStyle: ViewStyle | TextStyle;
|
||||
iconStyle: StyleProp<Intersection<ViewStyle, TextStyle>>;
|
||||
children: ReactNode | ReactNode[];
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ const NavigationHeaderLargeTitle = ({
|
|||
|
||||
const containerStyle = useMemo(() => {
|
||||
return [{height: heightOffset}, styles.container];
|
||||
}, [heightOffset, theme]);
|
||||
}, [heightOffset, styles.container]);
|
||||
|
||||
return (
|
||||
<Animated.View style={[containerStyle, transform]}>
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ const AnimatedOptionBox = ({
|
|||
animate.value = withTiming(1, {duration: 150, easing: Easing.out(Easing.linear)});
|
||||
setActivated(true);
|
||||
onPress();
|
||||
}, [onPress]);
|
||||
}, [animate, onPress]);
|
||||
|
||||
const backgroundStyle = useAnimatedStyle(() => ({
|
||||
backgroundColor: interpolateColor(
|
||||
|
|
@ -111,7 +111,7 @@ const AnimatedOptionBox = ({
|
|||
clearTimeout(t);
|
||||
}
|
||||
};
|
||||
}, [activated, animate.value, onAnimationEnd]);
|
||||
}, [activated, animate, onAnimationEnd]);
|
||||
|
||||
return (
|
||||
<AnimatedPressable
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
|||
|
||||
export type OptionItemProps = {
|
||||
action?: (React.Dispatch<React.SetStateAction<string | boolean>>)|((value: string | boolean) => void);
|
||||
arrowStyle?: StyleProp<ViewStyle>;
|
||||
arrowStyle?: StyleProp<Intersection<TextStyle, ViewStyle>>;
|
||||
containerStyle?: StyleProp<ViewStyle>;
|
||||
description?: string;
|
||||
destructive?: boolean;
|
||||
|
|
|
|||
|
|
@ -121,7 +121,7 @@ function Typing({
|
|||
|
||||
useEffect(() => {
|
||||
typingHeight.value = typing.current.length ? TYPING_HEIGHT : 0;
|
||||
}, [refresh]);
|
||||
}, [refresh, typingHeight]);
|
||||
|
||||
useEffect(() => {
|
||||
typing.current = [];
|
||||
|
|
@ -130,7 +130,7 @@ function Typing({
|
|||
clearTimeout(timeoutToDisappear.current);
|
||||
timeoutToDisappear.current = undefined;
|
||||
}
|
||||
}, [channelId, rootId]);
|
||||
}, [channelId, rootId, typingHeight]);
|
||||
|
||||
const renderTyping = () => {
|
||||
const nextTyping = typing.current.map(({username}) => username);
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ function Uploads({
|
|||
const errorHeight = useSharedValue(ERROR_HEIGHT_MIN);
|
||||
const containerHeight = useSharedValue(files.length ? CONTAINER_HEIGHT_MAX : CONTAINER_HEIGHT_MIN);
|
||||
const filesForGallery = useRef(files.filter((f) => !f.failed && !DraftUploadManager.isUploading(f.clientId!)));
|
||||
const hasFiles = files.length > 0;
|
||||
|
||||
const errorAnimatedStyle = useAnimatedStyle(() => {
|
||||
return {
|
||||
|
|
@ -109,21 +110,21 @@ function Uploads({
|
|||
} else {
|
||||
errorHeight.value = ERROR_HEIGHT_MIN;
|
||||
}
|
||||
}, [uploadFileError]);
|
||||
}, [errorHeight, uploadFileError]);
|
||||
|
||||
useEffect(() => {
|
||||
if (files.length) {
|
||||
if (hasFiles) {
|
||||
containerHeight.value = CONTAINER_HEIGHT_MAX;
|
||||
return;
|
||||
}
|
||||
containerHeight.value = CONTAINER_HEIGHT_MIN;
|
||||
}, [files.length > 0]);
|
||||
}, [containerHeight, hasFiles]);
|
||||
|
||||
const openGallery = useCallback((file: FileInfo) => {
|
||||
const items = filesForGallery.current.map((f) => fileToGalleryItem(f, currentUserId));
|
||||
const index = filesForGallery.current.findIndex((f) => f.clientId === file.clientId);
|
||||
openGalleryAtIndex(galleryIdentifier, index, items, true);
|
||||
}, [currentUserId, files]);
|
||||
}, [currentUserId, galleryIdentifier]);
|
||||
|
||||
const buildFilePreviews = () => {
|
||||
return files.map((file, index) => {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React from 'react';
|
||||
import {type StyleProp, View, type ViewStyle} from 'react-native';
|
||||
import {type StyleProp, type TextStyle, View, type ViewStyle} from 'react-native';
|
||||
|
||||
import FormattedDate, {type FormattedDateFormat} from '@components/formatted_date';
|
||||
import FormattedText from '@components/formatted_text';
|
||||
|
|
@ -13,7 +13,7 @@ import {typography} from '@utils/typography';
|
|||
|
||||
type DateSeparatorProps = {
|
||||
date: number | Date;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
style?: StyleProp<Intersection<TextStyle, ViewStyle>>;
|
||||
timezone?: string | null;
|
||||
};
|
||||
|
||||
|
|
@ -81,7 +81,7 @@ const DateSeparator = (props: DateSeparatorProps) => {
|
|||
const styles = getStyleSheet(theme);
|
||||
|
||||
return (
|
||||
<View style={[styles.container, props.style]}>
|
||||
<View style={[styles.container, props.style as StyleProp<ViewStyle>]}>
|
||||
<View style={styles.line}/>
|
||||
<RecentDate
|
||||
{...props}
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ const MoreMessages = ({
|
|||
top.value = 0;
|
||||
resetMessageCount(serverUrl, channelId);
|
||||
pressed.current = false;
|
||||
}, [serverUrl, channelId]);
|
||||
}, [top, serverUrl, channelId]);
|
||||
|
||||
const onPress = useCallback(() => {
|
||||
if (pressed.current) {
|
||||
|
|
@ -223,7 +223,7 @@ const MoreMessages = ({
|
|||
|
||||
pressed.current = true;
|
||||
scrollToIndex(newMessageLineIndex, true);
|
||||
}, [newMessageLineIndex]);
|
||||
}, [newMessageLineIndex, scrollToIndex]);
|
||||
|
||||
useDidUpdate(() => {
|
||||
setLoading(EphemeralStore.isLoadingMessagesForChannel(serverUrl, channelId));
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {LinearGradient} from 'expo-linear-gradient';
|
||||
import {LinearGradient, type LinearGradientProps} from 'expo-linear-gradient';
|
||||
import React from 'react';
|
||||
import {TouchableOpacity, View} from 'react-native';
|
||||
|
||||
|
|
@ -74,7 +74,7 @@ const ShowMoreButton = ({highlight, onPress, showMore = true, theme}: ShowMoreBu
|
|||
iconName = 'chevron-up';
|
||||
}
|
||||
|
||||
let gradientColors = [
|
||||
let gradientColors: LinearGradientProps['colors'] = [
|
||||
changeOpacity(theme.centerChannelBg, 0),
|
||||
changeOpacity(theme.centerChannelBg, 0.75),
|
||||
theme.centerChannelBg,
|
||||
|
|
|
|||
|
|
@ -117,20 +117,13 @@ const PostList = ({
|
|||
const serverUrl = useServerUrl();
|
||||
const orderedPosts = useMemo(() => {
|
||||
return preparePostList(posts, lastViewedAt, showNewMessageLine, currentUserId, currentUsername, shouldShowJoinLeaveMessages, currentTimezone, location === Screens.THREAD, savedPostIds);
|
||||
}, [posts, lastViewedAt, showNewMessageLine, currentTimezone, currentUsername, shouldShowJoinLeaveMessages, location, savedPostIds]);
|
||||
}, [posts, lastViewedAt, showNewMessageLine, currentUserId, currentUsername, shouldShowJoinLeaveMessages, currentTimezone, location, savedPostIds]);
|
||||
|
||||
const initialIndex = useMemo(() => {
|
||||
return orderedPosts.findIndex((i) => i.type === 'start-of-new-messages');
|
||||
}, [orderedPosts]);
|
||||
|
||||
const isNewMessage = useMemo(() => {
|
||||
if (!lastPostId) {
|
||||
// Avoid flash when the channel loads without posts
|
||||
// e.g. The first time we navigate to a channel
|
||||
return false;
|
||||
}
|
||||
return posts[0]?.id !== lastPostId;
|
||||
}, [posts[0]?.id, lastPostId]);
|
||||
const isNewMessage = lastPostId ? posts[0]?.id !== lastPostId : false;
|
||||
|
||||
useEffect(() => {
|
||||
const t = setTimeout(() => {
|
||||
|
|
@ -266,7 +259,6 @@ const PostList = ({
|
|||
case 'user-activity': {
|
||||
const postProps = {
|
||||
currentUsername,
|
||||
key: item.value,
|
||||
postId: item.value,
|
||||
location,
|
||||
style: styles.container,
|
||||
|
|
@ -275,7 +267,11 @@ const PostList = ({
|
|||
theme,
|
||||
};
|
||||
|
||||
return (<CombinedUserActivity {...postProps}/>);
|
||||
return (
|
||||
<CombinedUserActivity
|
||||
{...postProps}
|
||||
key={item.value}
|
||||
/>);
|
||||
}
|
||||
default: {
|
||||
const post = item.value.currentPost;
|
||||
|
|
@ -289,7 +285,6 @@ const PostList = ({
|
|||
highlight: highlightedId === post.id,
|
||||
highlightPinnedOrSaved,
|
||||
isSaved,
|
||||
key: post.id,
|
||||
location,
|
||||
nextPost,
|
||||
post,
|
||||
|
|
@ -300,10 +295,15 @@ const PostList = ({
|
|||
testID: `${testID}.post`,
|
||||
};
|
||||
|
||||
return (<Post {...postProps}/>);
|
||||
return (
|
||||
<Post
|
||||
{...postProps}
|
||||
key={post.id}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
}, [appsEnabled, currentTimezone, customEmojiNames, highlightPinnedOrSaved, isCRTEnabled, isPostAcknowledgementEnabled, shouldRenderReplyButton, theme]);
|
||||
}, [appsEnabled, currentTimezone, currentUsername, customEmojiNames, highlightPinnedOrSaved, highlightedId, isCRTEnabled, isPostAcknowledgementEnabled, location, rootId, shouldRenderReplyButton, shouldShowJoinLeaveMessages, testID, theme]);
|
||||
|
||||
const scrollToIndex = useCallback((index: number, animated = true, applyOffset = true) => {
|
||||
listRef.current?.scrollToIndex({
|
||||
|
|
|
|||
|
|
@ -61,6 +61,14 @@ exports[`ThreadOverview should match snapshot when post is saved and has replies
|
|||
onGestureHandlerStateChange={[Function]}
|
||||
onHandlerStateChange={[Function]}
|
||||
rippleColor={0}
|
||||
style={
|
||||
[
|
||||
undefined,
|
||||
{
|
||||
"cursor": undefined,
|
||||
},
|
||||
]
|
||||
}
|
||||
testID="thread-overview.save.button"
|
||||
touchSoundDisabled={false}
|
||||
>
|
||||
|
|
@ -94,6 +102,14 @@ exports[`ThreadOverview should match snapshot when post is saved and has replies
|
|||
onGestureHandlerStateChange={[Function]}
|
||||
onHandlerStateChange={[Function]}
|
||||
rippleColor={0}
|
||||
style={
|
||||
[
|
||||
undefined,
|
||||
{
|
||||
"cursor": undefined,
|
||||
},
|
||||
]
|
||||
}
|
||||
testID="thread-overview.post_options.button"
|
||||
touchSoundDisabled={false}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import Animated from 'react-native-reanimated';
|
|||
import {useTheme} from '@context/theme';
|
||||
import {changeOpacity, makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
const AnimatedImageBackground = Animated.createAnimatedComponent(ImageBackground);
|
||||
const AnimatedImage = Animated.createAnimatedComponent(Image);
|
||||
|
||||
type Props = ProgressiveImageProps & {
|
||||
|
|
@ -55,14 +54,14 @@ const ProgressiveImage = ({
|
|||
if (isBackgroundImage && imageUri) {
|
||||
return (
|
||||
<View style={[styles.defaultImageContainer, style]}>
|
||||
<AnimatedImageBackground
|
||||
<ImageBackground
|
||||
key={id}
|
||||
source={{uri: imageUri}}
|
||||
contentFit='cover'
|
||||
style={[StyleSheet.absoluteFill, imageStyle]}
|
||||
style={[StyleSheet.absoluteFill, imageStyle as StyleProp<ViewStyle>]}
|
||||
>
|
||||
{children}
|
||||
</AnimatedImageBackground>
|
||||
</ImageBackground>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useMemo} from 'react';
|
||||
import {type StyleProp, StyleSheet, View, type ViewStyle} from 'react-native';
|
||||
import {type StyleProp, StyleSheet, type TextStyle, View, type ViewStyle} from 'react-native';
|
||||
|
||||
import Badge from '@components/badge';
|
||||
import CompassIcon from '@components/compass_icon';
|
||||
|
|
@ -14,7 +14,7 @@ type Props = {
|
|||
badgeBackgroundColor?: string;
|
||||
badgeBorderColor?: string;
|
||||
badgeColor?: string;
|
||||
badgeStyle?: StyleProp<ViewStyle>;
|
||||
badgeStyle?: StyleProp<TextStyle>;
|
||||
hasUnreads: boolean;
|
||||
iconColor?: string;
|
||||
mentionCount: number;
|
||||
|
|
@ -22,7 +22,7 @@ type Props = {
|
|||
size?: number;
|
||||
style?: StyleProp<ViewStyle>;
|
||||
testID?: string;
|
||||
unreadStyle?: StyleProp<ViewStyle>;
|
||||
unreadStyle?: StyleProp<TextStyle>;
|
||||
}
|
||||
|
||||
const hitSlop = {top: 20, bottom: 5, left: 40, right: 20};
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ export default schemaMigrations({migrations: [
|
|||
{
|
||||
toVersion: 6,
|
||||
steps: [
|
||||
unsafeExecuteSql('CREATE INDEX IF NOT EXISTS Post_type ON Post (type)'),
|
||||
unsafeExecuteSql('CREATE INDEX IF NOT EXISTS Post_type ON Post (type);'),
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import {renderHook} from '@testing-library/react-hooks';
|
||||
import {act} from '@testing-library/react-native';
|
||||
|
||||
|
|
@ -12,10 +13,6 @@ const LARGE_HEADER_TITLE_HEIGHT = 128;
|
|||
const HEADER_OFFSET = LARGE_HEADER_TITLE_HEIGHT - ViewConstants.DEFAULT_HEADER_HEIGHT;
|
||||
|
||||
describe('useCollapsibleHeader', () => {
|
||||
afterEach(() => {
|
||||
jest.resetAllMocks();
|
||||
});
|
||||
|
||||
const commonHookResponse = {
|
||||
largeHeight: LARGE_HEADER_TITLE_HEIGHT,
|
||||
scrollRef: {current: null},
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ export const setServerCredentials = (serverUrl: string, token: string) => {
|
|||
accessGroup = appGroup.appGroupIdentifier;
|
||||
}
|
||||
|
||||
const options: KeyChain.Options = {
|
||||
const options: KeyChain.SetOptions = {
|
||||
accessGroup,
|
||||
securityLevel: KeyChain.SECURITY_LEVEL.SECURE_SOFTWARE,
|
||||
};
|
||||
|
|
@ -67,16 +67,7 @@ export const setServerCredentials = (serverUrl: string, token: string) => {
|
|||
};
|
||||
|
||||
export const removeServerCredentials = async (serverUrl: string) => {
|
||||
const options: KeyChain.Options = {
|
||||
securityLevel: KeyChain.SECURITY_LEVEL.SECURE_SOFTWARE,
|
||||
};
|
||||
|
||||
if (Platform.OS === 'ios') {
|
||||
const appGroup = getIOSAppGroupDetails();
|
||||
options.accessGroup = appGroup.appGroupIdentifier;
|
||||
}
|
||||
|
||||
await KeyChain.resetInternetCredentials(serverUrl, options);
|
||||
return KeyChain.resetInternetCredentials(serverUrl);
|
||||
};
|
||||
|
||||
export const removeActiveServerCredentials = async () => {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import type {CurrentCall} from '@calls/types/calls';
|
|||
|
||||
type Props = {
|
||||
pressableStyle: StyleProp<ViewStyle>;
|
||||
iconStyle: StyleProp<ViewStyle>;
|
||||
iconStyle: StyleProp<TextStyle>;
|
||||
buttonTextStyle: StyleProp<TextStyle>;
|
||||
currentCall: CurrentCall;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import {makeStyleSheetFromTheme} from '@utils/theme';
|
|||
|
||||
type Props = {
|
||||
pressableStyle: StyleProp<ViewStyle>;
|
||||
iconStyle: StyleProp<ViewStyle>;
|
||||
iconStyle: StyleProp<TextStyle>;
|
||||
buttonTextStyle: StyleProp<TextStyle>;
|
||||
currentCall: CurrentCall;
|
||||
}
|
||||
|
|
@ -33,7 +33,6 @@ export const AudioDeviceButton = ({pressableStyle, iconStyle, buttonTextStyle, c
|
|||
const theme = useTheme();
|
||||
const style = getStyleFromTheme(theme);
|
||||
const isTablet = Device.IS_TABLET; // not `useIsTablet` because even if we're in splitView, we're still using a tablet.
|
||||
const color = theme.awayIndicator;
|
||||
const audioDeviceInfo = currentCall.audioDeviceInfo;
|
||||
const phoneLabel = intl.formatMessage({id: 'mobile.calls_phone', defaultMessage: 'Phone'});
|
||||
const tabletLabel = intl.formatMessage({id: 'mobile.calls_tablet', defaultMessage: 'Tablet'});
|
||||
|
|
@ -111,7 +110,11 @@ export const AudioDeviceButton = ({pressableStyle, iconStyle, buttonTextStyle, c
|
|||
title: intl.formatMessage({id: 'mobile.calls_audio_device', defaultMessage: 'Select audio device'}),
|
||||
theme,
|
||||
});
|
||||
}, [setPreferredAudioRoute, audioDeviceInfo, color]);
|
||||
}, [
|
||||
audioDeviceInfo.selectedAudioDevice, audioDeviceInfo.availableAudioDeviceList,
|
||||
intl, theme, isTablet, tabletLabel, style.checkIcon,
|
||||
phoneLabel, speakerLabel, bluetoothLabel, headsetLabel,
|
||||
]);
|
||||
|
||||
let icon = 'volume-high';
|
||||
let label = speakerLabel;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useMemo} from 'react';
|
||||
import React, {useCallback, useMemo} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {Pressable, Text, View} from 'react-native';
|
||||
import Permissions from 'react-native-permissions';
|
||||
|
|
@ -99,6 +99,10 @@ const MessageBar = ({type, onDismiss}: Props) => {
|
|||
const style = getStyleSheet(callsTheme);
|
||||
const warning = type === Calls.MessageBarType.CallQuality;
|
||||
|
||||
const onPress = useCallback(() => {
|
||||
Permissions.openSettings();
|
||||
}, []);
|
||||
|
||||
let message = '';
|
||||
let icon = <></>;
|
||||
switch (type) {
|
||||
|
|
@ -129,7 +133,7 @@ const MessageBar = ({type, onDismiss}: Props) => {
|
|||
return (
|
||||
<View style={[style.outerContainer, warning && style.outerContainerWarning]}>
|
||||
<Pressable
|
||||
onPress={Permissions.openSettings}
|
||||
onPress={onPress}
|
||||
style={[style.innerContainer, warning && style.innerContainerWarning]}
|
||||
>
|
||||
<View style={style.iconContainer}>
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import BottomSheetM, {BottomSheetBackdrop, type BottomSheetBackdropProps} from '@gorhom/bottom-sheet';
|
||||
import BottomSheetM, {BottomSheetBackdrop, BottomSheetView, type BottomSheetBackdropProps} from '@gorhom/bottom-sheet';
|
||||
import React, {type ReactNode, useCallback, useEffect, useMemo, useRef} from 'react';
|
||||
import {DeviceEventEmitter, type Handle, InteractionManager, Keyboard, type StyleProp, View, type ViewStyle} from 'react-native';
|
||||
import {ReduceMotion, type WithSpringConfig} from 'react-native-reanimated';
|
||||
|
|
@ -71,6 +71,9 @@ export const getStyleSheet = makeStyleSheetFromTheme((theme: Theme) => {
|
|||
borderTopWidth: 1,
|
||||
borderColor: changeOpacity(theme.centerChannelColor, 0.08),
|
||||
},
|
||||
view: {
|
||||
flex: 1,
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
|
|
@ -221,8 +224,11 @@ const BottomSheet = ({
|
|||
keyboardBlurBehavior='restore'
|
||||
onClose={close}
|
||||
bottomInset={insets.bottom}
|
||||
enableDynamicSizing={false}
|
||||
>
|
||||
{renderContainerContent()}
|
||||
<BottomSheetView style={styles.view}>
|
||||
{renderContainerContent()}
|
||||
</BottomSheetView>
|
||||
</BottomSheetM>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
import {useHardwareKeyboardEvents} from '@mattermost/hardware-keyboard';
|
||||
import {createBottomTabNavigator, type BottomTabBarProps} from '@react-navigation/bottom-tabs';
|
||||
import {NavigationContainer} from '@react-navigation/native';
|
||||
import {NavigationContainer, DefaultTheme} from '@react-navigation/native';
|
||||
import React, {useCallback, useEffect, useMemo} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {DeviceEventEmitter, Platform} from 'react-native';
|
||||
|
|
@ -139,8 +139,10 @@ export function HomeScreen(props: HomeProps) {
|
|||
<>
|
||||
<NavigationContainer
|
||||
theme={{
|
||||
...DefaultTheme,
|
||||
dark: false,
|
||||
colors: {
|
||||
...DefaultTheme.colors,
|
||||
primary: theme.centerChannelColor,
|
||||
background: 'transparent',
|
||||
card: theme.centerChannelBg,
|
||||
|
|
@ -151,7 +153,7 @@ export function HomeScreen(props: HomeProps) {
|
|||
}}
|
||||
>
|
||||
<Tab.Navigator
|
||||
screenOptions={{headerShown: false, unmountOnBlur: false, lazy: true}}
|
||||
screenOptions={{headerShown: false, freezeOnBlur: false, lazy: true}}
|
||||
backBehavior='none'
|
||||
tabBar={(tabProps: BottomTabBarProps) => (
|
||||
<TabBar
|
||||
|
|
@ -161,29 +163,29 @@ export function HomeScreen(props: HomeProps) {
|
|||
>
|
||||
<Tab.Screen
|
||||
name={Screens.HOME}
|
||||
options={{tabBarTestID: 'tab_bar.home.tab', unmountOnBlur: false, freezeOnBlur: true}}
|
||||
options={{tabBarButtonTestID: 'tab_bar.home.tab', freezeOnBlur: true}}
|
||||
>
|
||||
{() => <ChannelList {...props}/>}
|
||||
</Tab.Screen>
|
||||
<Tab.Screen
|
||||
name={Screens.SEARCH}
|
||||
component={Search}
|
||||
options={{tabBarTestID: 'tab_bar.search.tab', unmountOnBlur: false, freezeOnBlur: true, lazy: true}}
|
||||
options={{tabBarButtonTestID: 'tab_bar.search.tab', freezeOnBlur: true, lazy: true}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name={Screens.MENTIONS}
|
||||
component={RecentMentions}
|
||||
options={{tabBarTestID: 'tab_bar.mentions.tab', freezeOnBlur: true, lazy: true}}
|
||||
options={{tabBarButtonTestID: 'tab_bar.mentions.tab', freezeOnBlur: true, lazy: true}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name={Screens.SAVED_MESSAGES}
|
||||
component={SavedMessages}
|
||||
options={{tabBarTestID: 'tab_bar.saved_messages.tab', freezeOnBlur: true, lazy: true}}
|
||||
options={{tabBarButtonTestID: 'tab_bar.saved_messages.tab', freezeOnBlur: true, lazy: true}}
|
||||
/>
|
||||
<Tab.Screen
|
||||
name={Screens.ACCOUNT}
|
||||
component={Account}
|
||||
options={{tabBarTestID: 'tab_bar.account.tab', freezeOnBlur: true, lazy: true}}
|
||||
options={{tabBarButtonTestID: 'tab_bar.account.tab', freezeOnBlur: true, lazy: true}}
|
||||
/>
|
||||
</Tab.Navigator>
|
||||
</NavigationContainer>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import {useIsFocused, useRoute} from '@react-navigation/native';
|
||||
import React, {useCallback, useState, useEffect, useMemo} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {ActivityIndicator, DeviceEventEmitter, FlatList, type ListRenderItemInfo, StyleSheet, View} from 'react-native';
|
||||
import {ActivityIndicator, DeviceEventEmitter, type ListRenderItemInfo, View} from 'react-native';
|
||||
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
|
||||
import {SafeAreaView, type Edge} from 'react-native-safe-area-context';
|
||||
|
||||
|
|
@ -19,13 +19,13 @@ import {useServerUrl} from '@context/server';
|
|||
import {useTheme} from '@context/theme';
|
||||
import {useCollapsibleHeader} from '@hooks/header';
|
||||
import {getDateForDateLine, selectOrderedPosts} from '@utils/post_list';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import EmptyState from './components/empty';
|
||||
|
||||
import type {PostListItem, PostListOtherItem, ViewableItemsChanged} from '@typings/components/post_list';
|
||||
import type PostModel from '@typings/database/models/servers/post';
|
||||
|
||||
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
|
||||
const EDGES: Edge[] = ['bottom', 'left', 'right'];
|
||||
|
||||
type Props = {
|
||||
|
|
@ -35,9 +35,10 @@ type Props = {
|
|||
mentions: PostModel[];
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => ({
|
||||
flex: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
|
|
@ -47,7 +48,7 @@ const styles = StyleSheet.create({
|
|||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
const RecentMentionsScreen = ({appsEnabled, customEmojiNames, mentions, currentTimezone}: Props) => {
|
||||
const theme = useTheme();
|
||||
|
|
@ -57,6 +58,7 @@ const RecentMentionsScreen = ({appsEnabled, customEmojiNames, mentions, currentT
|
|||
const [refreshing, setRefreshing] = useState(false);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const serverUrl = useServerUrl();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
const params = route.params as {direction: string};
|
||||
const toLeft = params.direction === 'left';
|
||||
|
|
@ -85,7 +87,7 @@ const RecentMentionsScreen = ({appsEnabled, customEmojiNames, mentions, currentT
|
|||
}
|
||||
}, [serverUrl, isFocused]);
|
||||
|
||||
const {scrollPaddingTop, scrollRef, scrollValue, onScroll, headerHeight} = useCollapsibleHeader<FlatList<string>>(true, onSnap);
|
||||
const {scrollPaddingTop, scrollRef, scrollValue, onScroll, headerHeight} = useCollapsibleHeader<Animated.FlatList<string>>(true, onSnap);
|
||||
const paddingTop = useMemo(() => ({paddingTop: scrollPaddingTop, flexGrow: 1}), [scrollPaddingTop]);
|
||||
const posts = useMemo(() => selectOrderedPosts(mentions, 0, false, '', '', false, currentTimezone, false).reverse(), [mentions]);
|
||||
|
||||
|
|
@ -181,7 +183,7 @@ const RecentMentionsScreen = ({appsEnabled, customEmojiNames, mentions, currentT
|
|||
<Animated.View style={top}>
|
||||
<RoundedHeaderContext/>
|
||||
</Animated.View>
|
||||
<AnimatedFlatList
|
||||
<Animated.FlatList
|
||||
ref={scrollRef}
|
||||
contentContainerStyle={paddingTop}
|
||||
ListEmptyComponent={renderEmptyList()}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
import {useIsFocused, useRoute} from '@react-navigation/native';
|
||||
import React, {useCallback, useEffect, useMemo, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {DeviceEventEmitter, FlatList, type ListRenderItemInfo, StyleSheet, View} from 'react-native';
|
||||
import {DeviceEventEmitter, type ListRenderItemInfo, View} from 'react-native';
|
||||
import Animated, {useAnimatedStyle, useSharedValue, withTiming} from 'react-native-reanimated';
|
||||
import {type Edge, SafeAreaView} from 'react-native-safe-area-context';
|
||||
|
||||
|
|
@ -20,6 +20,7 @@ import {useServerUrl} from '@context/server';
|
|||
import {useTheme} from '@context/theme';
|
||||
import {useCollapsibleHeader} from '@hooks/header';
|
||||
import {getDateForDateLine, selectOrderedPosts} from '@utils/post_list';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import EmptyState from './components/empty';
|
||||
|
||||
|
|
@ -33,12 +34,12 @@ type Props = {
|
|||
posts: PostModel[];
|
||||
}
|
||||
|
||||
const AnimatedFlatList = Animated.createAnimatedComponent(FlatList);
|
||||
const edges: Edge[] = ['bottom', 'left', 'right'];
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => ({
|
||||
flex: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
container: {
|
||||
flex: 1,
|
||||
|
|
@ -48,7 +49,7 @@ const styles = StyleSheet.create({
|
|||
flex: 1,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
function SavedMessages({appsEnabled, posts, currentTimezone, customEmojiNames}: Props) {
|
||||
const intl = useIntl();
|
||||
|
|
@ -58,6 +59,7 @@ function SavedMessages({appsEnabled, posts, currentTimezone, customEmojiNames}:
|
|||
const serverUrl = useServerUrl();
|
||||
const route = useRoute();
|
||||
const isFocused = useIsFocused();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
const params = route.params as {direction: string};
|
||||
const toLeft = params.direction === 'left';
|
||||
|
|
@ -86,7 +88,7 @@ function SavedMessages({appsEnabled, posts, currentTimezone, customEmojiNames}:
|
|||
}
|
||||
}, [serverUrl, isFocused]);
|
||||
|
||||
const {scrollPaddingTop, scrollRef, scrollValue, onScroll, headerHeight} = useCollapsibleHeader<FlatList<string>>(true, onSnap);
|
||||
const {scrollPaddingTop, scrollRef, scrollValue, onScroll, headerHeight} = useCollapsibleHeader<Animated.FlatList<string>>(true, onSnap);
|
||||
const paddingTop = useMemo(() => ({paddingTop: scrollPaddingTop, flexGrow: 1}), [scrollPaddingTop]);
|
||||
const data = useMemo(() => selectOrderedPosts(posts, 0, false, '', '', false, currentTimezone, false).reverse(), [posts]);
|
||||
|
||||
|
|
@ -183,7 +185,7 @@ function SavedMessages({appsEnabled, posts, currentTimezone, customEmojiNames}:
|
|||
<Animated.View style={top}>
|
||||
<RoundedHeaderContext/>
|
||||
</Animated.View>
|
||||
<AnimatedFlatList
|
||||
<Animated.FlatList
|
||||
ref={scrollRef}
|
||||
contentContainerStyle={paddingTop}
|
||||
ListEmptyComponent={emptyList}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import {useHardwareKeyboardEvents} from '@mattermost/hardware-keyboard';
|
|||
import {useIsFocused, useNavigation} from '@react-navigation/native';
|
||||
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {FlatList, type LayoutChangeEvent, Platform, StyleSheet, type ViewStyle, KeyboardAvoidingView, Keyboard} from 'react-native';
|
||||
import {FlatList, type LayoutChangeEvent, Platform, type ViewStyle, KeyboardAvoidingView, Keyboard} from 'react-native';
|
||||
import Animated, {useAnimatedStyle, useDerivedValue, withTiming, type AnimatedStyle} from 'react-native-reanimated';
|
||||
import {type Edge, SafeAreaView, useSafeAreaInsets} from 'react-native-safe-area-context';
|
||||
|
||||
|
|
@ -27,6 +27,7 @@ import {useCollapsibleHeader} from '@hooks/header';
|
|||
import NavigationStore from '@store/navigation_store';
|
||||
import {type FileFilter, FileFilters, filterFileExtensions} from '@utils/file';
|
||||
import {TabTypes, type TabType} from '@utils/search';
|
||||
import {makeStyleSheetFromTheme} from '@utils/theme';
|
||||
|
||||
import Initial from './initial';
|
||||
import Results from './results';
|
||||
|
|
@ -52,9 +53,10 @@ type Props = {
|
|||
teams: TeamModel[];
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
const getStyleSheet = makeStyleSheetFromTheme((theme) => ({
|
||||
flex: {
|
||||
flex: 1,
|
||||
backgroundColor: theme.centerChannelBg,
|
||||
},
|
||||
loading: {
|
||||
flex: 1,
|
||||
|
|
@ -63,7 +65,7 @@ const styles = StyleSheet.create({
|
|||
autocompleteContainer: {
|
||||
zIndex: 11,
|
||||
},
|
||||
});
|
||||
}));
|
||||
|
||||
const getSearchParams = (terms: string, filterValue?: FileFilter) => {
|
||||
const fileExtensions = filterFileExtensions(filterValue);
|
||||
|
|
@ -84,6 +86,7 @@ const SearchScreen = ({teamId, teams}: Props) => {
|
|||
const theme = useTheme();
|
||||
const insets = useSafeAreaInsets();
|
||||
const keyboardHeight = useKeyboardHeight();
|
||||
const styles = getStyleSheet(theme);
|
||||
|
||||
const stateIndex = nav.getState()?.index;
|
||||
const serverUrl = useServerUrl();
|
||||
|
|
@ -114,17 +117,9 @@ const SearchScreen = ({teamId, teams}: Props) => {
|
|||
setSearchTeamId(teamId);
|
||||
}, [teamId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (searchTerm) {
|
||||
resetToInitial();
|
||||
setSearchValue(searchTerm);
|
||||
handleSearch(searchTeamId, searchTerm);
|
||||
}
|
||||
}, [searchTerm]);
|
||||
|
||||
const onSnap = (offset: number, animated = true) => {
|
||||
const onSnap = useCallback((offset: number, animated = true) => {
|
||||
scrollRef.current?.scrollToOffset({offset, animated});
|
||||
};
|
||||
}, []);
|
||||
|
||||
const onSnapWithTimeout = useCallback((offset: number, animated = true) => {
|
||||
// wait until the keyboard is completely dismissed before scrolling to where the header should be
|
||||
|
|
@ -203,7 +198,7 @@ const SearchScreen = ({teamId, teams}: Props) => {
|
|||
setFileChannelIds(channels?.length ? channels : emptyChannelIds);
|
||||
handleLoading(false);
|
||||
setShowResults(true);
|
||||
}, [filter, handleClearSearch, handleLoading]);
|
||||
}, [filter, handleClearSearch, handleLoading, hideHeader, serverUrl]);
|
||||
|
||||
const onBlur = useCallback(() => {
|
||||
setSearchIsFocused(false);
|
||||
|
|
@ -233,7 +228,7 @@ const SearchScreen = ({teamId, teams}: Props) => {
|
|||
setFileInfos(files?.length ? files : emptyFileResults);
|
||||
setFileChannelIds(channels?.length ? channels : emptyChannelIds);
|
||||
setResultsLoading(false);
|
||||
}, [lastSearchedValue, searchTeamId]);
|
||||
}, [lastSearchedValue, searchTeamId, serverUrl]);
|
||||
|
||||
const handleResultsTeamChange = useCallback((newTeamId: string) => {
|
||||
setSearchTeamId(newTeamId);
|
||||
|
|
@ -267,8 +262,11 @@ const SearchScreen = ({teamId, teams}: Props) => {
|
|||
teams={teams}
|
||||
/>
|
||||
);
|
||||
}, [handleRecentSearch, handleTextChange, loading,
|
||||
scrollPaddingTop, searchTeamId, searchValue, theme]);
|
||||
}, [
|
||||
handleModifierTextChange, handleRecentSearch,
|
||||
loading, scrollEnabled, scrollPaddingTop, searchTeamId,
|
||||
searchValue, styles.loading, teams, theme.buttonBg,
|
||||
]);
|
||||
|
||||
const animated = useAnimatedStyle(() => {
|
||||
if (isFocused) {
|
||||
|
|
@ -320,6 +318,14 @@ const SearchScreen = ({teamId, teams}: Props) => {
|
|||
}
|
||||
}, [unlock, onSnapWithTimeout]);
|
||||
|
||||
useEffect(() => {
|
||||
if (searchTerm) {
|
||||
resetToInitial();
|
||||
setSearchValue(searchTerm);
|
||||
handleSearch(searchTeamId, searchTerm);
|
||||
}
|
||||
}, [handleSearch, resetToInitial, searchTeamId, searchTerm]);
|
||||
|
||||
useDidUpdate(() => {
|
||||
if (isFocused) {
|
||||
setTimeout(() => {
|
||||
|
|
|
|||
|
|
@ -200,7 +200,7 @@ function TabBar({state, descriptors, navigation, theme}: BottomTabBarProps & {th
|
|||
accessibilityRole='button'
|
||||
accessibilityState={isFocused ? {selected: true} : {}}
|
||||
accessibilityLabel={options.tabBarAccessibilityLabel}
|
||||
testID={options.tabBarTestID}
|
||||
testID={options.tabBarButtonTestID}
|
||||
onPress={onPress}
|
||||
onLongPress={onLongPress}
|
||||
style={style.item}
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ export const bottomSheetModalOptions = (theme: Theme, closeButtonId?: string): O
|
|||
default: OptionsModalPresentationStyle.overCurrentContext,
|
||||
}),
|
||||
statusBar: {
|
||||
backgroundColor: null,
|
||||
backgroundColor: theme.sidebarBg,
|
||||
drawBehind: true,
|
||||
translucent: true,
|
||||
},
|
||||
|
|
@ -468,6 +468,7 @@ export function goToScreen(name: AvailableScreens, title: string, passProps = {}
|
|||
},
|
||||
statusBar: {
|
||||
style: isDark ? 'light' : 'dark',
|
||||
backgroundColor: theme.sidebarBg,
|
||||
},
|
||||
topBar: {
|
||||
animate: true,
|
||||
|
|
@ -579,6 +580,7 @@ export function showModal(name: AvailableScreens, title: string, passProps = {},
|
|||
},
|
||||
statusBar: {
|
||||
visible: true,
|
||||
backgroundColor: theme.sidebarBg,
|
||||
},
|
||||
topBar: {
|
||||
animate: true,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||
// See LICENSE.txt for license information.
|
||||
|
||||
import React, {useEffect, useMemo, useRef, useState} from 'react';
|
||||
import React, {useCallback, useEffect, useMemo, useRef, useState} from 'react';
|
||||
import {useIntl} from 'react-intl';
|
||||
import {DeviceEventEmitter, Text, TouchableOpacity, useWindowDimensions, type ViewStyle} from 'react-native';
|
||||
import {DeviceEventEmitter, Text, TouchableOpacity, useWindowDimensions, type StyleProp, type ViewStyle} from 'react-native';
|
||||
import {Gesture, GestureDetector, GestureHandlerRootView} from 'react-native-gesture-handler';
|
||||
import {type ComponentEvent, Navigation} from 'react-native-navigation';
|
||||
import Animated, {
|
||||
|
|
@ -141,8 +141,8 @@ const SnackBar = ({
|
|||
return [
|
||||
styles.mobile,
|
||||
isTablet && tabletStyle,
|
||||
] as ViewStyle;
|
||||
}, [theme, barType]);
|
||||
] as StyleProp<ViewStyle>;
|
||||
}, [windowWidth, styles.mobile, isTablet, sourceScreen]);
|
||||
|
||||
const toastStyle = useMemo(() => {
|
||||
let backgroundColor: string;
|
||||
|
|
@ -158,7 +158,7 @@ const SnackBar = ({
|
|||
break;
|
||||
}
|
||||
return [styles.toast, {backgroundColor}];
|
||||
}, [theme, config?.type]);
|
||||
}, [config?.type, styles.toast, theme.onlineIndicator, theme.errorTextColor, theme.centerChannelColor]);
|
||||
|
||||
const animatedMotion = useAnimatedStyle(() => {
|
||||
return {
|
||||
|
|
@ -197,10 +197,10 @@ const SnackBar = ({
|
|||
runOnJS(hideSnackBar)();
|
||||
});
|
||||
|
||||
const animateHiding = (forceHiding: boolean) => {
|
||||
const animateHiding = useCallback((forceHiding: boolean) => {
|
||||
const duration = forceHiding ? 0 : 200;
|
||||
offset.value = withTiming(200, {duration}, () => runOnJS(hideSnackBar)());
|
||||
};
|
||||
}, [offset]);
|
||||
|
||||
const onUndoPressHandler = () => {
|
||||
userHasUndo.current = true;
|
||||
|
|
@ -220,7 +220,7 @@ const SnackBar = ({
|
|||
stopTimers();
|
||||
mounted.current = false;
|
||||
};
|
||||
}, [isPanned.value]);
|
||||
}, [animateHiding, isPanned]);
|
||||
|
||||
// This effect dismisses the Navigation Overlay after we have hidden the snack bar
|
||||
useEffect(() => {
|
||||
|
|
@ -230,7 +230,7 @@ const SnackBar = ({
|
|||
}
|
||||
dismissOverlay(componentId);
|
||||
}
|
||||
}, [showSnackBar, onAction]);
|
||||
}, [showSnackBar, onAction, componentId]);
|
||||
|
||||
// This effect checks if we are navigating away and if so, it dismisses the snack bar
|
||||
useEffect(() => {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ export const getErrorMessage = (error: unknown, intl?: IntlShape) => {
|
|||
return error;
|
||||
}
|
||||
if (isErrorWithIntl(error)) {
|
||||
return intl ? intl.formatMessage({id: error.intl.id, defaultMessage: error.intl.defaultMessage}, error.intl.values) : error.intl.defaultMessage;
|
||||
return intl ? intl.formatMessage({id: error.intl.id, defaultMessage: error.intl.defaultMessage}, error.intl.values) : error.intl.defaultMessage!;
|
||||
}
|
||||
|
||||
if (isErrorWithMessage(error)) {
|
||||
|
|
|
|||
|
|
@ -10,10 +10,6 @@ jest.mock('expo-application', () => ({
|
|||
applicationId: 'com.example.rnbeta',
|
||||
}));
|
||||
|
||||
jest.mock('expo-crypto', () => ({
|
||||
randomUUID: jest.fn(() => '12345678-1234-1234-1234-1234567890ab'),
|
||||
}));
|
||||
|
||||
jest.mock('react-intl', () => ({
|
||||
createIntl: jest.fn((config) => config),
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
// Import necessary dependencies and functions
|
||||
import * as Sentry from '@sentry/react-native'; // Importing Sentry as module mock
|
||||
import Sentry from '@sentry/react-native'; // Importing Sentry as module mock
|
||||
import {Platform} from 'react-native';
|
||||
|
||||
import Config from '@assets/config.json';
|
||||
|
|
@ -21,7 +21,9 @@ jest.mock('@sentry/react-native', () => ({
|
|||
addBreadcrumb: jest.fn(),
|
||||
setContext: jest.fn(),
|
||||
ReactNativeTracing: jest.fn(),
|
||||
ReactNativeNavigationInstrumentation: jest.fn(),
|
||||
reactNativeNavigationIntegration: jest.fn().mockImplementation(() => ({
|
||||
name: 'reactNativeNavigation',
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('@assets/config.json', () => ({
|
||||
|
|
@ -107,7 +109,7 @@ describe('initializeSentry function', () => {
|
|||
attachStacktrace: true, // Adjust based on your actual logic
|
||||
enableCaptureFailedRequests: false,
|
||||
integrations: [
|
||||
expect.any(Sentry.ReactNativeTracing),
|
||||
{name: 'reactNativeNavigation'},
|
||||
],
|
||||
beforeSend: expect.any(Function),
|
||||
});
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import {isBetaApp} from '@utils/general';
|
|||
import {logError, logWarning} from './log';
|
||||
|
||||
import type {Database} from '@nozbe/watermelondb';
|
||||
import type {Breadcrumb, Event} from '@sentry/types';
|
||||
import type {Breadcrumb, ErrorEvent} from '@sentry/types';
|
||||
|
||||
export const BREADCRUMB_UNCAUGHT_APP_ERROR = 'uncaught-app-error';
|
||||
export const BREADCRUMB_UNCAUGHT_NON_ERROR = 'uncaught-non-error';
|
||||
|
|
@ -41,7 +41,7 @@ export function initializeSentry() {
|
|||
environment: isBetaApp ? 'beta' : 'production',
|
||||
tracesSampleRate: isBetaApp ? 1.0 : 0.2,
|
||||
sampleRate: isBetaApp ? 1.0 : 0.2,
|
||||
attachStacktrace: isBetaApp, // For Beta, stack traces are automatically attached to all messages logged
|
||||
attachStacktrace: Boolean(isBetaApp), // For Beta, stack traces are automatically attached to all messages logged
|
||||
};
|
||||
|
||||
const eventFilter = Array.isArray(Config.SentryOptions?.severityLevelFilter) ? Config.SentryOptions.severityLevelFilter : [];
|
||||
|
|
@ -55,16 +55,9 @@ export function initializeSentry() {
|
|||
...sentryOptions,
|
||||
enableCaptureFailedRequests: false,
|
||||
integrations: [
|
||||
new Sentry.ReactNativeTracing({
|
||||
|
||||
// Pass instrumentation to be used as `routingInstrumentation`
|
||||
routingInstrumentation: new Sentry.ReactNativeNavigationInstrumentation(
|
||||
Navigation,
|
||||
{enableTabsInstrumentation: false},
|
||||
),
|
||||
}),
|
||||
Sentry.reactNativeNavigationIntegration({navigation: Navigation}),
|
||||
],
|
||||
beforeSend: (event: Event) => {
|
||||
beforeSend: (event: ErrorEvent) => {
|
||||
if (isBetaApp || (event?.level && eventFilter.includes(event.level))) {
|
||||
return event;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ class LoginScreen {
|
|||
await this.usernameInput.replaceText(user.newUser.email);
|
||||
await this.passwordInput.tap();
|
||||
await this.passwordInput.replaceText(user.newUser.password);
|
||||
await element(by.text(/^Log In to Your Account*$/)).tap();
|
||||
await this.signinButton.tap();
|
||||
|
||||
await wait(timeouts.FOUR_SEC);
|
||||
|
|
|
|||
5518
detox/package-lock.json
generated
5518
detox/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
|
@ -4,25 +4,25 @@
|
|||
"repository": "git@github.com:mattermost/mattermost-mobile.git",
|
||||
"author": "Mattermost, Inc.",
|
||||
"devDependencies": {
|
||||
"@aws-sdk/client-s3": "3.650.0",
|
||||
"@aws-sdk/lib-storage": "3.650.0",
|
||||
"@aws-sdk/client-s3": "3.712.0",
|
||||
"@aws-sdk/lib-storage": "3.712.0",
|
||||
"@babel/plugin-proposal-class-properties": "7.18.6",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.24.8",
|
||||
"@babel/plugin-transform-runtime": "7.25.4",
|
||||
"@babel/preset-env": "7.25.4",
|
||||
"@babel/plugin-transform-modules-commonjs": "7.26.3",
|
||||
"@babel/plugin-transform-runtime": "7.25.9",
|
||||
"@babel/preset-env": "7.26.0",
|
||||
"@jest/test-sequencer": "29.7.0",
|
||||
"@types/jest": "29.5.12",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/tough-cookie": "4.0.5",
|
||||
"@types/uuid": "10.0.0",
|
||||
"async": "3.2.6",
|
||||
"axios": "1.7.7",
|
||||
"axios-cookiejar-support": "5.0.2",
|
||||
"axios": "1.7.9",
|
||||
"axios-cookiejar-support": "5.0.4",
|
||||
"babel-jest": "29.7.0",
|
||||
"babel-plugin-module-resolver": "5.0.2",
|
||||
"client-oauth2": "4.3.3",
|
||||
"deepmerge": "4.3.1",
|
||||
"detox": "20.26.2",
|
||||
"form-data": "4.0.0",
|
||||
"detox": "20.28.0",
|
||||
"form-data": "4.0.1",
|
||||
"jest": "29.7.0",
|
||||
"jest-circus": "29.7.0",
|
||||
"jest-cli": "29.7.0",
|
||||
|
|
@ -30,15 +30,15 @@
|
|||
"jest-junit": "16.0.0",
|
||||
"jest-stare": "2.5.2",
|
||||
"junit-report-merger": "7.0.0",
|
||||
"moment-timezone": "0.5.45",
|
||||
"moment-timezone": "0.5.46",
|
||||
"recursive-readdir": "2.2.3",
|
||||
"sanitize-filename": "1.6.3",
|
||||
"shelljs": "0.8.5",
|
||||
"tough-cookie": "5.0.0",
|
||||
"ts-jest": "29.2.5",
|
||||
"tslib": "2.7.0",
|
||||
"typescript": "5.6.2",
|
||||
"uuid": "10.0.0",
|
||||
"tslib": "2.8.1",
|
||||
"typescript": "5.7.2",
|
||||
"uuid": "11.0.3",
|
||||
"xml2js": "0.6.2"
|
||||
},
|
||||
"scripts": {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@
|
|||
/* eslint-disable no-process-env */
|
||||
/* eslint-disable no-console */
|
||||
const fs = require('fs');
|
||||
const deviceName = process.env.DEVICE_NAME || 'iPhone 15 Pro';
|
||||
const deviceOSVersion = process.env.DEVICE_OS_VERSION || 'iOS 17.4';
|
||||
const deviceName = process.env.DEVICE_NAME || 'iPhone 14';
|
||||
const deviceOSVersion = process.env.DEVICE_OS_VERSION || 'iOS 17.2';
|
||||
const detoxConfigTemplate = fs.readFileSync('../.detoxrc.json', 'utf8');
|
||||
const detoxConfig = detoxConfigTemplate.replace('__DEVICE_NAME__', deviceName).replace('__DEVICE_OS_VERSION__', deviceOSVersion);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ func initSentryAppExt(){
|
|||
if(SENTRY_ENABLED=="true"){
|
||||
SentrySDK.start { options in
|
||||
options.dsn = SENTRY_DSN
|
||||
options.enableAppHangTracking = true
|
||||
options.enableCaptureFailedRequests = false
|
||||
options.enableAppHangTracking = false
|
||||
options.enableCaptureFailedRequests = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1393,6 +1393,9 @@
|
|||
"${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/ExpoConstants_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoDevice/ExpoDevice_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/ExpoFileSystem/ExpoFileSystem_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RCT-Folly/RCT-Folly_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNPermissions/RNPermissionsPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/RNSVG/RNSVGFilters.bundle",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/AntDesign.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Entypo.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/EvilIcons.ttf",
|
||||
|
|
@ -1412,12 +1415,16 @@
|
|||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Octicons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/SimpleLineIcons.ttf",
|
||||
"${PODS_ROOT}/../../node_modules/react-native-vector-icons/Fonts/Zocial.ttf",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/RCTI18nStrings.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-Core/React-Core_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/React-cxxreact/React-cxxreact_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/SDWebImage/SDWebImage.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/Sentry/Sentry.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/Starscream/Starscream_Privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/SwiftyJSON/SwiftyJSON.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/boost/boost_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/glog/glog_privacy.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/react-native-cameraroll/RNCameraRollPrivacyInfo.bundle",
|
||||
"${PODS_CONFIGURATION_BUILD_DIR}/react-native-image-picker/RNImagePickerPrivacyInfo.bundle",
|
||||
);
|
||||
name = "[CP] Copy Pods Resources";
|
||||
outputPaths = (
|
||||
|
|
@ -1428,6 +1435,9 @@
|
|||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoConstants_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoDevice_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/ExpoFileSystem_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCT-Folly_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNPermissionsPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNSVGFilters.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AntDesign.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Entypo.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EvilIcons.ttf",
|
||||
|
|
@ -1447,12 +1457,16 @@
|
|||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Octicons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SimpleLineIcons.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Zocial.ttf",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RCTI18nStrings.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-Core_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/React-cxxreact_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SDWebImage.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Sentry.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/Starscream_Privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/SwiftyJSON.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/boost_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/glog_privacy.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNCameraRollPrivacyInfo.bundle",
|
||||
"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/RNImagePickerPrivacyInfo.bundle",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
|
|
@ -1989,7 +2003,7 @@
|
|||
ENABLE_BITCODE = NO;
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = Mattermost/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -2031,7 +2045,7 @@
|
|||
ENABLE_BITCODE = NO;
|
||||
HEADER_SEARCH_PATHS = "$(inherited)";
|
||||
INFOPLIST_FILE = Mattermost/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -2079,7 +2093,7 @@
|
|||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -2128,7 +2142,7 @@
|
|||
DEVELOPMENT_TEAM = UQ8HT4Q2XM;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
INFOPLIST_FILE = NotificationService/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.4;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -2175,7 +2189,7 @@
|
|||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = MattermostShare/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -2225,7 +2239,7 @@
|
|||
GCC_C_LANGUAGE_STANDARD = gnu11;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
INFOPLIST_FILE = MattermostShare/Info.plist;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.1;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
|
|
@ -2307,6 +2321,7 @@
|
|||
OTHER_LDFLAGS = "$(inherited)";
|
||||
REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native";
|
||||
SDKROOT = iphoneos;
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) DEBUG";
|
||||
USE_HERMES = true;
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -2421,7 +2436,7 @@
|
|||
repositoryURL = "https://github.com/getsentry/sentry-cocoa.git";
|
||||
requirement = {
|
||||
kind = exactVersion;
|
||||
version = 8.36.0;
|
||||
version = 8.41.0;
|
||||
};
|
||||
};
|
||||
7FD4822A2864D73300A5B18B /* XCRemoteSwiftPackageReference "OpenGraph" */ = {
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@
|
|||
"repositoryURL": "https://github.com/getsentry/sentry-cocoa.git",
|
||||
"state": {
|
||||
"branch": null,
|
||||
"revision": "5575af93efb776414f243e93d6af9f6258dc539a",
|
||||
"version": "8.36.0"
|
||||
"revision": "56bfb7e723c76614be4c0861ee820ccbaed14c6d",
|
||||
"version": "8.41.0"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ NSString* const NOTIFICATION_TEST_ACTION = @"test";
|
|||
NSArray<NSString*> *servers = [keychain getAllServersForInternetPasswords];
|
||||
NSLog(@"Servers %@", servers);
|
||||
for (NSString *server in servers) {
|
||||
[keychain deleteCredentialsForServer:server];
|
||||
[keychain deleteCredentialsForServer:server withOptions:nil];
|
||||
}
|
||||
|
||||
[[NSUserDefaults standardUserDefaults] setValue:@YES forKey:@"FirstRun"];
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ require File.join(File.dirname(`node --print "require.resolve('expo/package.json
|
|||
node_require('react-native/scripts/react_native_pods.rb')
|
||||
node_require('react-native-permissions/scripts/setup.rb')
|
||||
|
||||
platform :ios, min_ios_version_supported
|
||||
platform :ios, '15.1' #min_ios_version_supported
|
||||
prepare_react_native_project!
|
||||
|
||||
linkage = ENV['USE_FRAMEWORKS']
|
||||
|
|
@ -54,7 +54,7 @@ target 'Mattermost' do
|
|||
|
||||
# installer.pods_project.targets.each do |target|
|
||||
# target.build_configurations.each do |config|
|
||||
# config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.4'
|
||||
# config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '15.1'
|
||||
# end
|
||||
# end
|
||||
end
|
||||
|
|
|
|||
3435
ios/Podfile.lock
3435
ios/Podfile.lock
File diff suppressed because it is too large
Load diff
51700
package-lock.json
generated
51700
package-lock.json
generated
File diff suppressed because it is too large
Load diff
191
package.json
191
package.json
|
|
@ -11,34 +11,37 @@
|
|||
"npm": "^9 || ^10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@formatjs/intl-datetimeformat": "6.12.5",
|
||||
"@formatjs/intl-getcanonicallocales": "2.3.0",
|
||||
"@formatjs/intl-listformat": "7.5.7",
|
||||
"@formatjs/intl-locale": "4.0.0",
|
||||
"@formatjs/intl-numberformat": "8.10.3",
|
||||
"@formatjs/intl-pluralrules": "5.2.14",
|
||||
"@gorhom/bottom-sheet": "4.6.4",
|
||||
"@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",
|
||||
"@mattermost/calls": "github:mattermost/calls-common#030ff7c0a37ee9b0ccc5fae0b2ea9c0e1c08473f",
|
||||
"@mattermost/compass-icons": "0.1.48",
|
||||
"@mattermost/hardware-keyboard": "file:./libraries/@mattermost/hardware-keyboard",
|
||||
"@mattermost/react-native-emm": "1.5.0",
|
||||
"@mattermost/react-native-network-client": "github:mattermost/react-native-network-client#ad7b88412f41c5a1024420a4f4c7461883cd0e63",
|
||||
"@mattermost/react-native-paste-input": "0.8.0",
|
||||
"@mattermost/react-native-turbo-log": "github:mattermost/react-native-turbo-log#d8ddf5e7974546aff3e83b2c563907eb609ac5f4",
|
||||
"@mattermost/react-native-emm": "1.5.1",
|
||||
"@mattermost/react-native-network-client": "1.8.0",
|
||||
"@mattermost/react-native-paste-input": "0.8.1",
|
||||
"@mattermost/react-native-turbo-log": "0.5.0",
|
||||
"@mattermost/rnshare": "file:./libraries/@mattermost/rnshare",
|
||||
"@mattermost/rnutils": "file:./libraries/@mattermost/rnutils",
|
||||
"@msgpack/msgpack": "2.8.0",
|
||||
"@nozbe/watermelondb": "0.27.1",
|
||||
"@react-native-camera-roll/camera-roll": "7.8.3",
|
||||
"@react-native-clipboard/clipboard": "1.14.1",
|
||||
"@nozbe/watermelondb": "0.28.0-1",
|
||||
"@react-native-camera-roll/camera-roll": "7.9.0",
|
||||
"@react-native-clipboard/clipboard": "1.15.0",
|
||||
"@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/netinfo": "11.3.2",
|
||||
"@react-native-community/netinfo": "11.4.1",
|
||||
"@react-native-cookies/cookies": "6.2.1",
|
||||
"@react-navigation/bottom-tabs": "6.6.1",
|
||||
"@react-navigation/native": "6.1.18",
|
||||
"@react-navigation/stack": "6.4.1",
|
||||
"@react-navigation/bottom-tabs": "7.2.0",
|
||||
"@react-navigation/native": "7.0.14",
|
||||
"@react-navigation/stack": "7.1.0",
|
||||
"@rneui/base": "4.0.0-rc.8",
|
||||
"@sentry/react-native": "5.33.2",
|
||||
"@sentry/react-native": "6.4.0",
|
||||
"@stream-io/flat-list-mvcp": "0.10.3",
|
||||
"@voximplant/react-native-foreground-service": "3.0.2",
|
||||
"base-64": "1.0.0",
|
||||
|
|
@ -46,123 +49,123 @@
|
|||
"commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#81b5d27509652bae50b4b510ede777dd3bd923cf",
|
||||
"deep-equal": "2.2.3",
|
||||
"deepmerge": "4.3.1",
|
||||
"emoji-regex": "10.3.0",
|
||||
"expo": "51.0.24",
|
||||
"expo-application": "5.9.1",
|
||||
"expo-crypto": "13.0.2",
|
||||
"expo-device": "6.0.2",
|
||||
"expo-image": "1.12.13",
|
||||
"expo-linear-gradient": "13.0.2",
|
||||
"expo-store-review": "7.0.2",
|
||||
"expo-video-thumbnails": "8.0.0",
|
||||
"expo-web-browser": "13.0.3",
|
||||
"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.3",
|
||||
"expo-linear-gradient": "14.0.1",
|
||||
"expo-store-review": "8.0.0",
|
||||
"expo-video-thumbnails": "9.0.2",
|
||||
"expo-web-browser": "14.0.1",
|
||||
"fflate": "0.8.2",
|
||||
"fuse.js": "7.0.0",
|
||||
"html-entities": "2.5.2",
|
||||
"mime-db": "1.53.0",
|
||||
"moment-timezone": "0.5.45",
|
||||
"moment-timezone": "0.5.46",
|
||||
"node-html-parser": "6.1.13",
|
||||
"path-to-regexp": "8.1.0",
|
||||
"react": "18.2.0",
|
||||
"path-to-regexp": "8.2.0",
|
||||
"react": "18.3.1",
|
||||
"react-freeze": "1.0.4",
|
||||
"react-intl": "6.6.8",
|
||||
"react-native": "0.74.5",
|
||||
"react-intl": "7.0.4",
|
||||
"react-native": "0.76.5",
|
||||
"react-native-background-timer": "2.4.1",
|
||||
"react-native-document-picker": "9.3.0",
|
||||
"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.18.1",
|
||||
"react-native-haptic-feedback": "2.2.0",
|
||||
"react-native-image-picker": "7.1.2",
|
||||
"react-native-gesture-handler": "2.21.2",
|
||||
"react-native-haptic-feedback": "2.3.3",
|
||||
"react-native-image-picker": "7.2.3",
|
||||
"react-native-incall-manager": "4.2.0",
|
||||
"react-native-keyboard-aware-scroll-view": "0.9.5",
|
||||
"react-native-keychain": "8.2.0",
|
||||
"react-native-localize": "3.2.1",
|
||||
"react-native-keychain": "9.2.2",
|
||||
"react-native-localize": "3.3.0",
|
||||
"react-native-math-view": "3.9.5",
|
||||
"react-native-navigation": "7.40.1",
|
||||
"react-native-navigation": "7.40.3",
|
||||
"react-native-notifications": "5.1.0",
|
||||
"react-native-performance": "5.1.2",
|
||||
"react-native-permissions": "4.1.5",
|
||||
"react-native-reanimated": "3.14.0",
|
||||
"react-native-safe-area-context": "4.10.8",
|
||||
"react-native-screens": "3.34.0",
|
||||
"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-section-list-get-item-layout": "2.2.3",
|
||||
"react-native-shadow-2": "7.1.0",
|
||||
"react-native-share": "10.2.1",
|
||||
"react-native-svg": "15.4.0",
|
||||
"react-native-shadow-2": "7.1.1",
|
||||
"react-native-share": "12.0.3",
|
||||
"react-native-svg": "15.10.1",
|
||||
"react-native-url-polyfill": "2.0.0",
|
||||
"react-native-vector-icons": "10.1.0",
|
||||
"react-native-video": "6.4.3",
|
||||
"react-native-vector-icons": "10.2.0",
|
||||
"react-native-video": "6.8.2",
|
||||
"react-native-walkthrough-tooltip": "1.6.0",
|
||||
"react-native-webrtc": "124.0.3",
|
||||
"react-syntax-highlighter": "15.5.0",
|
||||
"react-native-webrtc": "124.0.4",
|
||||
"react-syntax-highlighter": "15.6.1",
|
||||
"semver": "7.6.3",
|
||||
"tinycolor2": "1.6.0",
|
||||
"url-parse": "1.5.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/cli": "7.24.8",
|
||||
"@babel/core": "7.25.2",
|
||||
"@babel/eslint-parser": "7.25.1",
|
||||
"@babel/cli": "7.26.4",
|
||||
"@babel/core": "7.26.0",
|
||||
"@babel/eslint-parser": "7.25.9",
|
||||
"@babel/plugin-proposal-class-properties": "7.18.6",
|
||||
"@babel/plugin-proposal-decorators": "7.24.7",
|
||||
"@babel/plugin-transform-flow-strip-types": "7.25.2",
|
||||
"@babel/plugin-transform-runtime": "7.24.7",
|
||||
"@babel/preset-env": "7.25.3",
|
||||
"@babel/preset-typescript": "7.24.7",
|
||||
"@babel/register": "7.24.6",
|
||||
"@babel/runtime": "7.25.0",
|
||||
"@react-native/babel-preset": "0.74.87",
|
||||
"@react-native/eslint-config": "0.74.87",
|
||||
"@react-native/metro-config": "0.74.87",
|
||||
"@react-native/typescript-config": "0.74.87",
|
||||
"@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/preset-typescript": "7.26.0",
|
||||
"@babel/register": "7.25.9",
|
||||
"@babel/runtime": "7.26.0",
|
||||
"@react-native/babel-preset": "0.76.5",
|
||||
"@react-native/eslint-config": "0.76.5",
|
||||
"@react-native/metro-config": "0.76.5",
|
||||
"@react-native/typescript-config": "0.76.5",
|
||||
"@testing-library/react-hooks": "8.0.1",
|
||||
"@testing-library/react-native": "12.5.2",
|
||||
"@testing-library/react-native": "12.9.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.12",
|
||||
"@types/lodash": "4.17.7",
|
||||
"@types/jest": "29.5.14",
|
||||
"@types/lodash": "4.17.13",
|
||||
"@types/mime-db": "1.43.5",
|
||||
"@types/pako": "2.0.3",
|
||||
"@types/querystringify": "2.0.2",
|
||||
"@types/react": "18.3.3",
|
||||
"@types/react": "18.3.12",
|
||||
"@types/react-native-background-timer": "2.0.2",
|
||||
"@types/react-native-dotenv": "0.2.2",
|
||||
"@types/react-native-share": "3.3.8",
|
||||
"@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.13.1",
|
||||
"@typescript-eslint/parser": "7.13.1",
|
||||
"@typescript-eslint/eslint-plugin": "7.14.1",
|
||||
"@typescript-eslint/parser": "7.14.1",
|
||||
"babel-jest": "29.7.0",
|
||||
"babel-loader": "9.1.3",
|
||||
"babel-loader": "9.2.1",
|
||||
"babel-plugin-module-resolver": "5.0.2",
|
||||
"eslint": "8.57.0",
|
||||
"eslint": "8.57.1",
|
||||
"eslint-plugin-header": "3.1.1",
|
||||
"eslint-plugin-import": "2.29.1",
|
||||
"eslint-plugin-jest": "28.7.0",
|
||||
"eslint-plugin-react": "7.35.0",
|
||||
"eslint-plugin-react-hooks": "4.6.2",
|
||||
"husky": "9.1.4",
|
||||
"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",
|
||||
"husky": "9.1.7",
|
||||
"isomorphic-fetch": "3.0.0",
|
||||
"jest": "29.7.0",
|
||||
"jest-cli": "29.7.0",
|
||||
"jest-expo": "51.0.3",
|
||||
"jest-expo": "52.0.2",
|
||||
"jetifier": "2.0.0",
|
||||
"mmjstool": "github:mattermost/mattermost-utilities#83b1b311972b8f5e750aae4019457a40abb5aa44",
|
||||
"nock": "13.5.4",
|
||||
"nock": "13.5.6",
|
||||
"patch-package": "8.0.0",
|
||||
"react-devtools-core": "5.3.1",
|
||||
"tough-cookie": "4.1.4",
|
||||
"ts-jest": "29.2.4",
|
||||
"typescript": "5.5.4",
|
||||
"uuid": "10.0.0"
|
||||
"react-devtools-core": "6.0.1",
|
||||
"tough-cookie": "5.0.0",
|
||||
"ts-jest": "29.2.5",
|
||||
"typescript": "5.7.2",
|
||||
"uuid": "11.0.3"
|
||||
},
|
||||
"scripts": {
|
||||
"android": "react-native run-android",
|
||||
|
|
@ -198,25 +201,21 @@
|
|||
},
|
||||
"overrides": {
|
||||
"@testing-library/react-native": {
|
||||
"react": "^18.2.0"
|
||||
"react": "^18.3.1"
|
||||
},
|
||||
"@testing-library/react-hooks": {
|
||||
"@types/react": "^18.2.37",
|
||||
"react": "^18.2.0",
|
||||
"react": "^18.3.1",
|
||||
"react-test-renderer": "^18.2.0"
|
||||
},
|
||||
"@react-native-community/datetimepicker": {
|
||||
"react-native": "^0.74.2"
|
||||
},
|
||||
"@react-native/eslint-config": {
|
||||
"@typescript-eslint/eslint-plugin": "^7.12.0",
|
||||
"@typescript-eslint/parser": "^7.12.0"
|
||||
"react-native": "^0.76.5"
|
||||
},
|
||||
"@react-native-clipboard/clipboard": {
|
||||
"react-native": "^0.74.2"
|
||||
"react-native": "^0.76.5"
|
||||
},
|
||||
"react-native-windows": {
|
||||
"react-native": "^0.74.2"
|
||||
"react-native": "^0.76.5"
|
||||
}
|
||||
},
|
||||
"expo": {
|
||||
|
|
|
|||
|
|
@ -1,21 +1,21 @@
|
|||
diff --git a/node_modules/@nozbe/watermelondb/Database/index.d.ts b/node_modules/@nozbe/watermelondb/Database/index.d.ts
|
||||
index 861ed06..d2d6527 100644
|
||||
index e6eefec..d3a7dc0 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/Database/index.d.ts
|
||||
+++ b/node_modules/@nozbe/watermelondb/Database/index.d.ts
|
||||
@@ -88,6 +88,8 @@ export default class Database {
|
||||
// Yes, this sucks and there should be some safety mechanisms or warnings. Please contribute!
|
||||
unsafeResetDatabase(): Promise<void>
|
||||
@@ -93,6 +93,8 @@ export default class Database {
|
||||
// has a significant performance impact so should only be enabled when debugging.
|
||||
experimentalIsVerbose: boolean
|
||||
|
||||
+ unsafeVacuum(): Promise<void>
|
||||
+
|
||||
+
|
||||
_ensureInWriter(diagnosticMethodName: string): void
|
||||
|
||||
// (experimental) puts Database in a broken state
|
||||
diff --git a/node_modules/@nozbe/watermelondb/Database/index.js b/node_modules/@nozbe/watermelondb/Database/index.js
|
||||
index fa82516..de24ff2 100644
|
||||
index 9139dd4..aec45b5 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/Database/index.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/Database/index.js
|
||||
@@ -91,7 +91,9 @@ var Database = /*#__PURE__*/function () {
|
||||
@@ -92,7 +92,9 @@ var Database = exports.default = /*#__PURE__*/function () {
|
||||
var preparedState = record._preparedState;
|
||||
if (!preparedState) {
|
||||
(0, _common.invariant)('disposable' !== record._raw._status, "Cannot batch a disposable record");
|
||||
|
|
@ -26,22 +26,21 @@ index fa82516..de24ff2 100644
|
|||
}
|
||||
var raw = record._raw;
|
||||
var {
|
||||
@@ -122,6 +124,10 @@ var Database = /*#__PURE__*/function () {
|
||||
@@ -123,6 +125,9 @@ var Database = exports.default = /*#__PURE__*/function () {
|
||||
// subsequent changes to the record don't trip up the invariant
|
||||
// TODO: What if this fails?
|
||||
record._preparedState = null;
|
||||
+
|
||||
+ if ('update' === preparedState) {
|
||||
+ record.__original = null;
|
||||
+ }
|
||||
}
|
||||
if (!changeNotifications[table]) {
|
||||
changeNotifications[table] = [];
|
||||
@@ -379,6 +385,57 @@ var Database = /*#__PURE__*/function () {
|
||||
}
|
||||
@@ -399,6 +404,57 @@ var Database = exports.default = /*#__PURE__*/function () {
|
||||
}.bind(this));
|
||||
};
|
||||
+ _proto.unsafeVacuum = function unsafeVacuum() {
|
||||
}
|
||||
|
||||
+ _proto.unsafeVacuum = function () {
|
||||
+ return new Promise(function ($return, $error) {
|
||||
+ var $Try_3_Finally = function ($Try_3_Exit) {
|
||||
+ return function ($Try_3_Value) {
|
||||
|
|
@ -75,7 +74,6 @@ index fa82516..de24ff2 100644
|
|||
+ } = this);
|
||||
+ ErrorAdapter = require('../adapters/error').default;
|
||||
+ this.adapter = new ErrorAdapter();
|
||||
+
|
||||
+ // Vacuum the database
|
||||
+ return Promise.resolve(adapter.unsafeVacuum()).then(function () {
|
||||
+ try {
|
||||
|
|
@ -92,11 +90,12 @@ index fa82516..de24ff2 100644
|
|||
+ }
|
||||
+ }.bind(this));
|
||||
+ };
|
||||
_proto._ensureInWriter = function _ensureInWriter(diagnosticMethodName) {
|
||||
(0, _common.invariant)(this._workQueue.isWriterRunning, "".concat(diagnosticMethodName, " can only be called from inside of a Writer. See docs for more details."));
|
||||
}
|
||||
+
|
||||
// (experimental) if true, Models will print to console diagnostic information on every
|
||||
// prepareCreate/Update/Delete call, as well as on commit (Database.batch() call). Note that this
|
||||
// has a significant performance impact so should only be enabled when debugging.
|
||||
diff --git a/node_modules/@nozbe/watermelondb/Model/index.d.ts b/node_modules/@nozbe/watermelondb/Model/index.d.ts
|
||||
index 96114ec..ecfe3c1 100644
|
||||
index 96114ec..258bb92 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/Model/index.d.ts
|
||||
+++ b/node_modules/@nozbe/watermelondb/Model/index.d.ts
|
||||
@@ -61,6 +61,8 @@ export default class Model {
|
||||
|
|
@ -104,20 +103,20 @@ index 96114ec..ecfe3c1 100644
|
|||
prepareUpdate(recordUpdater?: (_: this) => void): this
|
||||
|
||||
+ cancelPrepareUpdate(): void
|
||||
+
|
||||
+
|
||||
prepareMarkAsDeleted(): this
|
||||
|
||||
prepareDestroyPermanently(): this
|
||||
diff --git a/node_modules/@nozbe/watermelondb/Model/index.js b/node_modules/@nozbe/watermelondb/Model/index.js
|
||||
index dbfdf6e..2e63166 100644
|
||||
index a5b6815..18a21d8 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/Model/index.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/Model/index.js
|
||||
@@ -80,7 +80,17 @@ var Model = /*#__PURE__*/function () {
|
||||
@@ -101,7 +101,18 @@ var Model = exports.default = /*#__PURE__*/function () {
|
||||
*/;
|
||||
_proto.prepareUpdate = function prepareUpdate(recordUpdater = _noop.default) {
|
||||
_proto.prepareUpdate = function (recordUpdater = _noop.default) {
|
||||
var _this = this;
|
||||
- (0, _invariant.default)(!this._preparedState, "Cannot update a record with pending changes. Update attempted for table ".concat(this.table, " and record ").concat(this.id, "."));
|
||||
+ // (0, _invariant.default)(!this._preparedState, "Cannot update a record with pending changes. Update attempted for table ".concat(this.table, " and record ").concat(this.id, "."));
|
||||
- (0, _invariant.default)(!this._preparedState, "Cannot update a record with pending changes (".concat(this.__debugName, ")"));
|
||||
+ // (0, _invariant.default)(!this._preparedState, "Cannot update a record with pending changes (".concat(this.__debugName, ")"));
|
||||
+ if ('deleted' === this._raw._status) {
|
||||
+ console.debug("Updating a deleted record in table " + _this.table);
|
||||
+ return this;
|
||||
|
|
@ -128,16 +127,16 @@ index dbfdf6e..2e63166 100644
|
|||
+ } else {
|
||||
+ this.__original = Object.assign({}, this._raw);
|
||||
+ }
|
||||
+
|
||||
this.__ensureNotDisposable("Model.prepareUpdate()");
|
||||
this._isEditing = true;
|
||||
|
||||
@@ -125,6 +135,21 @@ var Model = /*#__PURE__*/function () {
|
||||
@@ -147,6 +158,20 @@ var Model = exports.default = /*#__PURE__*/function () {
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
+ _proto.cancelPrepareUpdate = function cancelPrepareUpdate() {
|
||||
+ _proto.cancelPrepareUpdate = function () {
|
||||
+ var _this = this;
|
||||
+
|
||||
+ if ('test' !== process.env.NODE_ENV && 'undefined' !== typeof process && process) {
|
||||
+ (0, _invariant.default)('update' === _this._preparedState, "Cannot cancel an update on a model that has not been prepared in table " + _this.table);
|
||||
+ }
|
||||
|
|
@ -153,12 +152,12 @@ index dbfdf6e..2e63166 100644
|
|||
/**
|
||||
* Prepares record to be marked as deleted
|
||||
*
|
||||
@@ -173,7 +198,10 @@ var Model = /*#__PURE__*/function () {
|
||||
@@ -196,7 +221,10 @@ var Model = exports.default = /*#__PURE__*/function () {
|
||||
* @see {Database#batch}
|
||||
*/;
|
||||
_proto.prepareDestroyPermanently = function prepareDestroyPermanently() {
|
||||
- (0, _invariant.default)(!this._preparedState, "Cannot destroy permanently a record with pending changes");
|
||||
+ // (0, _invariant.default)(!this._preparedState, "Cannot destroy permanently a record with pending changes");
|
||||
_proto.prepareDestroyPermanently = function () {
|
||||
- (0, _invariant.default)(!this._preparedState, "Cannot destroy permanently record with pending changes (".concat(this.__debugName, ")"));
|
||||
+ // (0, _invariant.default)(!this._preparedState, "Cannot destroy permanently record with pending changes (".concat(this.__debugName, ")"));
|
||||
+ if (this._preparedState) {
|
||||
+ console.debug("Deleting a record with pending changes in table " + this.table);
|
||||
+ }
|
||||
|
|
@ -179,28 +178,28 @@ index 51879c7..435ad72 100644
|
|||
|
||||
getLocal(key: string): Promise<string | undefined>
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/compat.js b/node_modules/@nozbe/watermelondb/adapters/compat.js
|
||||
index 4a0b5ef..9b8ff13 100644
|
||||
index 138bc91..82c6311 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/compat.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/compat.js
|
||||
@@ -76,6 +76,12 @@ var DatabaseAdapterCompat = /*#__PURE__*/function () {
|
||||
@@ -76,6 +76,12 @@ var DatabaseAdapterCompat = exports.default = /*#__PURE__*/function () {
|
||||
return _this11.underlyingAdapter.unsafeResetDatabase(callback);
|
||||
});
|
||||
};
|
||||
+ _proto.unsafeVacuum = function unsafeVacuum() {
|
||||
+ _proto.unsafeVacuum = function () {
|
||||
+ var _this16 = this;
|
||||
+ return (0, _Result.toPromise)(function (callback) {
|
||||
+ return _this16.underlyingAdapter.unsafeVacuum(callback);
|
||||
+ });
|
||||
+ };
|
||||
_proto.unsafeExecute = function unsafeExecute(work) {
|
||||
_proto.unsafeExecute = function (work) {
|
||||
var _this12 = this;
|
||||
return (0, _Result.toPromise)(function (callback) {
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/error.js b/node_modules/@nozbe/watermelondb/adapters/error.js
|
||||
index 70a4c11..453dca2 100644
|
||||
index 83b5754..f023e14 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/error.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/error.js
|
||||
@@ -13,7 +13,7 @@ var throwError = function (name) {
|
||||
var ErrorAdapter = /*#__PURE__*/function () {
|
||||
var ErrorAdapter = exports.default = /*#__PURE__*/function () {
|
||||
function ErrorAdapter() {
|
||||
var _this = this;
|
||||
- ['find', 'query', 'queryIds', 'count', 'batch', 'getDeletedRecords', 'destroyDeletedRecords', 'unsafeResetDatabase', 'getLocal', 'setLocal', 'removeLocal', 'testClone'].forEach(function (name) {
|
||||
|
|
@ -209,7 +208,7 @@ index 70a4c11..453dca2 100644
|
|||
_this[name] = function () {
|
||||
return throwError(name);
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/lokijs/common.d.ts b/node_modules/@nozbe/watermelondb/adapters/lokijs/common.d.ts
|
||||
index 5528dc1..0408198 100644
|
||||
index f8d179f..4b39cf9 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/lokijs/common.d.ts
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/lokijs/common.d.ts
|
||||
@@ -13,6 +13,7 @@ export type WorkerExecutorType =
|
||||
|
|
@ -234,24 +233,24 @@ index e09fb14..51d42d9 100644
|
|||
|
||||
getLocal(key: string, callback: ResultCallback<string | undefined>): void
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/lokijs/index.js b/node_modules/@nozbe/watermelondb/adapters/lokijs/index.js
|
||||
index 9d5ea84..aa8397d 100644
|
||||
index 08916f6..672fc29 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/lokijs/index.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/lokijs/index.js
|
||||
@@ -105,6 +105,9 @@ var LokiJSAdapter = /*#__PURE__*/function () {
|
||||
_proto.unsafeResetDatabase = function unsafeResetDatabase(callback) {
|
||||
@@ -105,6 +105,9 @@ var LokiJSAdapter = exports.default = /*#__PURE__*/function () {
|
||||
_proto.unsafeResetDatabase = function (callback) {
|
||||
this._dispatcher.call('unsafeResetDatabase', [], callback);
|
||||
};
|
||||
+ _proto.unsafeVacuum = function unssafeVacuum(callback) {
|
||||
+ _proto.unsafeVacuum = function (callback) {
|
||||
+ this._dispatcher.call('unsafeVacuum', [], callback);
|
||||
+ };
|
||||
_proto.unsafeExecute = function unsafeExecute(operations, callback) {
|
||||
_proto.unsafeExecute = function (operations, callback) {
|
||||
this._dispatcher.call('unsafeExecute', [operations], callback);
|
||||
};
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/lokijs/worker/DatabaseBridge.js b/node_modules/@nozbe/watermelondb/adapters/lokijs/worker/DatabaseBridge.js
|
||||
index ca35a79..7079572 100644
|
||||
index e7acc55..afc44d0 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/lokijs/worker/DatabaseBridge.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/lokijs/worker/DatabaseBridge.js
|
||||
@@ -33,7 +33,7 @@ var DatabaseBridge = /*#__PURE__*/function () {
|
||||
@@ -33,7 +33,7 @@ var DatabaseBridge = exports.default = /*#__PURE__*/function () {
|
||||
type: type,
|
||||
payload: payload
|
||||
} = action;
|
||||
|
|
@ -261,22 +260,22 @@ index ca35a79..7079572 100644
|
|||
} else {
|
||||
var response = this._driverAction(type).apply(void 0, (0, _toConsumableArray2.default)(payload));
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/lokijs/worker/DatabaseDriver.js b/node_modules/@nozbe/watermelondb/adapters/lokijs/worker/DatabaseDriver.js
|
||||
index ee89cff..04de604 100644
|
||||
index 85626c4..e448e9b 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/lokijs/worker/DatabaseDriver.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/lokijs/worker/DatabaseDriver.js
|
||||
@@ -216,6 +216,12 @@ var DatabaseDriver = /*#__PURE__*/function () {
|
||||
@@ -216,6 +216,12 @@ var DatabaseDriver = exports.default = /*#__PURE__*/function () {
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
+ _proto.unsafeVacuum = function unsafeVacuum() {
|
||||
+ _proto.unsafeVacuum = function () {
|
||||
+ return new Promise(function ($return, $error) {
|
||||
+ return Promise.resolve(0);
|
||||
+ }.bind(this));
|
||||
+ }
|
||||
+ };
|
||||
+
|
||||
// *** LocalStorage ***
|
||||
;
|
||||
_proto.getLocal = function getLocal(key) {
|
||||
_proto.getLocal = function (key) {
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/sqlite/index.d.ts b/node_modules/@nozbe/watermelondb/adapters/sqlite/index.d.ts
|
||||
index 88c43a0..cef8232 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/sqlite/index.d.ts
|
||||
|
|
@ -291,14 +290,14 @@ index 88c43a0..cef8232 100644
|
|||
|
||||
getLocal(key: string, callback: ResultCallback<string | undefined>): void
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/sqlite/index.js b/node_modules/@nozbe/watermelondb/adapters/sqlite/index.js
|
||||
index 985dbd6..bcc232d 100644
|
||||
index 0af2b6c..193d7e9 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/sqlite/index.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/sqlite/index.js
|
||||
@@ -237,6 +237,14 @@ var SQLiteAdapter = /*#__PURE__*/function () {
|
||||
@@ -237,6 +237,14 @@ var SQLiteAdapter = exports.default = /*#__PURE__*/function () {
|
||||
callback(result);
|
||||
});
|
||||
};
|
||||
+ _proto.unsafeVacuum = function unsafeVacuum(callback) {
|
||||
+ _proto.unsafeVacuum = function (callback) {
|
||||
+ this._dispatcher.call('unsafeVacuum', [], function (result) {
|
||||
+ if (result.value) {
|
||||
+ _common.logger.log('[SQLite] Database is now vacuumed');
|
||||
|
|
@ -306,45 +305,45 @@ index 985dbd6..bcc232d 100644
|
|||
+ callback(result);
|
||||
+ });
|
||||
+ };
|
||||
_proto.unsafeExecute = function unsafeExecute(operations, callback) {
|
||||
_proto.unsafeExecute = function (operations, callback) {
|
||||
if ('production' !== process.env.NODE_ENV) {
|
||||
(0, _common.invariant)(operations && 'object' === typeof operations && 1 === Object.keys(operations).length && (Array.isArray(operations.sqls) || 'string' === typeof operations.sqlString), "unsafeExecute expects an { sqls: [ [sql, [args..]], ... ] } or { sqlString: 'foo; bar' } object");
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseBridge.js b/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseBridge.js
|
||||
index a93b0a7..df63896 100644
|
||||
index 896e027..ce4866d 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseBridge.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseBridge.js
|
||||
@@ -113,6 +113,14 @@ var DatabaseBridge = /*#__PURE__*/function () {
|
||||
});
|
||||
});
|
||||
};
|
||||
+ _proto.unsafeVacuum = function unsafeVacuum(tag, schema, schemaVersion, resolve, reject) {
|
||||
+ _proto.unsafeVacuum = function (tag, schema, schemaVersion, resolve, reject) {
|
||||
+ this.withDriver(tag, resolve, reject, 'unsafeVacuum', function (driver) {
|
||||
+ return driver.unsafeVacuum({
|
||||
+ version: schemaVersion,
|
||||
+ sql: schema
|
||||
+ });
|
||||
+ });
|
||||
+ }
|
||||
+ };
|
||||
_proto.getLocal = function getLocal(tag, key, resolve, reject) {
|
||||
_proto.getLocal = function (tag, key, resolve, reject) {
|
||||
this.withDriver(tag, resolve, reject, 'getLocal', function (driver) {
|
||||
return driver.getLocal(key);
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseDriver.js b/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseDriver.js
|
||||
index 483884c..c325299 100644
|
||||
index 40f7af6..97033b0 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseDriver.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/sqlite/sqlite-node/DatabaseDriver.js
|
||||
@@ -198,6 +198,10 @@ var DatabaseDriver = /*#__PURE__*/function () {
|
||||
_this5.database.userVersion = schema.version;
|
||||
});
|
||||
};
|
||||
+ _proto.unsafeVacuum = function unsafeVacuum() {
|
||||
+ _proto.unsafeVacuum = function () {
|
||||
+ var _this5 = this;
|
||||
+ this.database.unsafeVacuum();
|
||||
+ };
|
||||
_proto.migrate = function migrate(migrations) {
|
||||
_proto.migrate = function (migrations) {
|
||||
var _this6 = this;
|
||||
var databaseVersion = this.database.userVersion;
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/sqlite/type.d.ts b/node_modules/@nozbe/watermelondb/adapters/sqlite/type.d.ts
|
||||
index 16a8a71..ce6e743 100644
|
||||
index 5d1a321..bb7a195 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/sqlite/type.d.ts
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/sqlite/type.d.ts
|
||||
@@ -45,6 +45,7 @@ export type SqliteDispatcherMethod =
|
||||
|
|
@ -356,10 +355,10 @@ index 16a8a71..ce6e743 100644
|
|||
| 'unsafeExecuteMultiple'
|
||||
|
||||
diff --git a/node_modules/@nozbe/watermelondb/adapters/type.d.ts b/node_modules/@nozbe/watermelondb/adapters/type.d.ts
|
||||
index 027c366..5807e79 100644
|
||||
index 3a73e71..0e9395d 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/adapters/type.d.ts
|
||||
+++ b/node_modules/@nozbe/watermelondb/adapters/type.d.ts
|
||||
@@ -66,6 +66,9 @@ export interface DatabaseAdapter {
|
||||
@@ -67,6 +67,9 @@ export interface DatabaseAdapter {
|
||||
// Destroys the whole database, its schema, indexes, everything.
|
||||
unsafeResetDatabase(callback: ResultCallback<void>): void
|
||||
|
||||
|
|
@ -595,16 +594,16 @@ index f0073c5..028031b 100644
|
|||
void executeMultiple(std::string sql);
|
||||
|
||||
diff --git a/node_modules/@nozbe/watermelondb/native/shared/DatabaseBridge.cpp b/node_modules/@nozbe/watermelondb/native/shared/DatabaseBridge.cpp
|
||||
index ef0f23b..cb49ecd 100644
|
||||
index ef0f23b..d1a6742 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/native/shared/DatabaseBridge.cpp
|
||||
+++ b/node_modules/@nozbe/watermelondb/native/shared/DatabaseBridge.cpp
|
||||
@@ -213,6 +213,18 @@ void Database::install(jsi::Runtime *runtime) {
|
||||
std::abort();
|
||||
@@ -75,7 +75,17 @@ void Database::install(jsi::Runtime *runtime) {
|
||||
databaseToDestroy->destroy();
|
||||
}
|
||||
});
|
||||
-
|
||||
+ createMethod(rt, adapter, "unsafeVacuum", 0, [database](jsi::Runtime &rt, const jsi::Value *args) {
|
||||
+ assert(database->initialized_);
|
||||
+
|
||||
+ try {
|
||||
+ database->unsafeVacuum();
|
||||
+ return jsi::Value::undefined();
|
||||
|
|
@ -614,9 +613,9 @@ index ef0f23b..cb49ecd 100644
|
|||
+ std::abort();
|
||||
+ }
|
||||
+ });
|
||||
createMethod(rt, adapter, "unsafeClose", 0, [database](jsi::Runtime &rt, const jsi::Value *args) {
|
||||
assert(database->initialized_);
|
||||
database->destroy();
|
||||
createMethod(rt, adapter, "initialize", 2, [database](jsi::Runtime &rt, const jsi::Value *args) {
|
||||
jsi::String dbName = args[0].getString(rt);
|
||||
int expectedVersion = (int)args[1].getNumber();
|
||||
diff --git a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp b/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp
|
||||
index e08153b..2fca075 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/native/shared/Sqlite.cpp
|
||||
|
|
@ -645,34 +644,32 @@ index 4fe52f1..a4a99da 100644
|
|||
sqlite3 *sqlite;
|
||||
|
||||
diff --git a/node_modules/@nozbe/watermelondb/src/Database/index.js b/node_modules/@nozbe/watermelondb/src/Database/index.js
|
||||
index d4ca4e7..75c1f8e 100644
|
||||
index 6175192..3333e7c 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/src/Database/index.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/src/Database/index.js
|
||||
@@ -361,6 +361,24 @@ export default class Database {
|
||||
@@ -380,6 +380,22 @@ export default class Database {
|
||||
}
|
||||
}
|
||||
|
||||
+ async unsafeVacuum(): Promise<void> {
|
||||
+ try {
|
||||
+ // Kill ability to call adapter methods during reset (to catch bugs if someone does this)
|
||||
+ const { adapter } = this
|
||||
+ const ErrorAdapter = require('../adapters/error').default
|
||||
+ this.adapter = (new ErrorAdapter(): any)
|
||||
+
|
||||
+ // Vacuum the database
|
||||
+ await adapter.unsafeVacuum()
|
||||
+
|
||||
+ // Restore working Database
|
||||
+ this._resetCount += 1
|
||||
+ this.adapter = adapter
|
||||
+ } finally {
|
||||
+ this._isBeingReset = false
|
||||
+ }
|
||||
+ try {
|
||||
+ // Kill ability to call adapter methods during reset (to catch bugs if someone does this)
|
||||
+ const { adapter } = this
|
||||
+ const ErrorAdapter = require('../adapters/error').default
|
||||
+ this.adapter = (new ErrorAdapter(): any)
|
||||
+ // Vacuum the database
|
||||
+ await adapter.unsafeVacuum()
|
||||
+ // Restore working Database
|
||||
+ this._resetCount += 1
|
||||
+ this.adapter = adapter
|
||||
+ } finally {
|
||||
+ this._isBeingReset = false
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
_ensureInWriter(diagnosticMethodName: string): void {
|
||||
invariant(
|
||||
this._workQueue.isWriterRunning,
|
||||
// (experimental) if true, Models will print to console diagnostic information on every
|
||||
// prepareCreate/Update/Delete call, as well as on commit (Database.batch() call). Note that this
|
||||
// has a significant performance impact so should only be enabled when debugging.
|
||||
diff --git a/node_modules/@nozbe/watermelondb/src/adapters/compat.js b/node_modules/@nozbe/watermelondb/src/adapters/compat.js
|
||||
index c5175c0..c8c0c17 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/src/adapters/compat.js
|
||||
|
|
@ -701,20 +698,20 @@ index 9f1e847..cdd3af4 100644
|
|||
'setLocal',
|
||||
'removeLocal',
|
||||
diff --git a/node_modules/@nozbe/watermelondb/src/adapters/sqlite/index.js b/node_modules/@nozbe/watermelondb/src/adapters/sqlite/index.js
|
||||
index 72a5af9..908ef6d 100644
|
||||
index 72a5af9..d7871d9 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/src/adapters/sqlite/index.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/src/adapters/sqlite/index.js
|
||||
@@ -339,6 +339,19 @@ export default class SQLiteAdapter implements DatabaseAdapter {
|
||||
)
|
||||
}
|
||||
|
||||
+ unsafeVacuum(callback: ResultCallback<void): void {
|
||||
+ unsafeVacuum(callback: ResultCallback<
|
||||
+ this._dispatcher.call(
|
||||
+ 'unsafeVacuum',
|
||||
+ [],
|
||||
+ (result) => {
|
||||
+ if (result.value) {
|
||||
+ logger.log('[SQLite] Database is vacuumed')
|
||||
+ logger.log('[SQLite] Database
|
||||
+ }
|
||||
+ callback(result)
|
||||
+ },
|
||||
|
|
@ -773,7 +770,7 @@ index 63c955f..4e2f43e 100644
|
|||
| 'unsafeExecuteMultiple'
|
||||
|
||||
diff --git a/node_modules/@nozbe/watermelondb/src/adapters/type.js b/node_modules/@nozbe/watermelondb/src/adapters/type.js
|
||||
index 8929541..bc3f95d 100644
|
||||
index 8929541..b9a4174 100644
|
||||
--- a/node_modules/@nozbe/watermelondb/src/adapters/type.js
|
||||
+++ b/node_modules/@nozbe/watermelondb/src/adapters/type.js
|
||||
@@ -68,6 +68,8 @@ export interface DatabaseAdapter {
|
||||
|
|
@ -781,7 +778,7 @@ index 8929541..bc3f95d 100644
|
|||
unsafeResetDatabase(callback: ResultCallback<void>): void;
|
||||
|
||||
+ unsafeVacuum(callback: ResultCallback<void>): void;
|
||||
+
|
||||
+
|
||||
// Performs work on the underlying database - see concrete DatabaseAdapter implementation for more details
|
||||
unsafeExecute(work: UnsafeExecuteOperations, callback: ResultCallback<void>): void;
|
||||
|
||||
|
|
@ -1,22 +1,22 @@
|
|||
diff --git a/node_modules/@react-native-community/cli-platform-apple/build/commands/runCommand/getBuildSettings.js b/node_modules/@react-native-community/cli-platform-apple/build/commands/runCommand/getBuildSettings.js
|
||||
index 147bb53..b7cb80c 100644
|
||||
index 8e60c59..bc201d2 100644
|
||||
--- a/node_modules/@react-native-community/cli-platform-apple/build/commands/runCommand/getBuildSettings.js
|
||||
+++ b/node_modules/@react-native-community/cli-platform-apple/build/commands/runCommand/getBuildSettings.js
|
||||
@@ -31,10 +31,16 @@ async function getBuildSettings(xcodeProject, mode, buildOutput, scheme, target)
|
||||
encoding: 'utf8'
|
||||
});
|
||||
const settings = JSON.parse(buildSettings);
|
||||
+ const fistIndexForAppTarget = Math.max(
|
||||
+ 0,
|
||||
+ settings.findIndex(({
|
||||
+ buildSettings: bs
|
||||
+ }) => bs.WRAPPER_EXTENSION === 'app')
|
||||
+ const firstIndexForAppTarget = Math.max(
|
||||
+ 0,
|
||||
+ settings.findIndex(({
|
||||
+ buildSettings: bs
|
||||
+ }) => bs.WRAPPER_EXTENSION === 'app')
|
||||
+ );
|
||||
const targets = settings.map(({
|
||||
target: settingsTarget
|
||||
}) => settingsTarget);
|
||||
- let selectedTarget = targets[0];
|
||||
+ let selectedTarget = targets[fistIndexForAppTarget];
|
||||
+ let selectedTarget = targets[firstIndexForAppTarget];
|
||||
if (target) {
|
||||
if (!targets.includes(target)) {
|
||||
_cliTools().logger.info(`Target ${_chalk().default.bold(target)} not found for scheme ${_chalk().default.bold(scheme)}, automatically selected target ${_chalk().default.bold(selectedTarget)}`);
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
diff --git a/node_modules/@sentry/utils/cjs/object.js b/node_modules/@sentry/utils/cjs/object.js
|
||||
index a6151b5..67dcf57 100644
|
||||
--- a/node_modules/@sentry/utils/cjs/object.js
|
||||
+++ b/node_modules/@sentry/utils/cjs/object.js
|
||||
@@ -203,7 +203,11 @@ function dropUndefinedKeys(inputValue) {
|
||||
return _dropUndefinedKeys(inputValue, memoizationMap);
|
||||
}
|
||||
|
||||
-function _dropUndefinedKeys(inputValue, memoizationMap) {
|
||||
+function _dropUndefinedKeys(inputValue, memoizationMap, depth = 0) {
|
||||
+ if (depth >= 5) {
|
||||
+ return inputValue;
|
||||
+ }
|
||||
+
|
||||
if (isPojo(inputValue)) {
|
||||
// If this node has already been visited due to a circular reference, return the object it was mapped to in the new object
|
||||
const memoVal = memoizationMap.get(inputValue);
|
||||
@@ -217,7 +221,7 @@ function _dropUndefinedKeys(inputValue, memoizationMap) {
|
||||
|
||||
for (const key of Object.keys(inputValue)) {
|
||||
if (typeof inputValue[key] !== 'undefined') {
|
||||
- returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap);
|
||||
+ returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,7 +240,7 @@ function _dropUndefinedKeys(inputValue, memoizationMap) {
|
||||
memoizationMap.set(inputValue, returnValue);
|
||||
|
||||
inputValue.forEach((item) => {
|
||||
- returnValue.push(_dropUndefinedKeys(item, memoizationMap));
|
||||
+ returnValue.push(_dropUndefinedKeys(item, memoizationMap, depth + 1));
|
||||
});
|
||||
|
||||
return returnValue ;
|
||||
diff --git a/node_modules/@sentry/utils/esm/object.js b/node_modules/@sentry/utils/esm/object.js
|
||||
index c63c177..3e43a58 100644
|
||||
--- a/node_modules/@sentry/utils/esm/object.js
|
||||
+++ b/node_modules/@sentry/utils/esm/object.js
|
||||
@@ -201,7 +201,11 @@ function dropUndefinedKeys(inputValue) {
|
||||
return _dropUndefinedKeys(inputValue, memoizationMap);
|
||||
}
|
||||
|
||||
-function _dropUndefinedKeys(inputValue, memoizationMap) {
|
||||
+function _dropUndefinedKeys(inputValue, memoizationMap, depth = 0) {
|
||||
+ if (depth >= 5) {
|
||||
+ return inputValue;
|
||||
+ }
|
||||
+
|
||||
if (isPojo(inputValue)) {
|
||||
// If this node has already been visited due to a circular reference, return the object it was mapped to in the new object
|
||||
const memoVal = memoizationMap.get(inputValue);
|
||||
@@ -215,7 +219,7 @@ function _dropUndefinedKeys(inputValue, memoizationMap) {
|
||||
|
||||
for (const key of Object.keys(inputValue)) {
|
||||
if (typeof inputValue[key] !== 'undefined') {
|
||||
- returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap);
|
||||
+ returnValue[key] = _dropUndefinedKeys(inputValue[key], memoizationMap, depth + 1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +238,7 @@ function _dropUndefinedKeys(inputValue, memoizationMap) {
|
||||
memoizationMap.set(inputValue, returnValue);
|
||||
|
||||
inputValue.forEach((item) => {
|
||||
- returnValue.push(_dropUndefinedKeys(item, memoizationMap));
|
||||
+ returnValue.push(_dropUndefinedKeys(item, memoizationMap, depth + 1));
|
||||
});
|
||||
|
||||
return returnValue ;
|
||||
|
|
@ -1,15 +1,14 @@
|
|||
diff --git a/node_modules/expo-image/android/src/main/java/expo/modules/image/okhttp/ExpoImageOkHttpClientGlideModule.kt b/node_modules/expo-image/android/src/main/java/expo/modules/image/okhttp/ExpoImageOkHttpClientGlideModule.kt
|
||||
index 071907c..e5c39f5 100644
|
||||
index 071907c..edf10c1 100644
|
||||
--- a/node_modules/expo-image/android/src/main/java/expo/modules/image/okhttp/ExpoImageOkHttpClientGlideModule.kt
|
||||
+++ b/node_modules/expo-image/android/src/main/java/expo/modules/image/okhttp/ExpoImageOkHttpClientGlideModule.kt
|
||||
@@ -70,8 +70,16 @@ data class GlideUrlWrapper(val glideUrl: GlideUrl) {
|
||||
@@ -70,8 +70,15 @@ data class GlideUrlWrapper(val glideUrl: GlideUrl) {
|
||||
|
||||
@GlideModule
|
||||
class ExpoImageOkHttpClientGlideModule : LibraryGlideModule() {
|
||||
+ companion object {
|
||||
+ var okHttpClient: OkHttpClient? = null
|
||||
+ }
|
||||
+
|
||||
override fun registerComponents(context: Context, glide: Glide, registry: Registry) {
|
||||
- val client = OkHttpClient()
|
||||
+ val client = if (okHttpClient != null) {
|
||||
|
|
@ -21,13 +20,13 @@ index 071907c..e5c39f5 100644
|
|||
// to make sure that the app will use only one client.
|
||||
registry.replace(GlideUrl::class.java, InputStream::class.java, OkHttpUrlLoader.Factory(client))
|
||||
diff --git a/node_modules/expo-image/ios/ExpoImage.podspec b/node_modules/expo-image/ios/ExpoImage.podspec
|
||||
index de8bc65..564397d 100644
|
||||
index 21bef71..d662d23 100644
|
||||
--- a/node_modules/expo-image/ios/ExpoImage.podspec
|
||||
+++ b/node_modules/expo-image/ios/ExpoImage.podspec
|
||||
@@ -18,9 +18,7 @@ Pod::Spec.new do |s|
|
||||
@@ -20,9 +20,7 @@ Pod::Spec.new do |s|
|
||||
|
||||
s.dependency 'ExpoModulesCore'
|
||||
s.dependency 'SDWebImage', '~> 5.19.1'
|
||||
s.dependency 'SDWebImageWebPCoder', '~> 0.14.6'
|
||||
- s.dependency 'SDWebImageAVIFCoder', '~> 0.11.0'
|
||||
s.dependency 'SDWebImageSVGCoder', '~> 1.7.0'
|
||||
- s.dependency 'libavif/libdav1d'
|
||||
|
|
@ -35,23 +34,22 @@ index de8bc65..564397d 100644
|
|||
# Swift/Objective-C compatibility
|
||||
s.pod_target_xcconfig = {
|
||||
diff --git a/node_modules/expo-image/ios/ImageModule.swift b/node_modules/expo-image/ios/ImageModule.swift
|
||||
index e4b7fca..5057b0a 100644
|
||||
index 4bab386..a41d924 100644
|
||||
--- a/node_modules/expo-image/ios/ImageModule.swift
|
||||
+++ b/node_modules/expo-image/ios/ImageModule.swift
|
||||
@@ -3,7 +3,6 @@
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
import ExpoModulesCore
|
||||
import SDWebImage
|
||||
import SDWebImageWebPCoder
|
||||
-import SDWebImageAVIFCoder
|
||||
import SDWebImageSVGCoder
|
||||
|
||||
public final class ImageModule: Module {
|
||||
@@ -193,7 +192,7 @@ public final class ImageModule: Module {
|
||||
// This coder is much slower, but it's the only one that works in iOS 13
|
||||
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
|
||||
}
|
||||
@@ -211,7 +210,6 @@ public final class ImageModule: Module {
|
||||
static func registerCoders() {
|
||||
// By default Animated WebP is not supported
|
||||
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
|
||||
- SDImageCodersManager.shared.addCoder(SDImageAVIFCoder.shared)
|
||||
+
|
||||
SDImageCodersManager.shared.addCoder(SDImageSVGCoder.shared)
|
||||
SDImageCodersManager.shared.addCoder(SDImageHEICCoder.shared)
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
diff --git a/node_modules/expo-modules-core/build/web/CoreModule.js b/node_modules/expo-modules-core/build/web/CoreModule.js
|
||||
index 7a02851..b1b9561 100644
|
||||
--- a/node_modules/expo-modules-core/build/web/CoreModule.js
|
||||
+++ b/node_modules/expo-modules-core/build/web/CoreModule.js
|
||||
@@ -1,4 +1,4 @@
|
||||
-import uuid from '../uuid';
|
||||
+import * as uuid from 'uuid';
|
||||
class EventEmitter {
|
||||
listeners;
|
||||
addListener(eventName, listener) {
|
||||
12
patches/expo-modules-core+2.1.2.patch
Normal file
12
patches/expo-modules-core+2.1.2.patch
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
Binary files /dev/null and b/node_modules/expo-modules-core/android/build/tmp/kotlin-classes/debug/expo/modules/rncompatibility/ReactNativeFeatureFlags.class differ
|
||||
diff --git a/node_modules/expo-modules-core/src/web/index.web.ts b/node_modules/expo-modules-core/src/web/index.web.ts
|
||||
index 611564a..d9b46db 100644
|
||||
--- a/node_modules/expo-modules-core/src/web/index.web.ts
|
||||
+++ b/node_modules/expo-modules-core/src/web/index.web.ts
|
||||
@@ -1,5 +1,5 @@
|
||||
import { EventEmitter, NativeModule, SharedObject, SharedRef } from './CoreModule';
|
||||
-import uuid from '../uuid';
|
||||
+import * as uuid from 'uuid';
|
||||
|
||||
// jest-expo imports to this file directly without going through the global types
|
||||
// Exporting the types to let jest-expo to know the globalThis types
|
||||
|
|
@ -1,13 +1,13 @@
|
|||
diff --git a/node_modules/expo-video-thumbnails/ios/VideoThumbnailsModule.swift b/node_modules/expo-video-thumbnails/ios/VideoThumbnailsModule.swift
|
||||
index 2b01a1d..78c7ffa 100644
|
||||
index 069e3e4..c32ba6c 100644
|
||||
--- a/node_modules/expo-video-thumbnails/ios/VideoThumbnailsModule.swift
|
||||
+++ b/node_modules/expo-video-thumbnails/ios/VideoThumbnailsModule.swift
|
||||
@@ -7,7 +7,7 @@ public class VideoThumbnailsModule: Module {
|
||||
public func definition() -> ModuleDefinition {
|
||||
Name("ExpoVideoThumbnails")
|
||||
|
||||
- AsyncFunction("getThumbnail", getVideoThumbnail).runOnQueue(.main)
|
||||
+ AsyncFunction("getThumbnail", getVideoThumbnail).runOnQueue(.global())
|
||||
- AsyncFunction("getThumbnail", getVideoThumbnail)
|
||||
+ AsyncFunction("getThumbnail", getVideoThumbnail).runOnQueue(.global())
|
||||
}
|
||||
|
||||
internal func getVideoThumbnail(sourceFilename: URL, options: VideoThumbnailsOptions) throws -> [String: Any] {
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
diff --git a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.h b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.h
|
||||
index 4a1234f..f3e2308 100644
|
||||
--- a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.h
|
||||
+++ b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.h
|
||||
@@ -10,5 +10,6 @@
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
@interface RNKeychainManager : NSObject <RCTBridgeModule>
|
||||
-
|
||||
+-(OSStatus)deleteCredentialsForServer:(NSString *)server;
|
||||
+-(NSArray<NSString*>*)getAllServersForInternetPasswords;
|
||||
@end
|
||||
diff --git a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m
|
||||
index 58d555f..d8c4069 100644
|
||||
--- a/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m
|
||||
+++ b/node_modules/react-native-keychain/RNKeychainManager/RNKeychainManager.m
|
||||
@@ -275,6 +275,36 @@ SecAccessControlCreateFlags accessControlValue(NSDictionary *options)
|
||||
return SecItemDelete((__bridge CFDictionaryRef) query);
|
||||
}
|
||||
|
||||
+-(NSArray<NSString*>*)getAllServersForInternetPasswords
|
||||
+{
|
||||
+ NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
+ (__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];
|
||||
+ NSArray *result = nil;
|
||||
+ CFTypeRef resultRef = NULL;
|
||||
+ OSStatus osStatus = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef*)&resultRef);
|
||||
+ if (osStatus != noErr && osStatus != errSecItemNotFound) {
|
||||
+ NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
|
||||
+ @throw error;
|
||||
+ } else if (osStatus != errSecItemNotFound) {
|
||||
+ result = (__bridge NSArray*)(resultRef);
|
||||
+ if (result != NULL) {
|
||||
+ for (id entry in result) {
|
||||
+ NSString *serverData = [entry objectForKey:(__bridge NSString *)kSecAttrServer];
|
||||
+ if (serverData != NULL) {
|
||||
+ [servers addObject:serverData];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return servers;
|
||||
+}
|
||||
+
|
||||
-(NSArray<NSString*>*)getAllServicesForSecurityClasses:(NSArray *)secItemClasses
|
||||
{
|
||||
NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
@@ -607,4 +637,14 @@ RCT_EXPORT_METHOD(getAllGenericPasswordServices:(RCTPromiseResolveBlock)resolve
|
||||
}
|
||||
}
|
||||
|
||||
+RCT_EXPORT_METHOD(getAllInternetPasswordServers:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
||||
+{
|
||||
+ @try {
|
||||
+ NSArray *servers = [self getAllServersForInternetPasswords];
|
||||
+ return resolve(servers);
|
||||
+ } @catch (NSError *nsError) {
|
||||
+ return rejectWithError(reject, nsError);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
@end
|
||||
diff --git a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
|
||||
index 9413000..422581a 100644
|
||||
--- a/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
|
||||
+++ b/node_modules/react-native-keychain/android/src/main/java/com/oblador/keychain/KeychainModule.java
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.oblador.keychain;
|
||||
|
||||
import android.os.Build;
|
||||
+import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -129,6 +130,7 @@ public class KeychainModule extends ReactContextBaseJavaModule {
|
||||
//region Members
|
||||
/** Name-to-instance lookup map. */
|
||||
private final Map<String, CipherStorage> cipherStorageMap = new HashMap<>();
|
||||
+ private final Map<String, Bundle> cachedCredentialsMap = new HashMap<>();
|
||||
/** Shared preferences storage. */
|
||||
private final PrefsStorage prefsStorage;
|
||||
//endregion
|
||||
@@ -140,13 +142,7 @@ public class KeychainModule extends ReactContextBaseJavaModule {
|
||||
super(reactContext);
|
||||
prefsStorage = new PrefsStorage(reactContext);
|
||||
|
||||
- addCipherStorageToMap(new CipherStorageFacebookConceal(reactContext));
|
||||
addCipherStorageToMap(new CipherStorageKeystoreAesCbc());
|
||||
-
|
||||
- // we have a references to newer api that will fail load of app classes in old androids OS
|
||||
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
- addCipherStorageToMap(new CipherStorageKeystoreRsaEcb());
|
||||
- }
|
||||
}
|
||||
|
||||
/** Allow initialization in chain. */
|
||||
@@ -278,6 +274,11 @@ public class KeychainModule extends ReactContextBaseJavaModule {
|
||||
@Nullable final ReadableMap options,
|
||||
@NonNull final Promise promise) {
|
||||
try {
|
||||
+ Bundle cached = cachedCredentialsMap.get(alias);
|
||||
+ if (cached != null) {
|
||||
+ promise.resolve(Arguments.fromBundle(cached));
|
||||
+ return;
|
||||
+ }
|
||||
final ResultSet resultSet = prefsStorage.getEncryptedEntry(alias);
|
||||
|
||||
if (resultSet == null) {
|
||||
@@ -310,6 +311,7 @@ public class KeychainModule extends ReactContextBaseJavaModule {
|
||||
credentials.putString(Maps.USERNAME, decryptionResult.username);
|
||||
credentials.putString(Maps.PASSWORD, decryptionResult.password);
|
||||
credentials.putString(Maps.STORAGE, cipher.getCipherStorageName());
|
||||
+ cachedCredentialsMap.put(alias, Arguments.toBundle(credentials));
|
||||
|
||||
promise.resolve(credentials);
|
||||
} catch (KeyStoreAccessException e) {
|
||||
@@ -382,6 +384,7 @@ public class KeychainModule extends ReactContextBaseJavaModule {
|
||||
}
|
||||
// And then we remove the entry in the shared preferences
|
||||
prefsStorage.removeEntry(alias);
|
||||
+ cachedCredentialsMap.remove(alias);
|
||||
|
||||
promise.resolve(true);
|
||||
} catch (KeyStoreAccessException e) {
|
||||
diff --git a/node_modules/react-native-keychain/index.js b/node_modules/react-native-keychain/index.js
|
||||
index 083938e..c8728a0 100644
|
||||
--- a/node_modules/react-native-keychain/index.js
|
||||
+++ b/node_modules/react-native-keychain/index.js
|
||||
@@ -351,6 +351,21 @@ export function canImplyAuthentication(options?: Options): Promise<boolean> {
|
||||
return RNKeychainManager.canCheckAuthentication(options);
|
||||
}
|
||||
|
||||
+/**
|
||||
++ * Gets all `kSecAttrServer` values used in internet credentials for iOS.
|
||||
++ * @return {Promise} Resolves to an array of strings
|
||||
++ */
|
||||
+export async function getAllInternetPasswordServers(): Promise<string[]> {
|
||||
+ if (Platform.OS !== 'ios') {
|
||||
+ return Promise.reject(
|
||||
+ new Error(
|
||||
+ `getAllInternetPasswordServers() is not supported on ${Platform.OS}`
|
||||
+ )
|
||||
+ );
|
||||
+ }
|
||||
+ return RNKeychainManager.getAllInternetPasswordServers();
|
||||
+}
|
||||
+
|
||||
//* ANDROID ONLY */
|
||||
|
||||
/**
|
||||
diff --git a/node_modules/react-native-keychain/typings/react-native-keychain.d.ts b/node_modules/react-native-keychain/typings/react-native-keychain.d.ts
|
||||
index 6846468..bc03596 100644
|
||||
--- a/node_modules/react-native-keychain/typings/react-native-keychain.d.ts
|
||||
+++ b/node_modules/react-native-keychain/typings/react-native-keychain.d.ts
|
||||
@@ -97,6 +97,8 @@ declare module 'react-native-keychain' {
|
||||
|
||||
function getAllGenericPasswordServices(): Promise<string[]>;
|
||||
|
||||
+ function getAllInternetPasswordServers(): Promise<string[]>;
|
||||
+
|
||||
function hasInternetCredentials(server: string): Promise<false | Result>;
|
||||
|
||||
function setInternetCredentials(
|
||||
122
patches/react-native-keychain+9.2.2.patch
Normal file
122
patches/react-native-keychain+9.2.2.patch
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
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
|
||||
--- a/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.h
|
||||
+++ b/node_modules/react-native-keychain/ios/RNKeychainManager/RNKeychainManager.h
|
||||
@@ -10,5 +10,6 @@
|
||||
#import <React/RCTLog.h>
|
||||
|
||||
@interface RNKeychainManager : NSObject <RCTBridgeModule>
|
||||
-
|
||||
+-(OSStatus)deleteCredentialsForServer:(NSString *)server withOptions:(NSDictionary * __nullable)options;
|
||||
+-(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
|
||||
--- 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)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+-(NSArray<NSString*>*)getAllServersForInternetPasswords
|
||||
+{
|
||||
+ NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys:
|
||||
+ (__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];
|
||||
+ NSArray *result = nil;
|
||||
+ CFTypeRef resultRef = NULL;
|
||||
+ OSStatus osStatus = SecItemCopyMatching((__bridge CFDictionaryRef)query, (CFTypeRef*)&resultRef);
|
||||
+ if (osStatus != noErr && osStatus != errSecItemNotFound) {
|
||||
+ NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:osStatus userInfo:nil];
|
||||
+ @throw error;
|
||||
+ } else if (osStatus != errSecItemNotFound) {
|
||||
+ result = (__bridge NSArray*)(resultRef);
|
||||
+ if (result != NULL) {
|
||||
+ for (id entry in result) {
|
||||
+ NSString *serverData = [entry objectForKey:(__bridge NSString *)kSecAttrServer];
|
||||
+ if (serverData != NULL) {
|
||||
+ [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
|
||||
}
|
||||
}
|
||||
|
||||
+RCT_EXPORT_METHOD(getAllInternetPasswordServers:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
|
||||
+{
|
||||
+ @try {
|
||||
+ NSArray *servers = [self getAllServersForInternetPasswords];
|
||||
+ return resolve(servers);
|
||||
+ } @catch (NSError *nsError) {
|
||||
+ return rejectWithError(reject, nsError);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
@end
|
||||
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
|
||||
--- 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
|
||||
* ```
|
||||
*/
|
||||
export declare function getAllGenericPasswordServices(): Promise<string[]>;
|
||||
+/**
|
||||
+* 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.
|
||||
*
|
||||
diff --git a/node_modules/react-native-keychain/src/index.ts b/node_modules/react-native-keychain/src/index.ts
|
||||
index 7bfe371..3ac11b5 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();
|
||||
}
|
||||
|
||||
+/**
|
||||
+* 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(
|
||||
+ new Error(
|
||||
+ `getAllInternetPasswordServers() is not supported on ${Platform.OS}`
|
||||
+ )
|
||||
+ );
|
||||
+ }
|
||||
+ return RNKeychainManager.getAllInternetPasswordServers();
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* Checks if internet credentials exist for the given server.
|
||||
*
|
||||
|
|
@ -73,6 +73,31 @@ 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
|
||||
|
|
@ -296,6 +321,18 @@ index 834d734..3fc00c3 100644
|
|||
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
|
||||
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
|
||||
--- a/node_modules/react-native-navigation/lib/android/app/src/main/java/com/reactnativenavigation/viewcontrollers/child/ChildController.java
|
||||
|
|
@ -327,6 +364,32 @@ 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
|
||||
|
|
@ -342,6 +405,76 @@ 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
|
||||
--- 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{
|
||||
}
|
||||
}
|
||||
override fun onChildStartedNativeGesture(child: View, androidEvent: MotionEvent?) {
|
||||
- mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher())
|
||||
+ androidEvent?.let {
|
||||
+ mJSTouchDispatcher.onChildStartedNativeGesture(it, this.getEventDispatcher()!!)
|
||||
+ }
|
||||
}
|
||||
override fun onChildStartedNativeGesture(androidEvent: MotionEvent?) {
|
||||
- mJSTouchDispatcher.onChildStartedNativeGesture(androidEvent, this.getEventDispatcher())
|
||||
+ androidEvent?.let {
|
||||
+ mJSTouchDispatcher.onChildStartedNativeGesture(it, this.getEventDispatcher()!!)
|
||||
+ }
|
||||
}
|
||||
override fun onChildEndedNativeGesture(child: View, androidEvent: MotionEvent?) {
|
||||
- mJSTouchDispatcher.onChildEndedNativeGesture(androidEvent, this.getEventDispatcher())
|
||||
+ 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{
|
||||
}
|
||||
|
||||
override fun onInterceptTouchEvent(event: MotionEvent?): Boolean {
|
||||
- mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher())
|
||||
+ event?.let {
|
||||
+ mJSTouchDispatcher.handleTouchEvent(it, getEventDispatcher()!!)
|
||||
+ }
|
||||
return super.onInterceptTouchEvent(event)
|
||||
}
|
||||
|
||||
override fun onTouchEvent(event: MotionEvent?): Boolean {
|
||||
- mJSTouchDispatcher.handleTouchEvent(event, getEventDispatcher())
|
||||
+ 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
|
||||
|
|
@ -376,6 +509,30 @@ 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
|
||||
--- a/node_modules/react-native-navigation/lib/src/interfaces/Options.ts
|
||||
12
patches/react-native-reanimated+3.16.5.patch
Normal file
12
patches/react-native-reanimated+3.16.5.patch
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
diff --git a/node_modules/react-native-reanimated/src/mock.ts b/node_modules/react-native-reanimated/src/mock.ts
|
||||
index 3d8e3f8..b32d457 100644
|
||||
--- a/node_modules/react-native-reanimated/src/mock.ts
|
||||
+++ b/node_modules/react-native-reanimated/src/mock.ts
|
||||
@@ -114,6 +114,7 @@ const hook = {
|
||||
}),
|
||||
// useFrameCallback: ADD ME IF NEEDED
|
||||
useAnimatedKeyboard: () => ({ height: 0, state: 0 }),
|
||||
+ useReducedMotion: () => false,
|
||||
// useScrollViewOffset: ADD ME IF NEEDED
|
||||
};
|
||||
|
||||
|
|
@ -1,8 +1,8 @@
|
|||
diff --git a/node_modules/react-native-svg/src/xml.tsx b/node_modules/react-native-svg/src/xml.tsx
|
||||
index 9e2352a..fb45382 100644
|
||||
index edfaa9b..41246bb 100644
|
||||
--- a/node_modules/react-native-svg/src/xml.tsx
|
||||
+++ b/node_modules/react-native-svg/src/xml.tsx
|
||||
@@ -138,9 +138,11 @@ export function SvgUri(props: UriProps) {
|
||||
@@ -87,9 +87,11 @@ export function SvgUri(props: UriProps) {
|
||||
uri
|
||||
? fetchText(uri)
|
||||
.then((data) => {
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
diff --git a/node_modules/react-native-video/ios/Video/Features/RCTVideoUtils.swift b/node_modules/react-native-video/ios/Video/Features/RCTVideoUtils.swift
|
||||
index c13c4d9..b86a860 100644
|
||||
--- a/node_modules/react-native-video/ios/Video/Features/RCTVideoUtils.swift
|
||||
+++ b/node_modules/react-native-video/ios/Video/Features/RCTVideoUtils.swift
|
||||
@@ -9,7 +9,11 @@ enum RCTVideoAssetsUtils {
|
||||
for mediaCharacteristic: AVMediaCharacteristic
|
||||
) async -> AVMediaSelectionGroup? {
|
||||
if #available(iOS 15, tvOS 15, visionOS 1.0, *) {
|
||||
- return try? await asset?.loadMediaSelectionGroup(for: mediaCharacteristic)
|
||||
+ if let mediaSelectionGroup = try? await asset?.loadMediaSelectionGroup(for: mediaCharacteristic) {
|
||||
+ return mediaSelectionGroup
|
||||
+ }
|
||||
+
|
||||
+ return nil
|
||||
} else {
|
||||
#if !os(visionOS)
|
||||
return asset?.mediaSelectionGroup(forMediaCharacteristic: mediaCharacteristic)
|
||||
|
|
@ -16,7 +16,7 @@ if [[ "$OSTYPE" == "darwin"* ]]; then
|
|||
gem install bundler --version 2.5.11 || exit 1
|
||||
fi
|
||||
|
||||
if !(gem list cocoapods -i --version 1.15.2) > /dev/null 2>&1; then
|
||||
if !(gem list cocoapods -i --version 1.16.1) > /dev/null 2>&1; then
|
||||
cocoapods
|
||||
fi
|
||||
fi
|
||||
|
|
@ -2,7 +2,7 @@
|
|||
// See LICENSE.txt for license information.
|
||||
|
||||
import {Image} from 'expo-image';
|
||||
import {LinearGradient} from 'expo-linear-gradient';
|
||||
import {LinearGradient, type LinearGradientProps} from 'expo-linear-gradient';
|
||||
import React, {useMemo} from 'react';
|
||||
import {StyleSheet, useWindowDimensions, View} from 'react-native';
|
||||
|
||||
|
|
@ -20,9 +20,9 @@ type Props = {
|
|||
type?: 'image' | 'video';
|
||||
}
|
||||
|
||||
const GRADIENT_COLORS = ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, .16)'];
|
||||
const GRADIENT_COLORS: LinearGradientProps['colors'] = ['rgba(0, 0, 0, 0)', 'rgba(0, 0, 0, .16)'];
|
||||
const GRADIENT_END = {x: 1, y: 1};
|
||||
const GRADIENT_LOCATIONS = [0.5, 1];
|
||||
const GRADIENT_LOCATIONS: LinearGradientProps['locations'] = [0.5, 1];
|
||||
const GRADIENT_START = {x: 0.3, y: 0.3};
|
||||
|
||||
const getStyles = makeStyleSheetFromTheme((theme: Theme) => ({
|
||||
|
|
@ -81,7 +81,7 @@ const Thumbnail = ({contentMode, file, hasError, theme, type}: Props) => {
|
|||
styles.container,
|
||||
hasError && styles.error,
|
||||
styles.radius,
|
||||
]), [styles, imgStyle, hasError]);
|
||||
]), [styles, hasError]);
|
||||
|
||||
const source = useMemo(() => ({uri: type === 'video' ? file.videoThumb : file.value}), [type, file]);
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ export const getServerHasChannels = async (serverUrl: string) => {
|
|||
|
||||
export const observeServerHasChannels = (serverUrl: string) => {
|
||||
return queryHasChannels(serverUrl)?.observe().pipe(
|
||||
switchMap((channels) => of$(channels?.length > 0 ?? false)),
|
||||
switchMap((channels) => of$(channels.length > 0)),
|
||||
) || of$(false);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -31,6 +31,10 @@ jest.mock('expo-application', () => {
|
|||
};
|
||||
});
|
||||
|
||||
jest.mock('expo-crypto', () => ({
|
||||
randomUUID: jest.fn(() => '12345678-1234-1234-1234-1234567890ab'),
|
||||
}));
|
||||
|
||||
jest.mock('expo-device', () => {
|
||||
return {
|
||||
deviceName: 'Device',
|
||||
|
|
@ -235,7 +239,6 @@ jest.mock('react-native-vector-icons', () => {
|
|||
};
|
||||
});
|
||||
|
||||
jest.mock('react-native/Libraries/Animated/NativeAnimatedHelper');
|
||||
jest.mock('../node_modules/react-native/Libraries/EventEmitter/NativeEventEmitter');
|
||||
|
||||
jest.mock('react-native-localize', () => ({
|
||||
|
|
@ -392,7 +395,7 @@ jest.mock('react-native-reanimated', () => require('react-native-reanimated/mock
|
|||
jest.mock('react-native-permissions', () => require('react-native-permissions/mock'));
|
||||
|
||||
jest.mock('react-native-haptic-feedback', () => {
|
||||
const RNHF = jest.requireActual('react-native-haptic-feedback');
|
||||
const RNHF = jest.requireActual('react-native-haptic-feedback/src/types');
|
||||
return {
|
||||
...RNHF,
|
||||
trigger: () => '',
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ export type EmojiProps = {
|
|||
size?: number;
|
||||
textStyle?: StyleProp<TextStyle>;
|
||||
imageStyle?: StyleProp<ImageStyle>;
|
||||
commonStyle?: StyleProp<EmojiCommonStyle>;
|
||||
commonStyle?: StyleProp<Intersection<TextStyle, EmojiCommonStyle>>;
|
||||
customEmojis: CustomEmojiModel[];
|
||||
testID?: string;
|
||||
}
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue